<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import styles from './photon.scss';
import coreStyles from './Core.scss';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import AceEditor from 'react-ace';
import brace from 'brace';
import 'brace/mode/javascript';
import 'brace/theme/tomorrow_night_bright';

// Gui columns
import Left from './Left';
import Right from '../containers/RightPage.js';

// Main editor component
import Workspace from '../containers/Workspace';

// Visual component exporter function
import getVisComponent from './VisComponents/exporter';

import ExportButton from '../containers/ExportButton';
import { ipcRenderer } from 'electron';

class Core extends Component {
  constructor(props) {
    super(props);
    console.log(props);
    this.state = {
      code: '*** Insert Code Here ***',
      hideEditor: true,
      freeMoveMode: true
    };
    this.toggleEditor = this.toggleEditor.bind(this);
    this.onEditorChange = this.onEditorChange.bind(this);
    this.updateMethods = this.props.updateMethods;
  }

  props: {
    updateMethods: () => void,
  }

  onEditorChange(newValue) {
    this.updateMethods(newValue);
  }

  toggleEditor(e){
    this.setState({
      hideEditor: !this.state.hideEditor
    });
  }

  render() {
    const options = {
      lineNumbers: true
    };
    const editorValue = this.props.methods;
    return (

        <div className={`${styles['window-content']} ${coreStyles.container}`}>

            <Left drag={this.dragComponent} />
            <div className={`${styles.pane} ${coreStyles.main}`}>
              <header className={`${coreStyles.footer}`}>
                <h1 className={`${styles.title} ${coreStyles.title}`}>Workspace

                <Workspace
                  hideEditor={this.state.hideEditor}
                  freeMoveMode={this.state.freeMoveMode}
                />

              <div className={`${this.state.hideEditor ? coreStyles.hideEditor : ''}`}>
                <form data-tid="textEditor">
                  <div className={`${coreStyles.ace}`}>
                    <AceEditor
                      className={`${coreStyles.aceInterior}`}
                      mode="javascript"
                      theme="tomorrow_night_bright"
                      onChange={this.onEditorChange}
                      highlightActiveLine={true}
                      value={editorValue}
                      name="editorInterior"
                      style={{width: '100%', margin:'none'}}
                      editorProps={{ $blockScrolling: true }}
                    />

                </form>

                  <Link to="/">

                  </Link>

                <a
                  className={`${coreStyles['btn']} ${coreStyles['btn-blue']}`}
                  onClick={()=>{this.setState({ freeMoveMode: !this.state.freeMoveMode })}}
                >
                  { this.state.freeMoveMode ? 'Nest' : 'Move'  } mode

                <a
                  className={`${coreStyles['btn']} ${coreStyles['btn-blue']}`}
                  onClick={() => this.props.deleteComponent(this.props.activeComponent)} >
                    Delete component

                <ExportButton />
                <a className={`${coreStyles['btn']} ${coreStyles['btn-blue']} ${styles['pull-right']}`}  onClick={this.toggleEditor}>
                  {this.state.hideEditor ? 'Show' : 'Hide'} Text Editor

                <a className={`${coreStyles['btn']} ${coreStyles['btn-blue']} ${styles['pull-right']}`} onClick={()=>{ipcRenderer.send('openSimulator')}}>preview

            <Right />

    );
  }
}

export default DragDropContext(HTML5Backend)(Core);
<commit_msg>removes code value from core.state<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import styles from './photon.scss';
import coreStyles from './Core.scss';
import { DragDropContext } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import AceEditor from 'react-ace';
import brace from 'brace';
import 'brace/mode/javascript';
import 'brace/theme/tomorrow_night_bright';

// Gui columns
import Left from './Left';
import Right from '../containers/RightPage.js';

// Main editor component
import Workspace from '../containers/Workspace';

// Visual component exporter function
import getVisComponent from './VisComponents/exporter';

import ExportButton from '../containers/ExportButton';
import { ipcRenderer } from 'electron';

class Core extends Component {
  constructor(props) {
    super(props);
    console.log(props);
    this.state = {
      hideEditor: true,
      freeMoveMode: true
    };
    this.toggleEditor = this.toggleEditor.bind(this);
    this.onEditorChange = this.onEditorChange.bind(this);
    this.updateMethods = this.props.updateMethods;
  }

  props: {
    updateMethods: () => void,
  }

  onEditorChange(newValue) {
    this.updateMethods(newValue);
  }

  toggleEditor(e){
    this.setState({
      hideEditor: !this.state.hideEditor
    });
  }

  render() {
    const options = {
      lineNumbers: true
    };
    const editorValue = this.props.methods;
    return (

        <div className={`${styles['window-content']} ${coreStyles.container}`}>

            <Left drag={this.dragComponent} />
            <div className={`${styles.pane} ${coreStyles.main}`}>
              <header className={`${coreStyles.footer}`}>
                <h1 className={`${styles.title} ${coreStyles.title}`}>Workspace

                <Workspace
                  hideEditor={this.state.hideEditor}
                  freeMoveMode={this.state.freeMoveMode}
                />

              <div className={`${this.state.hideEditor ? coreStyles.hideEditor : ''}`}>
                <form data-tid="textEditor">
                  <div className={`${coreStyles.ace}`}>
                    <AceEditor
                      className={`${coreStyles.aceInterior}`}
                      mode="javascript"
                      theme="tomorrow_night_bright"
                      onChange={this.onEditorChange}
                      highlightActiveLine={true}
                      value={editorValue}
                      name="editorInterior"
                      style={{width: '100%', margin:'none'}}
                      editorProps={{ $blockScrolling: true }}
                    />

                </form>

                  <Link to="/">

                  </Link>

                <a
                  className={`${coreStyles['btn']} ${coreStyles['btn-blue']}`}
                  onClick={()=>{this.setState({ freeMoveMode: !this.state.freeMoveMode })}}
                >
                  { this.state.freeMoveMode ? 'Nest' : 'Move'  } mode

                <a
                  className={`${coreStyles['btn']} ${coreStyles['btn-blue']}`}
                  onClick={() => this.props.deleteComponent(this.props.activeComponent)} >
                    Delete component

                <ExportButton />
                <a className={`${coreStyles['btn']} ${coreStyles['btn-blue']} ${styles['pull-right']}`}  onClick={this.toggleEditor}>
                  {this.state.hideEditor ? 'Show' : 'Hide'} Text Editor

                <a className={`${coreStyles['btn']} ${coreStyles['btn-blue']} ${styles['pull-right']}`} onClick={()=>{ipcRenderer.send('openSimulator')}}>preview

            <Right />

    );
  }
}

export default DragDropContext(HTML5Backend)(Core);
<|endoftext|>


<commit_before>var qd = function() {
    var result = {};
    var modelUpdateCallbacks = [];

    //change this to accomodate varying streamids (for compare functionality)
    var url = function(resource) {
        var result = "";
        if (location.hostname == "localhost") {
            result = "http://" + location.hostname + ":5000/quantifieddev/" + resource + "/" + window.localStorage.streamId;
        } else {
            result = "http://quantifieddev.herokuapp.com/quantifieddev/" + resource + "/" + window.localStorage.streamId;
        }
        return result;
    }
    var postAjax = function(urlParam, successCallback, failureCallback) {
        $.ajax({
            url: url(urlParam),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            },
            success: successCallback,
            error: function(error) {
                if (failureCallback)
                    failureCallback(error);
            }
        });

    }
    var compare = function(todaysEvents, yesterdayEvents) {
        var difference = todaysEvents - yesterdayEvents;
        var percentChange = (difference / yesterdayEvents) * 100;
        return Math.ceil(percentChange);
    }
    var myDevSuccessCallback = function(buildEvents) {
        $("#stream-id-errors").text("");
        result.buildEvents = buildEvents;
        populateBuildTilesData(buildEvents);
        modelUpdateCallbacks.forEach(function(c) {
            c();
        });

    }
    var failureCallback = function(divId, msg) {
        return function() {
            $(divId).text(msg);
        }
    }
    var populateBuildTilesData = function(buildEvents) {
        var todaysBuild = buildEvents[buildEvents.length - 1]; // last record
        var yesterdaysBuild = buildEvents[buildEvents.length - 2];
        var totalBuildsForToday = todaysBuild.passed + todaysBuild.failed;
        var totalBuildsForYesterday = yesterdaysBuild.passed + yesterdaysBuild.failed;
        result.todaysPassedBuildCount = todaysBuild.passed;
        result.todaysFailedBuildCount = todaysBuild.failed;
        result.todaysTotalBuildCount = totalBuildsForToday;
        result.totalBuildComparison = compare(totalBuildsForToday, totalBuildsForYesterday);
        result.passedBuildComparison = compare(todaysBuild.passed, yesterdaysBuild.passed);
        result.failedBuildComparison = compare(todaysBuild.failed, yesterdaysBuild.failed);
    }
    result.updateBuildModel = function() {
        postAjax("mydev", myDevSuccessCallback, failureCallback("#stream-id-errors", "Incorrect streamid or read token!"))
    }
    var myWtfSuccessCallback = function(wtfEvents) {
        result.wtfEvents = wtfEvents;
        result.plotWTFHistory();
    }
    result.updateWTFModel = function() {
        postAjax("mywtf", myWtfSuccessCallback)
    };
    var myHydrationSuccessCallback = function(hydrationEvents) {
        result.hydrationEvents = hydrationEvents;
        result.plotHydrationHistory();
    }
    result.updateHydrationModel = function() {
        postAjax("myhydration", myHydrationSuccessCallback)
    };
    var myCaffeineSuccessCallback = function(caffeineEvents) {
        result.caffeineEvents = caffeineEvents;
        result.plotCaffeineHistory();
    }
    result.updateCaffeineModel = function() {
        postAjax("mycaffeine", myCaffeineSuccessCallback)

    };
    var buildDurationSuccessCallback = function(buildDurationEvents) {
        result.buildDurationEvents = buildDurationEvents;
        result.plotBuildDurationHistory();
    }
    result.updateBuildDurationModel = function() {
        postAjax("buildDuration", buildDurationSuccessCallback)

    };
    var hourlyBuildSuccessCallback = function(hourlyBuildEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyBuildEvents = hourlyBuildEvents;
        result.plotHourlyEventMap('#hourlyBuild-heat-map', hourlyBuildEvents);
    }

    result.updateHourlyBuildHeatMap = function() {
        postAjax("hourlyBuildCount", hourlyBuildSuccessCallback)

    };
    var hourlyWtfSuccessCallback = function(hourlyWtfEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyWtfEvents = hourlyWtfEvents;
        result.plotHourlyEventMap('#hourlyWtf-heat-map', hourlyWtfEvents);
    }
    result.updateHourlyWtfHeatMap = function() {
        postAjax("hourlyWtfCount", hourlyWtfSuccessCallback)
    };

    var hourlyHydrationSuccessCallback = function(hourlyHydrationEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyHydrationEvents = hourlyHydrationEvents;
        result.plotHourlyEventMap('#hourlyHydration-heat-map', hourlyHydrationEvents);
    }
    result.updateHourlyHydrationHeatMap = function() {
        postAjax("hourlyHydrationCount", hourlyHydrationSuccessCallback)

    };
    var hourlyCaffeineSuccessCallback = function(hourlyCaffeineEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyCaffeineEvents = hourlyCaffeineEvents;
        result.plotHourlyEventMap('#hourlyCaffeine-heat-map', hourlyCaffeineEvents);
    }
    result.updateHourlyCaffeineHeatMap = function() {
        postAjax("hourlyCaffeineCount", hourlyCaffeineSuccessCallback)
    };
    var activitySuccessCallback = function(myActiveEvents) {
        result.activeEvents = myActiveEvents;
        result.plotActiveEvents();
    }
    result.updateActiveEvents = function() {
        postAjax("myActiveEvents", activitySuccessCallback)

    };
    result.plotGraphs = function(graphs) {
        graphs.forEach(function(graph) {
            result[graph]();
        })
    }

    result.registerForBuildModelUpdates = function(callback) {
        modelUpdateCallbacks.push(callback);
    }

    result.tweetBuildSparkline = function() {
        if (result.buildEvents === undefined) {
            return;
        }

        var totalBuilds = [];
        var sparkbarDataForDays = 14;
        result.buildEvents.map(function(buildEvent) {
            totalBuilds.push(buildEvent.passed + buildEvent.failed);
        });
        totalBuilds = totalBuilds.slice(totalBuilds.length - sparkbarDataForDays, totalBuilds.length)
        console.log("sparking builds:", totalBuilds)
        var sparkBar = window.oneSelf.toSparkBars(totalBuilds);
        var tweetText = sparkBar + " my builds over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['coding'].join(',');
        $('#tweetMyBuilds').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetWtfSparkline = function() {
        if (result.wtfEvents === undefined) {
            return;
        }

        var totalWtfs = [];
        var sparkbarDataForDays = 14;
        result.wtfEvents.map(function(wtfEvent) {
            totalWtfs.push(wtfEvent.wtfCount);
        });
        totalWtfs = totalWtfs.slice(totalWtfs.length - sparkbarDataForDays, totalWtfs.length)
        console.log("sparking wtfs:", totalWtfs)
        var sparkBar = window.oneSelf.toSparkBars(totalWtfs);
        var tweetText = sparkBar + " my WTFs over the last 2 weeks. The only measure of code quality. See yours at quantifieddev.org";
        var hashTags = ['wtf', 'coding'].join(',');
        $('#tweetMyWtfs').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetHydrationSparkline = function() {
        if (result.hydrationEvents === undefined) {
            return;
        }

        var totalHydrations = [];
        var sparkbarDataForDays = 14;

        result.hydrationEvents.map(function(hydrationEvent) {
            totalHydrations.push(hydrationEvent.hydrationCount);
        });

        totalHydrations = totalHydrations.slice(totalHydrations.length - sparkbarDataForDays, totalHydrations.length);
        console.log("sparking hydrations:", totalHydrations)
        var sparkBar = window.oneSelf.toSparkBars(totalHydrations);
        var tweetText = sparkBar + " my hydration levels over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['hydrate', 'coding'].join(',');
        $('#tweetMyHydration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetCaffeineSparkline = function() {
        if (result.caffeineEvents === undefined) {
            return;
        }

        var totalCaffeine = [];
        var sparkbarDataForDays = 14;
        result.caffeineEvents.map(function(caffeineEvent) {
            totalCaffeine.push(caffeineEvent.caffeineCount);
        });

        totalCaffeine = totalCaffeine.slice(totalCaffeine.length - sparkbarDataForDays, totalCaffeine.length);
        console.log("sparking caffeine:", totalCaffeine)
        var sparkBar = window.oneSelf.toSparkBars(totalCaffeine);
        var tweetText = sparkBar + " my caffeine levels over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['coffee', 'coding'].join(',');
        $('#tweetMyCaffeine').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetBuildDurationSparkline = function() {
        if (result.buildDurationEvents === undefined) {
            return;
        }

        var totalBuildDuration = [];
        var sparkbarDataForDays = 14;
        result.buildDurationEvents.map(function(buildDurationEvent) {
            totalBuildDuration.push(buildDurationEvent.avgBuildDuration);
        });

        totalBuildDuration = totalBuildDuration.slice(totalBuildDuration.length - sparkbarDataForDays, totalBuildDuration.length);
        console.log("sparking totalBuildDuration:", totalBuildDuration)
        var sparkBar = window.oneSelf.toSparkBars(totalBuildDuration);
        var tweetText = sparkBar + " my build duration over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['buildDuration', 'coding'].join(',');
        $('#tweetMyBuildDuration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetActiveEventSparkline = function() {
        if (result.activeEvents === undefined) {
            return;
        }

        var totalActiveDuration = [];
        var sparkbarDataForDays = 14;
        result.activeEvents.map(function(activeEvent) {
            totalActiveDuration.push(activeEvent.totalActiveDuration);
        });

        totalActiveDuration = totalActiveDuration.slice(totalActiveDuration.length - sparkbarDataForDays, totalActiveDuration.length);
        console.log("sparking totalActiveDuration:", totalActiveDuration)
        var sparkBar = window.oneSelf.toSparkBars(totalActiveDuration);
        var tweetText = sparkBar + " my programming activity over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['IntelliJ', 'coding'].join(',');
        $('#tweetMyActiveDuration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    var urlForCompare = function(resource, streamId) {
        var result = "";
        if (location.hostname == "localhost") {
            result = "http://" + location.hostname + ":5000/quantifieddev/" + resource + "/" + streamId;
        } else {
            result = "http://quantifieddev.herokuapp.com/quantifieddev/" + resource + "/" + streamId;
        }
        return result;
    };

    result.updateBuildHistoryModelForMyStreamId = function() {
        return $.ajax({
            url: urlForCompare("mydev", window.localStorage.streamId),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateBuildHistoryModelForTheirStreamId = function() {
        return $.ajax({
            url: urlForCompare("mydev", window.localStorage.theirStreamId),
            headers: {
                "Authorization": window.localStorage.theirReadToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateActiveEventsModelForMyStreamId = function() {
        return $.ajax({
            url: urlForCompare("myActiveEvents", window.localStorage.streamId),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateActiveEventsModelForTheirStreamId = function() {
        return $.ajax({
            url: urlForCompare("myActiveEvents", window.localStorage.theirStreamId),
            headers: {
                "Authorization": window.localStorage.theirReadToken,
                "Accept": "application/json"
            }
        });
    };
    result.compareBuildHistories = function(myBuildEvents, theirBuildEvents) {
        result.plotBuildHistory(myBuildEvents[0], "#my-build-history");
        result.plotBuildHistory(theirBuildEvents[0], "#their-build-history");
        result.plotComparison("#compare-build-history", myBuildEvents[0], theirBuildEvents[0])
    };
    result.compareActiveEvents = function(myActiveEvents, theirActiveEvents) {
        result.plotActiveEventsFor(myActiveEvents[0], "#my-active-events");
        result.plotActiveEventsFor(theirActiveEvents[0], "#their-active-events");
        result.plotComparisonForActiveEvents("#compare-active-events", myActiveEvents[0], theirActiveEvents[0])
    };

    var handlePlotComparisonGraphsSuccess = function(myBuildEvents, theirBuildEvents) {
         $("#compare-stream-id-errors").text("");
         result.compareBuildHistories(myBuildEvents, theirBuildEvents)
    }

    result.plotComparisonGraphs = function() {
        $.when(result.updateBuildHistoryModelForMyStreamId(), result.updateBuildHistoryModelForTheirStreamId())
            .done(handlePlotComparisonGraphsSuccess).fail(failureCallback("#compare-stream-id-errors","Incorrect streamid or read token!"));
        $.when(result.updateActiveEventsModelForMyStreamId(), result.updateActiveEventsModelForTheirStreamId())
            .done(result.compareActiveEvents).fail("Error getting active events!");
    };

    return result;
}

window.qd = qd();<commit_msg>refactored url constructor<commit_after>var qd = function() {
    var result = {};
    var modelUpdateCallbacks = [];

    //change this to accomodate varying streamids (for compare functionality)

    var url = function(resource, streamId) {
        var result = "";
        if (location.hostname == "localhost") {
            result = "http://" + location.hostname + ":5000/quantifieddev/" + resource + "/" + streamId;
        } else {
            result = "http://quantifieddev.herokuapp.com/quantifieddev/" + resource + "/" + streamId;
        }
        return result;
    };
    var postAjax = function(urlParam, successCallback, failureCallback) {
        $.ajax({
            url: url(urlParam,window.localStorage.streamid),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            },
            success: successCallback,
            error: function(error) {
                if (failureCallback)
                    failureCallback(error);
            }
        });

    }
    var compare = function(todaysEvents, yesterdayEvents) {
        var difference = todaysEvents - yesterdayEvents;
        var percentChange = (difference / yesterdayEvents) * 100;
        return Math.ceil(percentChange);
    }
    var myDevSuccessCallback = function(buildEvents) {
        $("#stream-id-errors").text("");
        result.buildEvents = buildEvents;
        populateBuildTilesData(buildEvents);
        modelUpdateCallbacks.forEach(function(c) {
            c();
        });

    }
    var failureCallback = function(divId, msg) {
        return function() {
            $(divId).text(msg);
        }
    }
    var populateBuildTilesData = function(buildEvents) {
        var todaysBuild = buildEvents[buildEvents.length - 1]; // last record
        var yesterdaysBuild = buildEvents[buildEvents.length - 2];
        var totalBuildsForToday = todaysBuild.passed + todaysBuild.failed;
        var totalBuildsForYesterday = yesterdaysBuild.passed + yesterdaysBuild.failed;
        result.todaysPassedBuildCount = todaysBuild.passed;
        result.todaysFailedBuildCount = todaysBuild.failed;
        result.todaysTotalBuildCount = totalBuildsForToday;
        result.totalBuildComparison = compare(totalBuildsForToday, totalBuildsForYesterday);
        result.passedBuildComparison = compare(todaysBuild.passed, yesterdaysBuild.passed);
        result.failedBuildComparison = compare(todaysBuild.failed, yesterdaysBuild.failed);
    }
    result.updateBuildModel = function() {
        postAjax("mydev", myDevSuccessCallback, failureCallback("#stream-id-errors", "Incorrect streamid or read token!"))
    }
    var myWtfSuccessCallback = function(wtfEvents) {
        result.wtfEvents = wtfEvents;
        result.plotWTFHistory();
    }
    result.updateWTFModel = function() {
        postAjax("mywtf", myWtfSuccessCallback)
    };
    var myHydrationSuccessCallback = function(hydrationEvents) {
        result.hydrationEvents = hydrationEvents;
        result.plotHydrationHistory();
    }
    result.updateHydrationModel = function() {
        postAjax("myhydration", myHydrationSuccessCallback)
    };
    var myCaffeineSuccessCallback = function(caffeineEvents) {
        result.caffeineEvents = caffeineEvents;
        result.plotCaffeineHistory();
    }
    result.updateCaffeineModel = function() {
        postAjax("mycaffeine", myCaffeineSuccessCallback)

    };
    var buildDurationSuccessCallback = function(buildDurationEvents) {
        result.buildDurationEvents = buildDurationEvents;
        result.plotBuildDurationHistory();
    }
    result.updateBuildDurationModel = function() {
        postAjax("buildDuration", buildDurationSuccessCallback)

    };
    var hourlyBuildSuccessCallback = function(hourlyBuildEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyBuildEvents = hourlyBuildEvents;
        result.plotHourlyEventMap('#hourlyBuild-heat-map', hourlyBuildEvents);
    }

    result.updateHourlyBuildHeatMap = function() {
        postAjax("hourlyBuildCount", hourlyBuildSuccessCallback)

    };
    var hourlyWtfSuccessCallback = function(hourlyWtfEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyWtfEvents = hourlyWtfEvents;
        result.plotHourlyEventMap('#hourlyWtf-heat-map', hourlyWtfEvents);
    }
    result.updateHourlyWtfHeatMap = function() {
        postAjax("hourlyWtfCount", hourlyWtfSuccessCallback)
    };

    var hourlyHydrationSuccessCallback = function(hourlyHydrationEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyHydrationEvents = hourlyHydrationEvents;
        result.plotHourlyEventMap('#hourlyHydration-heat-map', hourlyHydrationEvents);
    }
    result.updateHourlyHydrationHeatMap = function() {
        postAjax("hourlyHydrationCount", hourlyHydrationSuccessCallback)

    };
    var hourlyCaffeineSuccessCallback = function(hourlyCaffeineEvents) {
        var timezoneOffset = new Date().getTimezoneOffset();
        var timezoneDifferenceInHours = Math.round(timezoneOffset / 60);
        result.timezoneDifferenceInHours = timezoneDifferenceInHours;
        result.hourlyCaffeineEvents = hourlyCaffeineEvents;
        result.plotHourlyEventMap('#hourlyCaffeine-heat-map', hourlyCaffeineEvents);
    }
    result.updateHourlyCaffeineHeatMap = function() {
        postAjax("hourlyCaffeineCount", hourlyCaffeineSuccessCallback)
    };
    var activitySuccessCallback = function(myActiveEvents) {
        result.activeEvents = myActiveEvents;
        result.plotActiveEvents();
    }
    result.updateActiveEvents = function() {
        postAjax("myActiveEvents", activitySuccessCallback)

    };
    result.plotGraphs = function(graphs) {
        graphs.forEach(function(graph) {
            result[graph]();
        })
    }

    result.registerForBuildModelUpdates = function(callback) {
        modelUpdateCallbacks.push(callback);
    }

    result.tweetBuildSparkline = function() {
        if (result.buildEvents === undefined) {
            return;
        }

        var totalBuilds = [];
        var sparkbarDataForDays = 14;
        result.buildEvents.map(function(buildEvent) {
            totalBuilds.push(buildEvent.passed + buildEvent.failed);
        });
        totalBuilds = totalBuilds.slice(totalBuilds.length - sparkbarDataForDays, totalBuilds.length)
        console.log("sparking builds:", totalBuilds)
        var sparkBar = window.oneSelf.toSparkBars(totalBuilds);
        var tweetText = sparkBar + " my builds over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['coding'].join(',');
        $('#tweetMyBuilds').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetWtfSparkline = function() {
        if (result.wtfEvents === undefined) {
            return;
        }

        var totalWtfs = [];
        var sparkbarDataForDays = 14;
        result.wtfEvents.map(function(wtfEvent) {
            totalWtfs.push(wtfEvent.wtfCount);
        });
        totalWtfs = totalWtfs.slice(totalWtfs.length - sparkbarDataForDays, totalWtfs.length)
        console.log("sparking wtfs:", totalWtfs)
        var sparkBar = window.oneSelf.toSparkBars(totalWtfs);
        var tweetText = sparkBar + " my WTFs over the last 2 weeks. The only measure of code quality. See yours at quantifieddev.org";
        var hashTags = ['wtf', 'coding'].join(',');
        $('#tweetMyWtfs').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetHydrationSparkline = function() {
        if (result.hydrationEvents === undefined) {
            return;
        }

        var totalHydrations = [];
        var sparkbarDataForDays = 14;

        result.hydrationEvents.map(function(hydrationEvent) {
            totalHydrations.push(hydrationEvent.hydrationCount);
        });

        totalHydrations = totalHydrations.slice(totalHydrations.length - sparkbarDataForDays, totalHydrations.length);
        console.log("sparking hydrations:", totalHydrations)
        var sparkBar = window.oneSelf.toSparkBars(totalHydrations);
        var tweetText = sparkBar + " my hydration levels over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['hydrate', 'coding'].join(',');
        $('#tweetMyHydration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetCaffeineSparkline = function() {
        if (result.caffeineEvents === undefined) {
            return;
        }

        var totalCaffeine = [];
        var sparkbarDataForDays = 14;
        result.caffeineEvents.map(function(caffeineEvent) {
            totalCaffeine.push(caffeineEvent.caffeineCount);
        });

        totalCaffeine = totalCaffeine.slice(totalCaffeine.length - sparkbarDataForDays, totalCaffeine.length);
        console.log("sparking caffeine:", totalCaffeine)
        var sparkBar = window.oneSelf.toSparkBars(totalCaffeine);
        var tweetText = sparkBar + " my caffeine levels over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['coffee', 'coding'].join(',');
        $('#tweetMyCaffeine').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetBuildDurationSparkline = function() {
        if (result.buildDurationEvents === undefined) {
            return;
        }

        var totalBuildDuration = [];
        var sparkbarDataForDays = 14;
        result.buildDurationEvents.map(function(buildDurationEvent) {
            totalBuildDuration.push(buildDurationEvent.avgBuildDuration);
        });

        totalBuildDuration = totalBuildDuration.slice(totalBuildDuration.length - sparkbarDataForDays, totalBuildDuration.length);
        console.log("sparking totalBuildDuration:", totalBuildDuration)
        var sparkBar = window.oneSelf.toSparkBars(totalBuildDuration);
        var tweetText = sparkBar + " my build duration over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['buildDuration', 'coding'].join(',');
        $('#tweetMyBuildDuration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.tweetActiveEventSparkline = function() {
        if (result.activeEvents === undefined) {
            return;
        }

        var totalActiveDuration = [];
        var sparkbarDataForDays = 14;
        result.activeEvents.map(function(activeEvent) {
            totalActiveDuration.push(activeEvent.totalActiveDuration);
        });

        totalActiveDuration = totalActiveDuration.slice(totalActiveDuration.length - sparkbarDataForDays, totalActiveDuration.length);
        console.log("sparking totalActiveDuration:", totalActiveDuration)
        var sparkBar = window.oneSelf.toSparkBars(totalActiveDuration);
        var tweetText = sparkBar + " my programming activity over the last 2 weeks. See yours at quantifieddev.org";
        var hashTags = ['IntelliJ', 'coding'].join(',');
        $('#tweetMyActiveDuration').attr('href', "https://twitter.com/share?url=''&hashtags=" + hashTags + "&text=" + tweetText);
    };

    result.updateBuildHistoryModelForMyStreamId = function() {
        return $.ajax({
            url: url("mydev", window.localStorage.streamId),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateBuildHistoryModelForTheirStreamId = function() {
        return $.ajax({
            url: url("mydev", window.localStorage.theirStreamId),
            headers: {
                "Authorization": window.localStorage.theirReadToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateActiveEventsModelForMyStreamId = function() {
        return $.ajax({
            url: url("myActiveEvents", window.localStorage.streamId),
            headers: {
                "Authorization": window.localStorage.readToken,
                "Accept": "application/json"
            }
        });
    };
    result.updateActiveEventsModelForTheirStreamId = function() {
        return $.ajax({
            url: url("myActiveEvents", window.localStorage.theirStreamId),
            headers: {
                "Authorization": window.localStorage.theirReadToken,
                "Accept": "application/json"
            }
        });
    };
    result.compareBuildHistories = function(myBuildEvents, theirBuildEvents) {
        result.plotBuildHistory(myBuildEvents[0], "#my-build-history");
        result.plotBuildHistory(theirBuildEvents[0], "#their-build-history");
        result.plotComparison("#compare-build-history", myBuildEvents[0], theirBuildEvents[0])
    };
    result.compareActiveEvents = function(myActiveEvents, theirActiveEvents) {
        result.plotActiveEventsFor(myActiveEvents[0], "#my-active-events");
        result.plotActiveEventsFor(theirActiveEvents[0], "#their-active-events");
        result.plotComparisonForActiveEvents("#compare-active-events", myActiveEvents[0], theirActiveEvents[0])
    };

    var handlePlotComparisonGraphsSuccess = function(myBuildEvents, theirBuildEvents) {
         $("#compare-stream-id-errors").text("");
         result.compareBuildHistories(myBuildEvents, theirBuildEvents)
    }

    result.plotComparisonGraphs = function() {
        $.when(result.updateBuildHistoryModelForMyStreamId(), result.updateBuildHistoryModelForTheirStreamId())
            .done(handlePlotComparisonGraphsSuccess).fail(failureCallback("#compare-stream-id-errors","Incorrect streamid or read token!"));
        $.when(result.updateActiveEventsModelForMyStreamId(), result.updateActiveEventsModelForTheirStreamId())
            .done(result.compareActiveEvents).fail("Error getting active events!");
    };

    return result;
}

window.qd = qd();<|endoftext|>


<commit_before>'use strict';

var $ = require('jquery');
var ko = require('knockout');
var bootbox = require('bootbox');
require('jquery-ui');
require('knockout-sortable');

var $osf = require('./osfHelpers');

var contribsEqual = function(a, b) {
    return a.id === b.id &&
        a.visible === b.visible &&
        a.permission === b.permission &&
        Boolean(a.deleteStaged) === Boolean(b.deleteStaged);
};

// Modified from http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript
var arraysEqual = function(a, b) {
    var i = a.length;
    if (i !== b.length) { return false;}
    while (i--) {
        if (!contribsEqual(a[i], b[i])) {return false;}
    }
    return true;
};

var sortMap = {
    surname: {
        label: 'Surname',
        order: 1,
        func: function(item) {
            return item.surname;
        }
    }
};

// TODO: We shouldn't need both pageOwner (the current user) and currentUserCanEdit. Separate
// out the permissions-related functions and remove currentUserCanEdit.
var ContributorModel = function(contributor, currentUserCanEdit, pageOwner, isRegistration, isAdmin) {

    var self = this;
    $.extend(self, contributor);

    self.permissionList = [
        {value: 'read', text: 'Read'},
        {value: 'write', text: 'Read + Write'},
        {value: 'admin', text: 'Administrator'}
    ];
    self.getPermission = function(permission) {
        for(var i = 0; i < self.permissionList.length; i++) {
            if(permission === self.permissionList[i].value) {
                return self.permissionList[i];
            }
        }
        return self.permissionList[0];
    };

    self.currentUserCanEdit = currentUserCanEdit;
    self.isAdmin = isAdmin;
    self.visible = ko.observable(contributor.visible);
    self.permission = ko.observable(contributor.permission);
    self.curPermission = ko.observable(self.getPermission(self.permission()));
    self.deleteStaged = ko.observable(contributor.deleteStaged || false);
    self.removeContributor = 'Remove contributor';
    self.pageOwner = pageOwner;
    self.serialize = function() {
        return JSON.parse(ko.toJSON(self));
    };

    self.canEdit = ko.computed(function() {
      return self.currentUserCanEdit && !self.isAdmin;
    });

    self.remove = function() {
        self.deleteStaged(true);
    };
    self.unremove = function(data, event) {
        var $target = $(event.target);
        if (!$target.hasClass('contrib-button')) {
            self.deleteStaged(false);
        }
        // Allow default action
        return true;
    };
    self.profileUrl = ko.observable(contributor.url);
    self.notDeleteStaged = ko.computed(function() {
        return !self.deleteStaged();
    });
    self.formatPermission = ko.computed(function() {
        var permission = self.permission();
        return self.getPermission(permission).text;
    });

    self.canRemove = ko.computed(function(){
        return (self.id === pageOwner.id) && !isRegistration;
    });

    self.change = ko.computed(function() {
        self.permission(self.curPermission().value);
        var current_val = self.curPermission().value;
        return current_val === self.original;
    });

    // TODO: copied-and-pasted from nodeControl. When nodeControl
    // gets refactored, update this to use global method.
    self.removeSelf = function() {

        var id = self.id,
            name = self.fullname;
        var payload = {
            id: id,
            name: self.fullname
        };
        $osf.postJSON(
            nodeApiUrl + 'beforeremovecontributors/',
            payload
        ).done(function(response) {
            var prompt = $osf.joinPrompts(response.prompts, 'Remove ' + name + ' from contributor list?');
            bootbox.confirm({
                title: 'Delete Contributor?',
                message: prompt,
                callback: function(result) {
                    if (result) {
                        $osf.postJSON(
                            nodeApiUrl + 'removecontributors/',
                            payload
                        ).done(function(response) {
                            if (response.redirectUrl) {
                                window.location.href = response.redirectUrl;
                            } else {
                                window.location.reload();
                            }
                        }).fail(
                            $osf.handleJSONError
                        );
                    }
                }
            });
        }).fail(
            $osf.handleJSONError
        );
        return false;
    };

};

var MessageModel = function(text, level) {

    var self = this;

    self.text = ko.observable(text || '');
    self.level = ko.observable(level || '');

    var classes = {
        success: 'text-success',
        error: 'text-danger'
    };

    self.cssClass = ko.computed(function() {
        var out = classes[self.level()];
        if (out === undefined) {
            out = '';
        }
        return out;
    });

};

var ContributorsViewModel = function(contributors, adminContributors, user, isRegistration) {

    var self = this;

    self.original = ko.observableArray(contributors);

    self.contributors = ko.observableArray();
    self.adminContributors = adminContributors;

    self.user = ko.observable(user);
    // TODO: Does this need to be an observable?
    self.userIsAdmin  = ko.observable($.inArray('admin', user.permissions) !== -1);
    self.canEdit = ko.computed(function() {
        return (self.userIsAdmin()) && !isRegistration;
    });

    self.messages = ko.observableArray([]);

    // Hack: Ignore beforeunload when submitting
    // TODO: Single-page-ify and remove this
    self.forceSubmit = ko.observable(false);

    self.sortKeys = Object.keys(sortMap);
    self.sortKey = ko.observable(self.sortKeys[0]);
    self.sortOrder = ko.observable(0);
    self.sortClass = ko.computed(function() {
        if (self.sortOrder() === 1) {
                return 'fa fa-caret-up';
        } else if (self.sortOrder() === -1) {
                return 'fa fa-caret-down';
        }
    });
    self.sortFunc = ko.computed(function() {
        return sortMap[self.sortKey()].func;
    });
    self.sortKey.subscribe(function() {
        self.sortOrder(0);
    });

    self.changed = ko.computed(function() {
        var contributorData = ko.utils.arrayMap(self.contributors(), function(item) {
            return item.serialize();
        });
        return !arraysEqual(contributorData, self.original());
    });

    self.retainedContributors = ko.computed(function() {
        return ko.utils.arrayFilter(self.contributors(), function(item) {
            return !item.deleteStaged();
        });
    });
    self.validAdmin = ko.computed(function() {
        var admins = ko.utils.arrayFilter(self.retainedContributors(), function(item) {
            return item.permission() === 'admin' &&
                item.registered;
        });
        return !!admins.length;
    });
    self.validVisible = ko.computed(function() {
        return ko.utils.arrayFilter(self.retainedContributors(), function(item) {
            return item.visible();
        }).length;
    });

    self.canSubmit = ko.computed(function() {
        return self.changed() && self.validAdmin() && self.validVisible();
    });
    self.changed.subscribe(function() {
        self.messages([]);
    });

    self.validAdmin.subscribe(function(value) {
        if (!value) {
            self.messages.push(
                new MessageModel(
                    'Must have at least one registered admin contributor',
                    'error'
                )
            );
        } else {
            self.messages([]);
        }
    });
    self.validVisible.subscribe(function(value) {
        if (!value) {
            self.messages.push(
                new MessageModel(
                    'Must have at least one visible contributor',
                    'error'
                )
            );
        }
    });

    self.init = function() {
        self.messages([]);
        self.contributors(self.original().map(function(item) {
            return new ContributorModel(item, self.canEdit(), self.user(), isRegistration);
        }));
        self.adminContributors = adminContributors.map(function(contributor) {
          return new ContributorModel(contributor, self.canEdit(), self.user(), isRegistration, true);
        });
    };

    self.initListeners = function() {
        var self = this;
        // Warn on add contributors if pending changes
        $('[href="#addContributors"]').on('click', function() {
            if (self.changed()) {
                $osf.growl('Error:',
                        'Your contributor list has unsaved changes. Please ' +
                        'save or cancel your changes before adding ' +
                        'contributors.'
                );
                return false;
            }
        });
        // Warn on URL change if pending changes
        $(window).on('beforeunload', function() {
            if (self.changed() && !self.forceSubmit()) {
                // TODO: Use GrowlBox.
                return 'There are unsaved changes to your contributor ' +
                    'settings. Are you sure you want to leave this page?';
            }
        });
    };

    self.init();
    self.initListeners();

    self.sort = function() {
        if (self.sortOrder() === 0) {
            self.sortOrder(sortMap[self.sortKey()].order);
        } else {
            self.sortOrder(-1 * self.sortOrder());
        }
        var func = sortMap[self.sortKey()].func;
        var comparator = function(left, right) {
            var leftVal = func(left);
            var rightVal = func(right);
            var spaceship = leftVal === rightVal ?
                0 :
                (leftVal < rightVal ?
                    -1 :
                    1
                );
            return self.sortOrder() * spaceship;
        };
        self.contributors.sort(comparator);
    };

    self.serialize = function() {
        return ko.utils.arrayMap(
            ko.utils.arrayFilter(self.contributors(), function(contributor) {
                return !contributor.deleteStaged();
            }),
            function(contributor) {
                var temp = contributor.serialize();
                var minInfo = {id: temp.id, permission: temp.permission, registered: temp.registered, visible: temp.visible};
                return minInfo;
            }
        );
    };

    self.cancel = function() {
        self.init();
    };

    self.submit = function() {
        self.messages([]);
        self.forceSubmit(true);
        bootbox.confirm({
            title: 'Save changes?',
            message: 'Are you sure you want to save these changes?',
            callback: function(result) {
                if (result) {
                    $osf.postJSON(
                        nodeApiUrl + 'contributors/manage/',
                        {contributors: self.serialize()}
                    ).done(function(response) {
                        // TODO: Don't reload the page here; instead use code below
                        if (response.redirectUrl) {
                            window.location.href = response.redirectUrl;
                        } else {
                            window.location.reload();
                        }
                    }).fail(function(xhr) {
                        self.init();
                        var response = xhr.responseJSON;
                        self.messages.push(
                            new MessageModel(
                                'Submission failed: ' + response.message_long,
                                'error'
                            )
                        );
                        self.forceSubmit(false);
                    });
                }
            }
        });
    };

};

////////////////
// Public API //
////////////////

function ContribManager(selector, contributors, adminContributors, user, isRegistration) {
    var self = this;
    self.selector = selector;
    self.$element = $(selector);
    self.contributors = contributors;
    self.adminContributors = adminContributors;
    self.viewModel = new ContributorsViewModel(contributors, adminContributors, user, isRegistration);
    self.init();
}

ContribManager.prototype.init = function() {
    ko.applyBindings(this.viewModel, this.$element[0]);
    this.$element.show();
};

module.exports = ContribManager;
<commit_msg>Make changes<commit_after>'use strict';

var $ = require('jquery');
var ko = require('knockout');
var bootbox = require('bootbox');
require('jquery-ui');
require('knockout-sortable');

var $osf = require('./osfHelpers');

var contribsEqual = function(a, b) {
    return a.id === b.id &&
        a.visible === b.visible &&
        a.permission === b.permission &&
        Boolean(a.deleteStaged) === Boolean(b.deleteStaged);
};

// Modified from http://stackoverflow.com/questions/7837456/comparing-two-arrays-in-javascript
var arraysEqual = function(a, b) {
    var i = a.length;
    if (i !== b.length) { return false;}
    while (i--) {
        if (!contribsEqual(a[i], b[i])) {return false;}
    }
    return true;
};

var sortMap = {
    surname: {
        label: 'Surname',
        order: 1,
        func: function(item) {
            return item.surname;
        }
    }
};

// TODO: We shouldn't need both pageOwner (the current user) and currentUserCanEdit. Separate
// out the permissions-related functions and remove currentUserCanEdit.
var ContributorModel = function(contributor, currentUserCanEdit, pageOwner, isRegistration, isAdmin) {

    var self = this;
    $.extend(self, contributor);

    self.permissionList = [
        {value: 'read', text: 'Read'},
        {value: 'write', text: 'Read + Write'},
        {value: 'admin', text: 'Administrator'}
    ];
    self.getPermission = function(permission) {
        for(var i = 0; i < self.permissionList.length; i++) {
            if(permission === self.permissionList[i].value) {
                return self.permissionList[i];
            }
        }
        return self.permissionList[0];
    };

    self.currentUserCanEdit = currentUserCanEdit;
    self.isAdmin = isAdmin;
    self.visible = ko.observable(contributor.visible);
    self.permission = ko.observable(contributor.permission);
    self.curPermission = ko.observable(self.getPermission(self.permission()));
    self.deleteStaged = ko.observable(contributor.deleteStaged || false);
    self.removeContributor = 'Remove contributor';
    self.pageOwner = pageOwner;
    self.serialize = function() {
        return JSON.parse(ko.toJSON(self));
    };

    self.canEdit = ko.computed(function() {
      return self.currentUserCanEdit && !self.isAdmin;
    });

    self.remove = function() {
        self.deleteStaged(true);
    };
    self.unremove = function(data, event) {
        var $target = $(event.target);
        if (!$target.hasClass('contrib-button')) {
            self.deleteStaged(false);
        }
        // Allow default action
        return true;
    };
    self.profileUrl = ko.observable(contributor.url);
    self.notDeleteStaged = ko.computed(function() {
        return !self.deleteStaged();
    });
    self.formatPermission = ko.computed(function() {
        var permission = self.permission();
        return self.getPermission(permission).text;
    });

    self.canRemove = ko.computed(function(){
        return (self.id === pageOwner.id) && !isRegistration;
    });

    self.change = ko.pureComputed(function() {
        self.permission(self.curPermission().value);
        var currentValue = self.curPermission().value;
        return currentValue === self.original;
    });

    // TODO: copied-and-pasted from nodeControl. When nodeControl
    // gets refactored, update this to use global method.
    self.removeSelf = function() {

        var id = self.id,
            name = self.fullname;
        var payload = {
            id: id,
            name: self.fullname
        };
        $osf.postJSON(
            nodeApiUrl + 'beforeremovecontributors/',
            payload
        ).done(function(response) {
            var prompt = $osf.joinPrompts(response.prompts, 'Remove ' + name + ' from contributor list?');
            bootbox.confirm({
                title: 'Delete Contributor?',
                message: prompt,
                callback: function(result) {
                    if (result) {
                        $osf.postJSON(
                            nodeApiUrl + 'removecontributors/',
                            payload
                        ).done(function(response) {
                            if (response.redirectUrl) {
                                window.location.href = response.redirectUrl;
                            } else {
                                window.location.reload();
                            }
                        }).fail(
                            $osf.handleJSONError
                        );
                    }
                }
            });
        }).fail(
            $osf.handleJSONError
        );
        return false;
    };

};

var MessageModel = function(text, level) {

    var self = this;

    self.text = ko.observable(text || '');
    self.level = ko.observable(level || '');

    var classes = {
        success: 'text-success',
        error: 'text-danger'
    };

    self.cssClass = ko.computed(function() {
        var out = classes[self.level()];
        if (out === undefined) {
            out = '';
        }
        return out;
    });

};

var ContributorsViewModel = function(contributors, adminContributors, user, isRegistration) {

    var self = this;

    self.original = ko.observableArray(contributors);

    self.contributors = ko.observableArray();
    self.adminContributors = adminContributors;

    self.user = ko.observable(user);
    // TODO: Does this need to be an observable?
    self.userIsAdmin  = ko.observable($.inArray('admin', user.permissions) !== -1);
    self.canEdit = ko.computed(function() {
        return (self.userIsAdmin()) && !isRegistration;
    });

    self.messages = ko.observableArray([]);

    // Hack: Ignore beforeunload when submitting
    // TODO: Single-page-ify and remove this
    self.forceSubmit = ko.observable(false);

    self.sortKeys = Object.keys(sortMap);
    self.sortKey = ko.observable(self.sortKeys[0]);
    self.sortOrder = ko.observable(0);
    self.sortClass = ko.computed(function() {
        if (self.sortOrder() === 1) {
                return 'fa fa-caret-up';
        } else if (self.sortOrder() === -1) {
                return 'fa fa-caret-down';
        }
    });
    self.sortFunc = ko.computed(function() {
        return sortMap[self.sortKey()].func;
    });
    self.sortKey.subscribe(function() {
        self.sortOrder(0);
    });

    self.changed = ko.computed(function() {
        var contributorData = ko.utils.arrayMap(self.contributors(), function(item) {
            return item.serialize();
        });
        return !arraysEqual(contributorData, self.original());
    });

    self.retainedContributors = ko.computed(function() {
        return ko.utils.arrayFilter(self.contributors(), function(item) {
            return !item.deleteStaged();
        });
    });
    self.validAdmin = ko.computed(function() {
        var admins = ko.utils.arrayFilter(self.retainedContributors(), function(item) {
            return item.permission() === 'admin' &&
                item.registered;
        });
        return !!admins.length;
    });
    self.validVisible = ko.computed(function() {
        return ko.utils.arrayFilter(self.retainedContributors(), function(item) {
            return item.visible();
        }).length;
    });

    self.canSubmit = ko.computed(function() {
        return self.changed() && self.validAdmin() && self.validVisible();
    });
    self.changed.subscribe(function() {
        self.messages([]);
    });

    self.validAdmin.subscribe(function(value) {
        if (!value) {
            self.messages.push(
                new MessageModel(
                    'Must have at least one registered admin contributor',
                    'error'
                )
            );
        } else {
            self.messages([]);
        }
    });
    self.validVisible.subscribe(function(value) {
        if (!value) {
            self.messages.push(
                new MessageModel(
                    'Must have at least one visible contributor',
                    'error'
                )
            );
        }
    });

    self.init = function() {
        self.messages([]);
        self.contributors(self.original().map(function(item) {
            return new ContributorModel(item, self.canEdit(), self.user(), isRegistration);
        }));
        self.adminContributors = adminContributors.map(function(contributor) {
          return new ContributorModel(contributor, self.canEdit(), self.user(), isRegistration, true);
        });
    };

    self.initListeners = function() {
        var self = this;
        // Warn on add contributors if pending changes
        $('[href="#addContributors"]').on('click', function() {
            if (self.changed()) {
                $osf.growl('Error:',
                        'Your contributor list has unsaved changes. Please ' +
                        'save or cancel your changes before adding ' +
                        'contributors.'
                );
                return false;
            }
        });
        // Warn on URL change if pending changes
        $(window).on('beforeunload', function() {
            if (self.changed() && !self.forceSubmit()) {
                // TODO: Use GrowlBox.
                return 'There are unsaved changes to your contributor ' +
                    'settings. Are you sure you want to leave this page?';
            }
        });
    };

    self.init();
    self.initListeners();

    self.sort = function() {
        if (self.sortOrder() === 0) {
            self.sortOrder(sortMap[self.sortKey()].order);
        } else {
            self.sortOrder(-1 * self.sortOrder());
        }
        var func = sortMap[self.sortKey()].func;
        var comparator = function(left, right) {
            var leftVal = func(left);
            var rightVal = func(right);
            var spaceship = leftVal === rightVal ?
                0 :
                (leftVal < rightVal ?
                    -1 :
                    1
                );
            return self.sortOrder() * spaceship;
        };
        self.contributors.sort(comparator);
    };

    self.serialize = function() {
        return ko.utils.arrayMap(
            ko.utils.arrayFilter(self.contributors(), function(contributor) {
                return !contributor.deleteStaged();
            }),
            function(contributor) {
                return contributor.serialize();
            }
        );
    };

    self.cancel = function() {
        self.init();
    };

    self.submit = function() {
        self.messages([]);
        self.forceSubmit(true);
        bootbox.confirm({
            title: 'Save changes?',
            message: 'Are you sure you want to save these changes?',
            callback: function(result) {
                if (result) {
                    $osf.postJSON(
                        nodeApiUrl + 'contributors/manage/',
                        {contributors: self.serialize()}
                    ).done(function(response) {
                        // TODO: Don't reload the page here; instead use code below
                        if (response.redirectUrl) {
                            window.location.href = response.redirectUrl;
                        } else {
                            window.location.reload();
                        }
                    }).fail(function(xhr) {
                        self.init();
                        var response = xhr.responseJSON;
                        self.messages.push(
                            new MessageModel(
                                'Submission failed: ' + response.message_long,
                                'error'
                            )
                        );
                        self.forceSubmit(false);
                    });
                }
            }
        });
    };

};

////////////////
// Public API //
////////////////

function ContribManager(selector, contributors, adminContributors, user, isRegistration) {
    var self = this;
    self.selector = selector;
    self.$element = $(selector);
    self.contributors = contributors;
    self.adminContributors = adminContributors;
    self.viewModel = new ContributorsViewModel(contributors, adminContributors, user, isRegistration);
    self.init();
}

ContribManager.prototype.init = function() {
    ko.applyBindings(this.viewModel, this.$element[0]);
    this.$element.show();
};

module.exports = ContribManager;
<|endoftext|>


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

var chai = require('chai');
var expect = chai.expect;

describe('capitalize', function() {
	it('capitalizes single words', function() {
		expect(capitalize('express')).to.equal('Express');
		expect(capitalize('cats')).to.equal('Cats');
	});

	it('makes the rest of the string lowercase', function() {
		expect(capitalize('javaScript')).to.equal('Javascript');
	});

	it('leaves empty strings alone', function() {
		expect(capitalize('')).to.equal('');
	});

	it('leaves strings with no words alone', function() {
		expect(capitalize(' ')).to.equal(' ');
		expect(capitalize('123')).to.equal('123');
	});

	it('capitalizes multiple-word strings', function() {
		expect(capitalize('what is Express')).to.equal('What is express');
		expect(capitalize('i love lamp')).to.equal('I love lamp');
	});

	it('leaves already-capitalized words alone', function() {
		expect(capitalize('Express')).to.equal('Express');
		expect(capitalize('Evan')).to.equal('Evan');
		expect(capitalize('Catman')).to.equal('Catman');
	});

	it('capitalizes String objects without changing their values', function() {
		var str = new String('who is JavaScript?');
		expect(capitalize(str)).to.equal('Who is javascript?');
		expect(str.valueOf()).to.equal('who is JavaScript?');
	});

	it('throws an error if passed a number', function() {
		expect(function() { capitalize(123); }).to.throw(Error);
	});
});
<commit_msg>Add test demonstrating "not equal"<commit_after>var capitalize = require('../capitalize');

var chai = require('chai');
var expect = chai.expect;

describe('capitalize', function() {
	it('capitalizes single words', function() {
		expect(capitalize('express')).to.equal('Express');
		expect(capitalize('cats')).to.equal('Cats');
	});

	it('makes the rest of the string lowercase', function() {
		expect(capitalize('javaScript')).to.equal('Javascript');
	});

	it('leaves empty strings alone', function() {
		expect(capitalize('')).to.equal('');
	});

	it('leaves strings with no words alone', function() {
		expect(capitalize(' ')).to.equal(' ');
		expect(capitalize('123')).to.equal('123');
	});

	it('capitalizes multiple-word strings', function() {
		expect(capitalize('what is Express')).to.equal('What is express');
		expect(capitalize('i love lamp')).to.equal('I love lamp');
	});

	it('leaves already-capitalized words alone', function() {
		expect(capitalize('Express')).to.equal('Express');
		expect(capitalize('Evan')).to.equal('Evan');
		expect(capitalize('Catman')).to.equal('Catman');
	});

	it('capitalizes String objects without changing their values', function() {
		var str = new String('who is JavaScript?');
		expect(capitalize(str)).to.equal('Who is javascript?');
		expect(str.valueOf()).to.equal('who is JavaScript?');
	});

	it('throws an error if passed a number', function() {
		expect(function() { capitalize(123); }).to.throw(Error);
	});

	it('changes the value', function() {
		expect(capitalize('foo')).not.to.equal('foo');
	});
});
<|endoftext|>


<commit_before>// nodeunit

this.tests = {

    clone: {
        _1arg: function(test){
            var p = {p:{}};
            var c = clone(p);

            test.strictEqual( Object.getPrototypeOf(c), p);
            test.ok(!c.hasOwnProperty('p') );
            test.equal( Object.getOwnPropertyNames(c).length, 0);
            test.strictEqual(c.p, p.p);

            test.done();
        },

        _2args: function(test){
            var p = {p:{}}, s = {s:{}};
            var c = clone(p,s);

                test.strictEqual( Object.getPrototypeOf(c), p);
                test.ok( c.hasOwnProperty('s') );
                test.ok(!c.hasOwnProperty('p') );
                test.equal( Object.getOwnPropertyNames(c).length, 1);
                test.strictEqual(c.p, p.p);
                test.strictEqual(c.s, s.s);

            test.done();
        },

//        _3args: function(test){
//            var p = {p:{name:"proto"}}, s = {s:{name:"state"}}, b = {b:{name:"behavior"}};
//            var c = clone(p,s,b);
//
////                //test.strictEqual( Object.getPrototypeOf(c), b);
////                test.ok( b.isPrototypeOf(c) );
////                //test.strictEqual( Object.getPrototypeOf(b), p);
////                test.ok( p.isPrototypeOf(b) );
//                test.ok( p.isPrototypeOf(c) );
//                test.ok( c.hasOwnProperty('s') );
//                test.ok(!c.hasOwnProperty('p') );
//                test.ok(!c.hasOwnProperty('b') );
//                test.equal( Object.getOwnPropertyNames(c).length, 1);
//                test.strictEqual(c.p, p.p);
//                test.strictEqual(c.s, s.s);
//                test.strictEqual(c.b, b.b);
//
//            test.done();
//        },

        $inits: function(test){
            getterCalls = 0;
            var state, obj = clone.create({
                thisCalls: 0
                },{
                $inits: {
                    getterOnce: function(){
                        this.thisCalls++;
                        getterCalls++;
                        return 'G';
                    }
                }
            });
//console.log(obj.getterOnce.valueOf());
            test.equal(obj.getterOnce, 'G');
            test.equal(obj.getterOnce, 'G');
            test.equal(obj.getterOnce.valueOf(), 'G');
            test.equal(getterCalls, 1);
            //if(Object.defineProperty && Object.defineProperty.name){// !== _shimDefineProperty
                test.equal(obj.thisCalls, 1);
            //}

            test.done();
        },

        create: function(test){
            var c = clone.create({a:1});
            test.ok( c.hasOwnProperty('a') );
//            test.equal( Object.getPrototypeOf(c), clone.prototype);
            test.strictEqual( Object.getOwnPropertyNames(c).length, 1);

            test.done();
        }

    }
};

if(! Object.getOwnPropertyNames )
Object.getOwnPropertyNames = function(obj){
    var names = [];
    for(var name in obj) if( obj.hasOwnProperty(name) ){
        names.push(name);
    }
    return names;
}

//var behavior1$ = {
//    __inits__: {},
//    __defaults__: {},
//    __extends__: Object
//}
//var behavior2$ = {
//    $: {
//        inits: {},
//        defaults: {},
//        extends$: Object
//    }
//}
//var behavior3$ = {
//    extends$: Object,
//    $fields: {
//        field: "default value",
//        lazy: function(){
//
//        },
//        __proto__: Object
//    },
//    method: function(){
//
//    },
//    __proto__: this.$fields
//}
//
//var myClass$ = {
//    extends$: Object,
//    $fields: {
//        field: "default value"
//    },
//    $inits: {
//        lazy: function(){
//
//        }
//    },
//    method: function(){
//
//    }
//}
//
//var instance = Clone($parent);
//var instance = Clone($parent, {field: "value"});
//var instance = Clone.create({field: "value"});
//var child$   = Clone.extend({$fields: {field: "default value"});
//var child$   = Clone.extend($parent, {$fields: {field: "default value"}});
//
//new Clone({})
//Clone.create({})
//Clone.Dict({})

//var behavior31$ = {
//    $fields: {
//        extends$: Object,
//        field: "default value",
//        lazy: function(){
//
//        },
//        __proto__: Object
//    },
//    method: function(){
//
//    },
//    __proto__: this.$defaults
//}
//
//var behavior4$ = {
//    __proto__: Object,
//    $fields: {
//        field: "default value",
//        lazy: function(){
//
//        },
//        __proto__: behavior4$
//    },
//    method: function(){
//
//    },
//    __proto__: this.$defaults
//}<commit_msg>cleanup tests<commit_after>// nodeunit

this.tests = {

    clone: {
        _1arg: function(test){
            var p = {p:{}};
            var c = clone(p);

            test.strictEqual( Object.getPrototypeOf(c), p);
            test.ok(!c.hasOwnProperty('p') );
            test.equal( Object.getOwnPropertyNames(c).length, 0);
            test.strictEqual(c.p, p.p);

            test.done();
        },

        _2args: function(test){
            var p = {p:{}}, s = {s:{}};
            var c = clone(p,s);

                test.strictEqual( Object.getPrototypeOf(c), p);
                test.ok( c.hasOwnProperty('s') );
                test.ok(!c.hasOwnProperty('p') );
                test.equal( Object.getOwnPropertyNames(c).length, 1);
                test.strictEqual(c.p, p.p);
                test.strictEqual(c.s, s.s);

            test.done();
        },

//        _3args: function(test){
//            var p = {p:{name:"proto"}}, s = {s:{name:"state"}}, b = {b:{name:"behavior"}};
//            var c = clone(p,s,b);
//
////                //test.strictEqual( Object.getPrototypeOf(c), b);
////                test.ok( b.isPrototypeOf(c) );
////                //test.strictEqual( Object.getPrototypeOf(b), p);
////                test.ok( p.isPrototypeOf(b) );
//                test.ok( p.isPrototypeOf(c) );
//                test.ok( c.hasOwnProperty('s') );
//                test.ok(!c.hasOwnProperty('p') );
//                test.ok(!c.hasOwnProperty('b') );
//                test.equal( Object.getOwnPropertyNames(c).length, 1);
//                test.strictEqual(c.p, p.p);
//                test.strictEqual(c.s, s.s);
//                test.strictEqual(c.b, b.b);
//
//            test.done();
//        },

        $inits: function(test){
            getterCalls = 0;
            var state, obj = clone.create({
                thisCalls: 0
                },{
                $inits: {
                    getterOnce: function(){
                        this.thisCalls++;
                        getterCalls++;
                        return 'G';
                    }
                }
            });
//console.log(obj.getterOnce.valueOf());
            test.equal(obj.getterOnce, 'G');
            test.equal(obj.getterOnce, 'G');
            test.equal(obj.getterOnce.valueOf(), 'G');
            test.equal(getterCalls, 1);
            //if(Object.defineProperty && Object.defineProperty.name){// !== _shimDefineProperty
                test.equal(obj.thisCalls, 1);
            //}

            test.done();
        },

        create: function(test){
            var c = clone.create({a:1});
            test.ok( c.hasOwnProperty('a') );
//            test.equal( Object.getPrototypeOf(c), clone.prototype);
            test.strictEqual( Object.getOwnPropertyNames(c).length, 1);

            test.done();
        }

    }
};

if(! Object.getOwnPropertyNames )
Object.getOwnPropertyNames = function(obj){
    var names = [];
    for(var name in obj) if( obj.hasOwnProperty(name) ){
        names.push(name);
    }
    return names;
}<|endoftext|>


<commit_before>const assert = require('assert')

// require the lib
const icaro = require('../')

describe('icaro core', () => {
  it('it can listen simple object changes', function(done) {
    const i = icaro()

    i.listen(function(changes) {
      assert.equal(changes.get('foo'), 'bar')
      done()
    })

    i.foo = 'bar'
  })

  it('does not throws error when listener is not a valid function', function() {
    const i = icaro()

    assert.throws(
      () => {
        i.listen({})
      }
    )
  })

  it('it groups multiple changes together', function(done) {
    const i = icaro()

    i.listen(function(changes) {
      assert.equal(changes.get('foo'), 'bar')
      assert.equal(changes.get('baz'), 'bar')
      done()
    })

    i.foo = 'bar'
    i.baz = 'bar'
  })

  it('it can listen arrays and sub children', function(done) {
    const i = icaro()

    i.arr = []
    i.arr.listen(function(changes) {
      assert.equal(changes.get('0'), 'one')
      assert.equal(changes.get('1'), 'two')
      done()
    })

    i.arr.push('one')
    i.arr.push('two')
  })

  it('it can listen array changes', function(done) {
    const arr = icaro(['one', 'two'])

    // can loop
    arr.listen(function() {
      arr.unlisten()
      arr.listen(function() {
        done()
      })
      arr.pop()
    })

    arr.shift()
  })

  it('it can loop arrays', function() {
    const arr = icaro(['one', 'two'])
    const test = []
    // can loop
    arr.forEach(function(item) {
      assert.ok(typeof item === 'string')
      test.push(item)
    })

    assert.ok(test.length === 2)

    for (let item in arr) {
      assert.ok(typeof item === 'string')
      test.push(item)
    }

    assert.ok(test.length === 4)
  })

  it('the toJSON call return properly either an object or an array', function() {
    const arr = icaro([1, 2])
    const obj = icaro({ uno: 1, due: 2 })

    assert.deepEqual(arr.toJSON(), [1, 2])
    assert.deepEqual(obj.toJSON(), { uno: 1, due: 2 })
  })

  it('array values should be listenable if objects', function() {
    const i = icaro([{ value: 'foo' }])
    assert.ok(i[0].listen)
  })

  it('"Array.reverse" will dispatch changes', function(done) {
    const i = icaro(['foo', 'bar'])
    i.listen(function(changes) {
      assert.equal(changes.get('0'), 'bar')
      assert.equal(changes.get('1'), 'foo')
      done()
    })
    i.reverse()
  })

  it('"Array.sort" will dispatch changes', function(done) {
    const i = icaro(['a', 'c', 'b'])
    i.listen(function(changes) {
      assert.ok(!changes.get('0')) // 'a' was never moved
      assert.equal(changes.get('1'), 'b')
      assert.equal(changes.get('2'), 'c')
      done()
    })
    i.sort()
  })
})
<commit_msg>changed test description (#11)<commit_after>const assert = require('assert')

// require the lib
const icaro = require('../')

describe('icaro core', () => {
  it('it can listen simple object changes', function(done) {
    const i = icaro()

    i.listen(function(changes) {
      assert.equal(changes.get('foo'), 'bar')
      done()
    })

    i.foo = 'bar'
  })

  it('throws error when listener is not a valid function', function() {
    const i = icaro()

    assert.throws(
      () => {
        i.listen({})
      }
    )
  })

  it('it groups multiple changes together', function(done) {
    const i = icaro()

    i.listen(function(changes) {
      assert.equal(changes.get('foo'), 'bar')
      assert.equal(changes.get('baz'), 'bar')
      done()
    })

    i.foo = 'bar'
    i.baz = 'bar'
  })

  it('it can listen arrays and sub children', function(done) {
    const i = icaro()

    i.arr = []
    i.arr.listen(function(changes) {
      assert.equal(changes.get('0'), 'one')
      assert.equal(changes.get('1'), 'two')
      done()
    })

    i.arr.push('one')
    i.arr.push('two')
  })

  it('it can listen array changes', function(done) {
    const arr = icaro(['one', 'two'])

    // can loop
    arr.listen(function() {
      arr.unlisten()
      arr.listen(function() {
        done()
      })
      arr.pop()
    })

    arr.shift()
  })

  it('it can loop arrays', function() {
    const arr = icaro(['one', 'two'])
    const test = []
    // can loop
    arr.forEach(function(item) {
      assert.ok(typeof item === 'string')
      test.push(item)
    })

    assert.ok(test.length === 2)

    for (let item in arr) {
      assert.ok(typeof item === 'string')
      test.push(item)
    }

    assert.ok(test.length === 4)
  })

  it('the toJSON call return properly either an object or an array', function() {
    const arr = icaro([1, 2])
    const obj = icaro({ uno: 1, due: 2 })

    assert.deepEqual(arr.toJSON(), [1, 2])
    assert.deepEqual(obj.toJSON(), { uno: 1, due: 2 })
  })

  it('array values should be listenable if objects', function() {
    const i = icaro([{ value: 'foo' }])
    assert.ok(i[0].listen)
  })

  it('"Array.reverse" will dispatch changes', function(done) {
    const i = icaro(['foo', 'bar'])
    i.listen(function(changes) {
      assert.equal(changes.get('0'), 'bar')
      assert.equal(changes.get('1'), 'foo')
      done()
    })
    i.reverse()
  })

  it('"Array.sort" will dispatch changes', function(done) {
    const i = icaro(['a', 'c', 'b'])
    i.listen(function(changes) {
      assert.ok(!changes.get('0')) // 'a' was never moved
      assert.equal(changes.get('1'), 'b')
      assert.equal(changes.get('2'), 'c')
      done()
    })
    i.sort()
  })
})
<|endoftext|>


<commit_before>import {test} from 'uvu'
import * as assert from 'uvu/assert'
import {createApp} from '../main.js'

test('app is created and responds to state changes', async () => {
  const app = createApp(0)

  app.render((state) => {
    assert.is(app.state, 2)
  })

  app.state = 1

  app.state++
})
<commit_msg>Edit test<commit_after>import {test} from 'uvu'
import * as assert from 'uvu/assert'
import {createApp} from '../main.js'

test('app is created and responds to state changes', async () => {
  const app = createApp(0)

  app.render((state) => {
    assert.is(state, 2)
  })

  app.state = 1

  app.state++
})
<|endoftext|>


<commit_before>#!/usr/bin/env node

var split = require('./split-file.js');

if (require.main === module) {
  cli();
}

function cli() {
  var option = process.argv[2];
  switch (option) {
    case '-m':
      cliMerge();
      break;
    case '-s':
      cliSplit();
      break;
    default:
      printLegend();
  }
}

function cliSplit() {
  var file = process.argv[3];
  var parts = parseInt(process.argv[4]);

  if (isNaN(parts)) {
    return printLegend();
  }

  split.splitFile(file, parts).then(function (names) {
    console.log('Successfully splitted into: ' + names);
  }).catch(function (err) {
    console.log('An error occured:');
    console.log(err);
  });
}

function cliMerge() {
  var files = [];
  var output_file = process.argv[3];

  for (var i = 4; i < process.argv.length; i++) {
    files.push(process.argv[i]);
  }

  split.mergeFiles(files, output_file).then(function(names) {
    console.log('Succesfully merged the parts into ' + output_file);
  }).catch(function (err) {
    console.log('An error occured:');
    console.log(err);
  });
}

function printLegend() {
  console.log("Usage: split-file -s input.bin 5");
  console.log("       split-file -m output.bin part1 part2 ...");
  console.log("");
  console.log(" -s <input> <num_parts>");
  console.log("    Split the input file in the number of parts given.");
  console.log("");
  console.log(" -m <output> <part> <part> ...");
  console.log("    Merge the given parts into the output file.");
  console.log("");
  console.log("");
  console.log("NPM Module 'split-file' by Tom Valk.");
  console.log("Visit https://github.com/tomvlk/node-split-file for info and help.");
}
<commit_msg>[TASK] Refactor CLI methods.<commit_after>#!/usr/bin/env node

var split = require('./split-file.js');

var Cli = function () {};

/**
 * Parse cli option.
 */
Cli.prototype.parse = function (option) {
  this.option = option;

  switch (option) {
    case '-m':
      this.method = this.merge;
      break;
    case '-s':
      this.method = this.split;
      break;
    default:
      this.method = this.help;
  }

  return this;
}

/**
 * Print the legend.
 */
Cli.prototype.help = function () {
  console.log("Usage: split-file -s input.bin 5");
  console.log("       split-file -m output.bin part1 part2 ...");
  console.log("");
  console.log(" -s <input> <num_parts>");
  console.log("    Split the input file in the number of parts given.");
  console.log("");
  console.log(" -m <output> <part> <part> ...");
  console.log("    Merge the given parts into the output file.");
  console.log("");
  console.log("");
  console.log("NPM Module 'split-file' by Tom Valk.");
  console.log("Visit https://github.com/tomvlk/node-split-file for info and help.");
}

/**
 * Split command.
 */
Cli.prototype.split = function () {
  var file = process.argv[3];
  var parts = parseInt(process.argv[4]);

  if (isNaN(parts)) {
    return this.help();
  }

  split.splitFile(file, parts).then(function (names) {
    console.log('Successfully splitted into: ' + names);
  }).catch(function (err) {
    console.log('An error occured:');
    console.log(err);
  });
}

/**
 * Merge command.
 */
Cli.prototype.merge = function () {
  var files = [];
  var output_file = process.argv[3];

  for (var i = 4; i < process.argv.length; i++) {
    files.push(process.argv[i]);
  }

  split.mergeFiles(files, output_file).then(function(names) {
    console.log('Succesfully merged the parts into ' + output_file);
  }).catch(function (err) {
    console.log('An error occured:');
    console.log(err);
  });
}

Cli.prototype.run = function () {
  return this.method();
}

if (require.main === module) {
  var cli = new Cli();
  cli
    .parse(process.argv[2])
    .run();
}
<|endoftext|>