<commit_before>module.exports = function() {
  var currentTickStep = 0;
  var orbitNodes;
  var orbitSize = [1,1];
  var nestedNodes;
  var flattenedNodes = [];
  var tickRadianStep = 0.004363323129985824;
    var orbitDispatch = d3.dispatch('tick');
    var tickInterval;
    var orbitalRings = [];
    var orbitDepthAdjust = function() {return 2.95};
    var childrenAccessor = function(d) {return d.children};
    var tickRadianFunction = function() {return 1};
    var fixedOrbitArray = [99];
    var orbitMode = "flat";

  function _orbitLayout() {

    return _orbitLayout;
  }

  _orbitLayout.mode = function(_mode) {
    //Atomic, Solar, other?
    if (!arguments.length) return orbitMode;

    if (_mode == "solar") {
      fixedOrbitArray = [1]
    }
    if (_mode == "atomic") {
      fixedOrbitArray = [2,8]
    }
    if (_mode == "flat") {
      fixedOrbitArray = [99]
    }
    orbitMode = _mode;
    if (Array.isArray(_mode)) {
      fixedOrbitArray = _mode;
      orbitMode = "custom";
    }
    return this
  }

  _orbitLayout.start = function() {
    //activate animation here
    tickInterval = setInterval(
      function() {
      currentTickStep++;
      flattenedNodes.forEach(function(_node){
        if (_node.parent) {
          _node.x = _node.parent.x + ( (_node.ring) * Math.sin( _node.angle + (currentTickStep * tickRadianStep * tickRadianFunction(_node))) );
          _node.y = _node.parent.y + ( (_node.ring) * Math.cos( _node.angle + (currentTickStep * tickRadianStep * tickRadianFunction(_node))) );
        }
      })
      orbitalRings.forEach(function(_ring) {
        _ring.x = _ring.source.x;
        _ring.y = _ring.source.y;
      })
      orbitDispatch.call("tick");
    },
    10);
  }

  _orbitLayout.stop = function() {
    //deactivate animation here
    clearInterval(tickInterval);
  }

  _orbitLayout.speed = function(_degrees) {
    if (!arguments.length) return tickRadianStep / (Math.PI / 360);
    tickRadianStep = tickRadianStep = _degrees * (Math.PI / 360);
    return this;
  }

  _orbitLayout.size = function(_value) {
    if (!arguments.length) return orbitSize;
    orbitSize = _value;
    return this;
    //change size here
  }

  _orbitLayout.revolution = function(_function) {
    //change ring size reduction (make that into dynamic function)
    if (!arguments.length) return tickRadianFunction;
    tickRadianFunction = _function;
    return this
  }

  _orbitLayout.orbitSize = function(_function) {
    //change ring size reduction (make that into dynamic function)
    if (!arguments.length) return orbitDepthAdjust;
    orbitDepthAdjust = _function;
    return this
  }

  _orbitLayout.orbitalRings = function() {
    //return an array of data corresponding to orbital rings
    if (!arguments.length) return orbitalRings;
    return this;
  }

  _orbitLayout.nodes = function(_data) {
      if (!arguments.length) return flattenedNodes;
      nestedNodes = _data;
      calculateNodes();
    return this;
  }

  _orbitLayout.children = function(_function) {
      if (!arguments.length) return childrenAccessor;

      //Probably should use d3.functor to turn a string into an object key
      childrenAccessor = _function;
      return this;

  }

  _orbitLayout.on = function() {
    var value = orbitDispatch.on.apply(orbitDispatch, arguments);
    return value === orbitDispatch ? _orbitLayout : value;
  };

  return _orbitLayout;
  function calculateNodes() {
      orbitalRings = [];
      orbitNodes = nestedNodes;

      orbitNodes.x = orbitSize[0] / 2;
      orbitNodes.y = orbitSize[1] / 2;
      orbitNodes.ring = orbitSize[0] / 2;
      orbitNodes.depth = 0;

      flattenedNodes = [];
      flattenedNodes.push(orbitNodes);

      traverseNestedData(orbitNodes);

    function traverseNestedData(_node) {

      if(childrenAccessor(_node)) {
        var y = 0;
        var totalChildren = childrenAccessor(_node).length;
        var _rings = 0;
        var _total_positions = 0;
        var _p = 0;
        while (_total_positions < totalChildren) {
          if (fixedOrbitArray[_p]) {
            _total_positions += fixedOrbitArray[_p];
          }
          else {
            _total_positions += fixedOrbitArray[fixedOrbitArray.length - 1];
          }
          _p++;
          _rings++;
        }

        while (y < totalChildren) {
          var _pos = 0;
          var _currentRing = 0;
          var _p = 0;
          var _total_positions = 0;

        while (_total_positions <= y) {
          if (fixedOrbitArray[_p]) {
            _total_positions += fixedOrbitArray[_p];
          }
          else {
            _total_positions += fixedOrbitArray[fixedOrbitArray.length-1];
          }

            _p++;
            _currentRing++;
        }

        var ringSize = fixedOrbitArray[fixedOrbitArray.length-1];

        if (fixedOrbitArray[_currentRing-1]) {
          ringSize = fixedOrbitArray[_currentRing-1];
        }

          if (_node.parent) {
            var _ring = {source: _node, x: _node.x, y: _node.y, r: _node.parent.ring / orbitDepthAdjust(_node) * (_currentRing / _rings)};
          }
          else {
            var _ring = {source: _node, x: _node.x, y: _node.y, r: (orbitSize[0] / 2) * (_currentRing / _rings)};
          }

          var thisPie = d3.pie().value(function(d) {return childrenAccessor(d) ? 4 : 1});
          var piedValues = thisPie(childrenAccessor(_node).filter(function(d,i) {return i >= y && i <= y+ringSize-1}));

          for (var x = y; x<y+ringSize && x<totalChildren;x++) {
            childrenAccessor(_node)[x].angle = ((piedValues[x - y].endAngle - piedValues[x - y].startAngle) / 2) + piedValues[x - y].startAngle;

            childrenAccessor(_node)[x].parent = _node;
            childrenAccessor(_node)[x].depth = _node.depth + 1;

            childrenAccessor(_node)[x].x = childrenAccessor(_node)[x].parent.x + ( (childrenAccessor(_node)[x].parent.ring / 2) * Math.sin( childrenAccessor(_node)[x].angle ) );
            childrenAccessor(_node)[x].y = childrenAccessor(_node)[x].parent.y + ( (childrenAccessor(_node)[x].parent.ring / 2) * Math.cos( childrenAccessor(_node)[x].angle ) );

            childrenAccessor(_node)[x].ring = _ring.r;

            flattenedNodes.push(childrenAccessor(_node)[x]);
            traverseNestedData(childrenAccessor(_node)[x]);
          }
          orbitalRings.push(_ring);
          y+=ringSize;
        }

      }
    }

  }

}
<commit_msg>define d3 to use as module<commit_after>var d3 = require('d3');

module.exports = function() {
  var currentTickStep = 0;
  var orbitNodes;
  var orbitSize = [1,1];
  var nestedNodes;
  var flattenedNodes = [];
  var tickRadianStep = 0.004363323129985824;
    var orbitDispatch = d3.dispatch('tick');
    var tickInterval;
    var orbitalRings = [];
    var orbitDepthAdjust = function() {return 2.95};
    var childrenAccessor = function(d) {return d.children};
    var tickRadianFunction = function() {return 1};
    var fixedOrbitArray = [99];
    var orbitMode = "flat";

  function _orbitLayout() {

    return _orbitLayout;
  }

  _orbitLayout.mode = function(_mode) {
    //Atomic, Solar, other?
    if (!arguments.length) return orbitMode;

    if (_mode == "solar") {
      fixedOrbitArray = [1]
    }
    if (_mode == "atomic") {
      fixedOrbitArray = [2,8]
    }
    if (_mode == "flat") {
      fixedOrbitArray = [99]
    }
    orbitMode = _mode;
    if (Array.isArray(_mode)) {
      fixedOrbitArray = _mode;
      orbitMode = "custom";
    }
    return this
  }

  _orbitLayout.start = function() {
    //activate animation here
    tickInterval = setInterval(
      function() {
      currentTickStep++;
      flattenedNodes.forEach(function(_node){
        if (_node.parent) {
          _node.x = _node.parent.x + ( (_node.ring) * Math.sin( _node.angle + (currentTickStep * tickRadianStep * tickRadianFunction(_node))) );
          _node.y = _node.parent.y + ( (_node.ring) * Math.cos( _node.angle + (currentTickStep * tickRadianStep * tickRadianFunction(_node))) );
        }
      })
      orbitalRings.forEach(function(_ring) {
        _ring.x = _ring.source.x;
        _ring.y = _ring.source.y;
      })
      orbitDispatch.call("tick");
    },
    10);
  }

  _orbitLayout.stop = function() {
    //deactivate animation here
    clearInterval(tickInterval);
  }

  _orbitLayout.speed = function(_degrees) {
    if (!arguments.length) return tickRadianStep / (Math.PI / 360);
    tickRadianStep = tickRadianStep = _degrees * (Math.PI / 360);
    return this;
  }

  _orbitLayout.size = function(_value) {
    if (!arguments.length) return orbitSize;
    orbitSize = _value;
    return this;
    //change size here
  }

  _orbitLayout.revolution = function(_function) {
    //change ring size reduction (make that into dynamic function)
    if (!arguments.length) return tickRadianFunction;
    tickRadianFunction = _function;
    return this
  }

  _orbitLayout.orbitSize = function(_function) {
    //change ring size reduction (make that into dynamic function)
    if (!arguments.length) return orbitDepthAdjust;
    orbitDepthAdjust = _function;
    return this
  }

  _orbitLayout.orbitalRings = function() {
    //return an array of data corresponding to orbital rings
    if (!arguments.length) return orbitalRings;
    return this;
  }

  _orbitLayout.nodes = function(_data) {
      if (!arguments.length) return flattenedNodes;
      nestedNodes = _data;
      calculateNodes();
    return this;
  }

  _orbitLayout.children = function(_function) {
      if (!arguments.length) return childrenAccessor;

      //Probably should use d3.functor to turn a string into an object key
      childrenAccessor = _function;
      return this;

  }

  _orbitLayout.on = function() {
    var value = orbitDispatch.on.apply(orbitDispatch, arguments);
    return value === orbitDispatch ? _orbitLayout : value;
  };

  return _orbitLayout;
  function calculateNodes() {
      orbitalRings = [];
      orbitNodes = nestedNodes;

      orbitNodes.x = orbitSize[0] / 2;
      orbitNodes.y = orbitSize[1] / 2;
      orbitNodes.ring = orbitSize[0] / 2;
      orbitNodes.depth = 0;

      flattenedNodes = [];
      flattenedNodes.push(orbitNodes);

      traverseNestedData(orbitNodes);

    function traverseNestedData(_node) {

      if(childrenAccessor(_node)) {
        var y = 0;
        var totalChildren = childrenAccessor(_node).length;
        var _rings = 0;
        var _total_positions = 0;
        var _p = 0;
        while (_total_positions < totalChildren) {
          if (fixedOrbitArray[_p]) {
            _total_positions += fixedOrbitArray[_p];
          }
          else {
            _total_positions += fixedOrbitArray[fixedOrbitArray.length - 1];
          }
          _p++;
          _rings++;
        }

        while (y < totalChildren) {
          var _pos = 0;
          var _currentRing = 0;
          var _p = 0;
          var _total_positions = 0;

        while (_total_positions <= y) {
          if (fixedOrbitArray[_p]) {
            _total_positions += fixedOrbitArray[_p];
          }
          else {
            _total_positions += fixedOrbitArray[fixedOrbitArray.length-1];
          }

            _p++;
            _currentRing++;
        }

        var ringSize = fixedOrbitArray[fixedOrbitArray.length-1];

        if (fixedOrbitArray[_currentRing-1]) {
          ringSize = fixedOrbitArray[_currentRing-1];
        }

          if (_node.parent) {
            var _ring = {source: _node, x: _node.x, y: _node.y, r: _node.parent.ring / orbitDepthAdjust(_node) * (_currentRing / _rings)};
          }
          else {
            var _ring = {source: _node, x: _node.x, y: _node.y, r: (orbitSize[0] / 2) * (_currentRing / _rings)};
          }

          var thisPie = d3.pie().value(function(d) {return childrenAccessor(d) ? 4 : 1});
          var piedValues = thisPie(childrenAccessor(_node).filter(function(d,i) {return i >= y && i <= y+ringSize-1}));

          for (var x = y; x<y+ringSize && x<totalChildren;x++) {
            childrenAccessor(_node)[x].angle = ((piedValues[x - y].endAngle - piedValues[x - y].startAngle) / 2) + piedValues[x - y].startAngle;

            childrenAccessor(_node)[x].parent = _node;
            childrenAccessor(_node)[x].depth = _node.depth + 1;

            childrenAccessor(_node)[x].x = childrenAccessor(_node)[x].parent.x + ( (childrenAccessor(_node)[x].parent.ring / 2) * Math.sin( childrenAccessor(_node)[x].angle ) );
            childrenAccessor(_node)[x].y = childrenAccessor(_node)[x].parent.y + ( (childrenAccessor(_node)[x].parent.ring / 2) * Math.cos( childrenAccessor(_node)[x].angle ) );

            childrenAccessor(_node)[x].ring = _ring.r;

            flattenedNodes.push(childrenAccessor(_node)[x]);
            traverseNestedData(childrenAccessor(_node)[x]);
          }
          orbitalRings.push(_ring);
          y+=ringSize;
        }

      }
    }

  }

}
<|endoftext|>


<commit_before>import {LightningElement, api, track} from 'lwc';
import getDataImportModel
    from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.getDataImportModel';
import getDataImportRows
    from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.getDataImportRows';
import GeFormService from 'c/geFormService';
import STATUS_FIELD from '@salesforce/schema/DataImport__c.Status__c';
import FAILURE_INFORMATION_FIELD
    from '@salesforce/schema/DataImport__c.FailureInformation__c';
import DONATION_AMOUNT from '@salesforce/schema/DataImport__c.Donation_Amount__c';
import {deleteRecord} from 'lightning/uiRecordApi';
import {handleError} from 'c/utilTemplateBuilder';
import runBatchDryRun from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.runBatchDryRun';
import geDonorColumnLabel from '@salesforce/label/c.geDonorColumnLabel';
import geDonationColumnLabel from '@salesforce/label/c.geDonationColumnLabel';
import bgeActionDelete from '@salesforce/label/c.bgeActionDelete';
import geBatchGiftsCount from '@salesforce/label/c.geBatchGiftsCount';
import geBatchGiftsTotal from '@salesforce/label/c.geBatchGiftsTotal';
import commonOpen from '@salesforce/label/c.commonOpen';
import { isNotEmpty } from 'c/utilCommon';

export default class GeBatchGiftEntryTable extends LightningElement {
    @api batchId;
    @track ready = false;

    _batchLoaded = false;
    @track data = [];
    @track hasData;

    _columnsLoaded = false;
    @track columns = [];
    _columns = [
        {label: 'Status', fieldName: STATUS_FIELD.fieldApiName, type: 'text'},
        {label: 'Errors', fieldName: FAILURE_INFORMATION_FIELD.fieldApiName, type: 'text'},
        {
            label: geDonorColumnLabel, fieldName: 'donorLink', type: 'url',
            typeAttributes: {label: {fieldName: 'donorName'}}
        },
        {
            label: geDonationColumnLabel, fieldName: 'matchedRecordUrl', type: 'url',
            typeAttributes: {label: {fieldName: 'matchedRecordLabel'}}
        }
    ];
    _actionsColumn = {
        type: 'action',
        typeAttributes: {
            rowActions: [
                {label: commonOpen, name: 'open'},
                {label: bgeActionDelete, name: 'delete'}
            ],
            menuAlignment: 'auto'
        }
    };

    @api title;
    @api total;
    @api expectedTotal;
    @api count;
    @api expectedCount;
    @track isLoaded = true;

    connectedCallback() {
        if (this.batchId) {
            this.loadBatch();
        }
    }

    setReady() {
        this.ready = this._columnsLoaded && this._batchLoaded;
    }

    loadBatch() {
        getDataImportModel({batchId: this.batchId})
            .then(
                response => {
                    const dataImportModel = JSON.parse(response);
                    this._count = dataImportModel.totalCountOfRows;
                    this._total = dataImportModel.totalRowAmount;
                    dataImportModel.dataImportRows.forEach(row => {
                            this.data.push(
                                Object.assign(row, row.record));
                        }
                    );
                    this.data = [...this.data];
                    this.hasData = this.data.length > 0 ? true : false;
                    this.batchLoaded();
                }
            )
            .catch(
                error => {
                    handleError(error);
                }
            );
    }

    batchLoaded() {
        this._batchLoaded = true;
        this.setReady();
    }

    @api
    handleSectionsRetrieved(sections) {
        this.initColumns(this.buildColumns(sections));
    }

    initColumns(userDefinedColumns) {
        this.columns = [
            ...this._columns,
            ...userDefinedColumns,
            this._actionsColumn];
        this.columnsLoaded();
    }

    buildColumns(sections) {
        const columns = [];
        sections.forEach(
            section => {
                section.elements
                    .filter(e => e.elementType === 'field')
                    .forEach(
                    element => {
                        const fieldWrapper = GeFormService.getFieldMappingWrapper(element.dataImportFieldMappingDevNames[0]);
                        if (isNotEmpty(fieldWrapper)) {
                            const column = {
                                label: element.customLabel,
                                fieldName: fieldWrapper.Source_Field_API_Name,
                                type: GeFormService.getInputTypeFromDataType(
                                    element.dataType
                                ) === 'date' ? 'date-local' :
                                    GeFormService.getInputTypeFromDataType(element.dataType)
                            };
                            columns.push(column);
                        }
                    }
                );
            }
        );
        return columns;
    }

    columnsLoaded() {
        this._columnsLoaded = true;
        this.setReady();
    }

    @api
    upsertData(dataRow, idProperty) {
        const existingRowIndex = this.data.findIndex(row =>
            row[idProperty] === dataRow[idProperty]
        );

        if (existingRowIndex !== -1) {
            this.data.splice(existingRowIndex, 1, dataRow);
            this.data = [...this.data];
        } else {
            this.data = [dataRow, ...this.data];
            if (this.hasData == false) {
                this.hasData = true;
            }
        }
    }

    handleRowActions(event) {
        switch (event.detail.action.name) {
            case 'open':
                this.loadRow(event.detail.row);
                break;
            case 'delete':
                deleteRecord(event.detail.row.Id).then(() => {
                    this.deleteDIRow(event.detail.row);
                }).catch(error => {
                        handleError(error);
                    }
                );
                break;
        }
    }

    deleteDIRow(rowToDelete) {
        const isRowToDelete = row => row.Id == rowToDelete.Id;
        const index = this.data.findIndex(isRowToDelete);
        this.data.splice(index, 1);
        this.data = [...this.data];
        this.dispatchEvent(new CustomEvent('delete', {
            detail: {
                amount: rowToDelete[DONATION_AMOUNT.fieldApiName]
            }
        }));
    }

    loadMoreData(event) {
        event.target.isLoading = true;
        const disableInfiniteLoading = function () {
            this.enableInfiniteLoading = false;
        }.bind(event.target);

        const disableIsLoading = function () {
            this.isLoading = false;
        }.bind(event.target);

        getDataImportRows({batchId: this.batchId, offset: this.data.length})
            .then(rows => {
                rows.forEach(row => {
                        this.data.push(
                            Object.assign(row, row.record)
                        );
                    }
                );
                this.data = [...this.data];
                if (this.data.length >= this.count) {
                    disableInfiniteLoading();
                }
                disableIsLoading();
            })
            .catch(error => {
                handleError(error);
            });
    }

    @api
    runBatchDryRun(callback) {
        runBatchDryRun({
            batchId: this.batchId,
            numberOfRowsToReturn: this.data.length
        })
            .then(result => {
                const dataImportModel = JSON.parse(result);
                this._count = dataImportModel.totalCountOfRows;
                this._total = dataImportModel.totalRowAmount;
                dataImportModel.dataImportRows.forEach((row, idx) => {
                    this.upsertData(
                        Object.assign(row, row.record), 'Id');
                });
            })
            .catch(error => {
                handleError(error);
            })
            .finally(() => {
                callback();
            });
    }

    get geBatchGiftsCountLabel() {
        return geBatchGiftsCount;
    }

    get geBatchGiftsTotalLabel() {
        return geBatchGiftsTotal;
    }

    loadRow(row) {
        this.dispatchEvent(new CustomEvent('loaddata', {
            detail: row
        }));
    }

    /**
     * @description Internal setters used to communicate the current count and total
     *              up to the App, which needs them to keep track of whether the batch's
     *              expected totals match.
     */
    set _count(count) {
        this.dispatchEvent(new CustomEvent('countchanged', {
            detail: {
                value: count
            }
        }));
    }

    set _total(total) {
        this.dispatchEvent(new CustomEvent('totalchanged', {
            detail: {
                value: total
            }
        }));
    }

}<commit_msg>added logic for converting lookup ids to names on the client while keeping id values for BDI<commit_after>import {LightningElement, api, track} from 'lwc';
import {deleteRecord} from 'lightning/uiRecordApi';

import getDataImportModel from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.getDataImportModel';
import runBatchDryRun from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.runBatchDryRun';
import getDataImportRows from '@salesforce/apex/BGE_DataImportBatchEntry_CTRL.getDataImportRows';

import {handleError} from 'c/utilTemplateBuilder';
import {isNotEmpty, isEmpty} from 'c/utilCommon';
import GeListView from 'c/geListView';
import GeFormService from 'c/geFormService';

import geDonorColumnLabel from '@salesforce/label/c.geDonorColumnLabel';
import geDonationColumnLabel from '@salesforce/label/c.geDonationColumnLabel';
import bgeActionDelete from '@salesforce/label/c.bgeActionDelete';
import geBatchGiftsCount from '@salesforce/label/c.geBatchGiftsCount';
import geBatchGiftsTotal from '@salesforce/label/c.geBatchGiftsTotal';

import commonOpen from '@salesforce/label/c.commonOpen';

import DATAIMPORT_INFO from '@salesforce/schema/DataImport__c';
import STATUS_FIELD from '@salesforce/schema/DataImport__c.Status__c';
import FAILURE_INFORMATION_FIELD from '@salesforce/schema/DataImport__c.FailureInformation__c';
import DONATION_AMOUNT from '@salesforce/schema/DataImport__c.Donation_Amount__c';

export default class GeBatchGiftEntryTable extends GeListView {
    @api batchId;
    @track ready = false;

    _batchLoaded = false;
    @track data = [];
    @track hasData;

    _columnsLoaded = false;
    @track columns = [];
    _columns = [
        {label: 'Status', fieldName: STATUS_FIELD.fieldApiName, type: 'text'},
        {label: 'Errors', fieldName: FAILURE_INFORMATION_FIELD.fieldApiName, type: 'text'},
        {
            label: geDonorColumnLabel, fieldName: 'donorLink', type: 'url',
            typeAttributes: {label: {fieldName: 'donorName'}}
        },
        {
            label: geDonationColumnLabel, fieldName: 'matchedRecordUrl', type: 'url',
            typeAttributes: {label: {fieldName: 'matchedRecordLabel'}}
        }
    ];
    _actionsColumn = {
        type: 'action',
        typeAttributes: {
            rowActions: [
                {label: commonOpen, name: 'open'},
                {label: bgeActionDelete, name: 'delete'}
            ],
            menuAlignment: 'auto'
        }
    };

    @api title;
    @api total;
    @api expectedTotal;
    @api count;
    @api expectedCount;
    @track isLoaded = true;

    fieldMappings;

    constructor() {
        super(DATAIMPORT_INFO.objectApiName);
    }

    connectedCallback() {
        GeFormService.getFormTemplate()
            .then( response => {
                    this.fieldMappings = response.fieldMappingSetWrapper.fieldMappingByDevName;

                    if (this.batchId) {
                        this.loadBatch();
                    }
                }
            )
    }

    setReady() {
        this.ready = this._columnsLoaded && this._batchLoaded;
    }

    loadBatch() {
        getDataImportModel({batchId: this.batchId})
            .then(
                response => {
                    const dataImportModel = JSON.parse(response);
                    this._count = dataImportModel.totalCountOfRows;
                    this._total = dataImportModel.totalRowAmount;
                    dataImportModel.dataImportRows.forEach(row => {
                        let rowRecord = this.convertLookIdsToNames(row.record);
                            this.data.push(
                                Object.assign(row, rowRecord));
                        }
                    );
                    this.data = [...this.data];
                    this.hasData = this.data.length > 0;
                    this.batchLoaded();
                }
            )
            .catch(
                error => {
                    handleError(error);
                }
            );
    }

    batchLoaded() {
        this._batchLoaded = true;
        this.setReady();
    }

    @api
    handleSectionsRetrieved(sections) {
        let columns = this.buildColumns((sections));
        this.initColumns(columns);
    }

    initColumns(userDefinedColumns) {
        this.columns = [
            ...this._columns,
            ...userDefinedColumns,
            this._actionsColumn];
        this.columnsLoaded();
    }

    buildColumns(sections) {
        const fieldApiNames = [];
        sections.forEach(section => {
            section.elements
                .filter(element => element.elementType === 'field')
                .forEach(element => {
                    const fieldWrapper = GeFormService.getFieldMappingWrapper(
                        element.dataImportFieldMappingDevNames[0]
                    );
                    if (isNotEmpty(fieldWrapper)) {
                        fieldApiNames.push(fieldWrapper.Source_Field_API_Name);
                    }
                });
        });

        return this.buildNameFieldColumns(fieldApiNames);
    }

    columnsLoaded() {
        this._columnsLoaded = true;
        this.setReady();
    }

    @api
    upsertData(dataRow, idProperty) {
        const existingRowIndex = this.data.findIndex(row =>
            row[idProperty] === dataRow[idProperty]
        );

        dataRow = this.convertLookIdsToNames(dataRow);

        if (existingRowIndex !== -1) {
            this.data.splice(existingRowIndex, 1, dataRow);
            this.data = [...this.data];
        } else {
            this.data = [dataRow, ...this.data];
            if (this.hasData === false) {
                this.hasData = true;
            }
        }
    }

    convertLookIdsToNames(dataRow) {
        Object.keys(dataRow).forEach(field => {
            if (this.fieldMappings.hasOwnProperty(field)) {
                let fieldInfo = this.objectInfo.fields[field];
                let referenceField = this.handleReferenceTypeFields(fieldInfo).split('.')[0];

                if (isNotEmpty(referenceField)) {
                    dataRow[referenceField] = dataRow[referenceField].Name;
                }
            }
        });
        return dataRow;
    }

    handleRowActions(event) {
        switch (event.detail.action.name) {
            case 'open':
                this.loadRow(event.detail.row);
                break;
            case 'delete':
                deleteRecord(event.detail.row.Id).then(() => {
                    this.deleteDIRow(event.detail.row);
                }).catch(error => {
                        handleError(error);
                    }
                );
                break;
        }
    }

    deleteDIRow(rowToDelete) {
        const isRowToDelete = row => row.Id == rowToDelete.Id;
        const index = this.data.findIndex(isRowToDelete);
        this.data.splice(index, 1);
        this.data = [...this.data];
        this.dispatchEvent(new CustomEvent('delete', {
            detail: {
                amount: rowToDelete[DONATION_AMOUNT.fieldApiName]
            }
        }));
    }

    loadMoreData(event) {
        event.target.isLoading = true;
        const disableInfiniteLoading = function () {
            this.enableInfiniteLoading = false;
        }.bind(event.target);

        const disableIsLoading = function () {
            this.isLoading = false;
        }.bind(event.target);

        getDataImportRows({batchId: this.batchId, offset: this.data.length})
            .then(rows => {
                rows.forEach(row => {
                        this.data.push(
                            Object.assign(row, row.record)
                        );
                    }
                );
                this.data = [...this.data];
                if (this.data.length >= this.count) {
                    disableInfiniteLoading();
                }
                disableIsLoading();
            })
            .catch(error => {
                handleError(error);
            });
    }

    @api
    runBatchDryRun(callback) {
        runBatchDryRun({
            batchId: this.batchId,
            numberOfRowsToReturn: this.data.length
        })
            .then(result => {
                const dataImportModel = JSON.parse(result);
                this._count = dataImportModel.totalCountOfRows;
                this._total = dataImportModel.totalRowAmount;
                dataImportModel.dataImportRows.forEach((row, idx) => {
                    this.upsertData(
                        Object.assign(row, row.record), 'Id');
                });
            })
            .catch(error => {
                handleError(error);
            })
            .finally(() => {
                callback();
            });
    }

    get geBatchGiftsCountLabel() {
        return geBatchGiftsCount;
    }

    get geBatchGiftsTotalLabel() {
        return geBatchGiftsTotal;
    }

    loadRow(row) {
        this.dispatchEvent(new CustomEvent('loaddata', {
            detail: row
        }));
    }

    /**
     * @description Internal setters used to communicate the current count and total
     *              up to the App, which needs them to keep track of whether the batch's
     *              expected totals match.
     */
    set _count(count) {
        this.dispatchEvent(new CustomEvent('countchanged', {
            detail: {
                value: count
            }
        }));
    }

    set _total(total) {
        this.dispatchEvent(new CustomEvent('totalchanged', {
            detail: {
                value: total
            }
        }));
    }

}<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const EventEmitter = require('events');
const async = require('async');
const _ = require('lodash');
const isUndefined = _.isUndefined;
const arrivals = require('arrivals');
const debug = require('debug')('phases');
const Nanotimer = require('nanotimer');

module.exports = phaser;

function phaser(phaseSpecs) {
  let ee = new EventEmitter();

  let tasks = _.map(phaseSpecs, function(spec, i) {
    if (isUndefined(spec.index)) {
      spec.index = i;
    }

    if (!isUndefined(spec.arrivalRate) && isUndefined(spec.rampTo)) {
      spec.mode = spec.mode || 'uniform';
    }

    if (!isUndefined(spec.pause)) {
      return createPause(spec, ee);
    }

    if (!isUndefined(spec.arrivalCount)) {
      return createArrivalCount(spec, ee);
    }

    if (!isUndefined(spec.arrivalRate)) {

      // If arrivalRate is zero, it's the same as a pause:
      if (spec.arrivalRate === 0) {
        return createPause(
          Object.assign(
            spec, { pause: spec.duration }),
          ee);
      }

      // If it's a ramp, create that:
      if (!isUndefined(spec.rampTo)) {
        return createRamp(spec, ee);
      }

      // Otherwise it's a plain arrival phase:
      return createArrivalRate(spec, ee);
    }

    console.log('Unknown phase spec\n%j\nThis should not happen', spec);
  });

  ee.run = function() {
    async.series(tasks, function(err) {
      if (err) {
        debug(err);
      }

      ee.emit('done');
    });
  };

  return ee;
}

function createPause(spec, ee) {
  const duration = spec.pause * 1000;
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    setTimeout(function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    }, duration);
  };
  return task;
}

function createRamp(spec, ee) {
  // We will increase the arrival rate by 1 every tick seconds.
  // The divisor is the number of distinct arrival rates there will be (6 for
  // arrivalRate=5 and rampTo=10)

  const tick = spec.duration / (spec.rampTo - spec.arrivalRate + 1); // not precise
  debug('tick = %s', tick);
  const timer1 = new Nanotimer();
  const timer2 = new Nanotimer();

  return function task(callback) {
    ee.emit('phaseStarted', spec);
    let currentRate = spec.arrivalRate;

    timer1.setInterval(function createArrivalsAtCurrentRate() {
      timer2.clearInterval();

      const interArrivalInterval = (1000/currentRate) + 'm';
      debug('currentRate = %s', currentRate);
      debug('interArrivalInterval = %s', interArrivalInterval);

      timer2.setInterval(function generateArrival() {
        ee.emit('arrival');
        debug('arrival');
      }, '', interArrivalInterval);

      if (currentRate <= spec.rampTo) {
        currentRate++;
      } else {
        timer1.clearInterval();
        timer1.setTimeout(function() {
          timer1.clearTimeout();
          timer2.clearInterval();
          ee.emit('phaseCompleted', spec);
          return callback(null);
        }, '', '1000m');
      }
    }, '', Math.floor(tick * 1e9) + 'n');
  };
}

function createArrivalCount(spec, ee) {
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    const duration = spec.duration * 1000;
    const interval = duration / spec.arrivalCount;
    const p = arrivals.uniform.process(interval, duration);
    p.on('arrival', function() {
      ee.emit('arrival');
    });
    p.on('finished', function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    });
    p.start();
  };

  return task;
}

function createArrivalRate(spec, ee) {
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    const ar = 1000 / spec.arrivalRate;
    const duration = spec.duration * 1000;
    debug('creating a %s process for arrivalRate', spec.mode);
    const p = arrivals[spec.mode].process(ar, duration);
    p.on('arrival', function() {
      ee.emit('arrival');
    });
    p.on('finished', function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    });
    p.start();
  };

  return task;
}
<commit_msg>Fix linter error<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

'use strict';

const EventEmitter = require('events');
const async = require('async');
const _ = require('lodash');
const isUndefined = _.isUndefined;
const arrivals = require('arrivals');
const debug = require('debug')('phases');
const Nanotimer = require('nanotimer');

module.exports = phaser;

function phaser(phaseSpecs) {
  let ee = new EventEmitter();

  let tasks = _.map(phaseSpecs, function(spec, i) {
    if (isUndefined(spec.index)) {
      spec.index = i;
    }

    if (!isUndefined(spec.arrivalRate) && isUndefined(spec.rampTo)) {
      spec.mode = spec.mode || 'uniform';
    }

    if (!isUndefined(spec.pause)) {
      return createPause(spec, ee);
    }

    if (!isUndefined(spec.arrivalCount)) {
      return createArrivalCount(spec, ee);
    }

    if (!isUndefined(spec.arrivalRate)) {

      // If arrivalRate is zero, it's the same as a pause:
      if (spec.arrivalRate === 0) {
        return createPause(
          Object.assign(
            spec, { pause: spec.duration }),
          ee);
      }

      // If it's a ramp, create that:
      if (!isUndefined(spec.rampTo)) {
        return createRamp(spec, ee);
      }

      // Otherwise it's a plain arrival phase:
      return createArrivalRate(spec, ee);
    }

    console.log('Unknown phase spec\n%j\nThis should not happen', spec);
  });

  ee.run = function() {
    async.series(tasks, function(err) {
      if (err) {
        debug(err);
      }

      ee.emit('done');
    });
  };

  return ee;
}

function createPause(spec, ee) {
  const duration = spec.pause * 1000;
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    setTimeout(function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    }, duration);
  };
  return task;
}

function createRamp(spec, ee) {
  // We will increase the arrival rate by 1 every tick seconds.
  // The divisor is the number of distinct arrival rates there will be (6 for
  // arrivalRate=5 and rampTo=10)

  const tick = spec.duration / (spec.rampTo - spec.arrivalRate + 1); // not precise
  debug('tick = %s', tick);
  const timer1 = new Nanotimer();
  const timer2 = new Nanotimer();

  return function task(callback) {
    ee.emit('phaseStarted', spec);
    let currentRate = spec.arrivalRate;

    timer1.setInterval(function createArrivalsAtCurrentRate() {
      timer2.clearInterval();

      const interArrivalInterval = (1000 / currentRate) + 'm';
      debug('currentRate = %s', currentRate);
      debug('interArrivalInterval = %s', interArrivalInterval);

      timer2.setInterval(function generateArrival() {
        ee.emit('arrival');
        debug('arrival');
      }, '', interArrivalInterval);

      if (currentRate <= spec.rampTo) {
        currentRate++;
      } else {
        timer1.clearInterval();
        timer1.setTimeout(function() {
          timer1.clearTimeout();
          timer2.clearInterval();
          ee.emit('phaseCompleted', spec);
          return callback(null);
        }, '', '1000m');
      }
    }, '', Math.floor(tick * 1e9) + 'n');
  };
}

function createArrivalCount(spec, ee) {
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    const duration = spec.duration * 1000;
    const interval = duration / spec.arrivalCount;
    const p = arrivals.uniform.process(interval, duration);
    p.on('arrival', function() {
      ee.emit('arrival');
    });
    p.on('finished', function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    });
    p.start();
  };

  return task;
}

function createArrivalRate(spec, ee) {
  const task = function(callback) {
    ee.emit('phaseStarted', spec);
    const ar = 1000 / spec.arrivalRate;
    const duration = spec.duration * 1000;
    debug('creating a %s process for arrivalRate', spec.mode);
    const p = arrivals[spec.mode].process(ar, duration);
    p.on('arrival', function() {
      ee.emit('arrival');
    });
    p.on('finished', function() {
      ee.emit('phaseCompleted', spec);
      return callback(null);
    });
    p.start();
  };

  return task;
}
<|endoftext|>


<commit_before>function Order (fee, tax, tipPercent) {
  var subtotal = 0;
  var costs = {};

  function setDefaults () {
    if (!fee) {
      console.warn('Fee unset; defaulting to 0');
      fee = 0;
    }

    if (!tax) {
      console.warn('Tax unset; defaulting to 0');
      tax = 0;
    }

    if (!tipPercent) {
      console.warn('Tip unset; defaulting to 0');
      tipPercent = 0;
    }
  }

  var order = {
    addItem: function (name, cost) {
      if (costs[name] == null) {
        costs[name] = 0;
      }

      costs[name] += cost;
      subtotal += cost;
    },

    set fee (x) {
      fee = x;
    },

    set tax (x) {
      tax = x;
    },

    set tipPercent (x) {
      tipPercent = x / 100;
    },

    split: function () {
      setDefaults();

      taxPercent = tax / subtotal;
      feesPerPerson = fee / Object.keys(costs).length;
      tip = tipPercent * subtotal;
      total = subtotal + tax + fee + tip;

      totals = {};
      for (var person in costs) {
        totals[person] =
            costs[person] + // cost of items
            costs[person] * taxPercent + // tax on items
            costs[person] * tipPercent + // tip on items
            feesPerPerson;
      }
    },

    get costs () {
      return costs;
    },

    get fee () {
      return fee;
    },

    get feesPerPerson () {
      return feesPerPerson;
    },

    get tax () {
      return tax;
    },

    get taxPercent () {
      return taxPercent * 100;
    },

    get tip () {
      return tip;
    },

    get tipPercent () {
      return tipPercent * 100;
    },

    get total () {
      return total;
    },

    get subtotal () {
      return subtotal;
    },

    get totals () {
      return totals;
    }
  };

  order.fee = fee;
  order.tax = tax;
  order.tipPercent = tipPercent;

  return order;
}
<commit_msg>Change Order to take tip as non-percentage with a flag to calculate one based of the other<commit_after>function Order (fee, tax, tip, isTipPercentage) {
  var subtotal = 0;
  var costs = {};

  function setDefaults () {
    if (!fee) {
      console.warn('Fee unset; defaulting to 0');
      fee = 0;
    }

    if (!tax) {
      console.warn('Tax unset; defaulting to 0');
      tax = 0;
    }

    if (!tip) {
      console.warn('Tip unset; defaulting to 0');
      tipPercent = 0;
    }
  }

  var order = {
    addItem: function (name, cost) {
      if (costs[name] == null) {
        costs[name] = 0;
      }

      costs[name] += cost;
      subtotal += cost;
    },

    set fee (x) {
      fee = x;
    },

    set tax (x) {
      tax = x;
    },

    set tip (x) {
      tip = x;
    },

    set isTipPercentage (x) {
      isTipPercentage = x;
    },

    split: function () {
      setDefaults();

      if (isTipPercentage) {
        tipPercent = tip / 100;
        tip = tipPercent * subtotal;
      } else {
        tipPercent = tip / subtotal;
      }

      taxPercent = tax / subtotal;
      feesPerPerson = fee / Object.keys(costs).length;
      total = subtotal + tax + fee + tip;

      totals = {};
      for (var person in costs) {
        totals[person] =
            costs[person] + // cost of items
            costs[person] * taxPercent + // tax on items
            costs[person] * tipPercent + // tip on items
            feesPerPerson;
      }
    },

    get costs () {
      return costs;
    },

    get fee () {
      return fee;
    },

    get feesPerPerson () {
      return feesPerPerson;
    },

    get tax () {
      return tax;
    },

    get taxPercent () {
      return taxPercent * 100;
    },

    get tip () {
      return tip;
    },

    get tipPercent () {
      return tipPercent * 100;
    },

    get isTipPercentage () {
      return isTipPercentage;
    },

    get total () {
      return total;
    },

    get subtotal () {
      return subtotal;
    },

    get totals () {
      return totals;
    }
  };

  order.fee = fee;
  order.tax = tax;
  order.tip = tip;
  order.isTipPercentage = isTipPercentage;

  return order;
}
<|endoftext|>


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

/**

  Methods are only installed on the prototype.
  If the method is overriding a method from a parent class,
  then SUPER support is added.

  Ex.

  foam.CLASS({
    name: 'Parent',
    methods: [
      // short-form
      function sayHello() { console.log('hello'); },

      // long-form
      {
        name: 'sayGoodbye',
        code: function() { console.log('goodbye'); }
      }
    ]
  });

  // Create a subclass of Parent and override the 'sayHello' method.
  // The parent classes 'sayHello' methold is called with 'this.SUPER()'
  foam.CLASS({
    name: 'Child',
    extends: 'Parent',
    methods: [
      function sayHello() { this.SUPER(); console.log('world'); }
    ]
  });

  Child.create().sayHello();
  >> hello
  >> world

*/
foam.CLASS({
  package: 'foam.core',
  name: 'AbstractMethod',
  extends: 'FObject',

  properties: [
    { name: 'name', required: true },
    { name: 'code', required: true },
    'returns',
    'args'
  ],

  methods: [
    /**
      Decorate a method so that it can call the
      method it overrides with this.SUPER().
    */
    function override_(proto, method) {
      var super_ = proto.__proto__[this.name];

      if ( ! method ) return;

      // Not using SUPER, so just return original method
      if ( method.toString().indexOf('SUPER') == -1 ) return method;

      // Not overriding, stub out super_
      if ( ! super_ ) super_ = function() {};

      console.assert(
          typeof super_ === 'function',
          'Attempt to override non-method: ',
          this.name);

      function SUPER() { return super_.apply(this, arguments); }

      var f = function() {
        var oldSuper = this.SUPER;
        this.SUPER = SUPER;

        try {
          return method.apply(this, arguments);
        } finally {
          this.SUPER = oldSuper;
        }

        return ret;
      };

      foam.Function.setName(f, this.name);
      f.toString = function() { return method.toString(); };

      return f;
    },
    function createChildMethod_(child) {
      return child;
    },
    function installInClass(cls) {
      var method = this;

      var superMethod = cls.__proto__.getAxiomByName(method.name);
      if ( superMethod && foam.core.AbstractMethod.isInstance(superMethod) ) {
        method = superMethod.createChildMethod_(method);
      }

      cls.axiomMap_[method.name] = method;
    }
  ]
});

foam.CLASS({
  package: 'foam.core',
  name: 'Method',
  extends: 'foam.core.AbstractMethod',

  methods: [
    function installInProto(proto) {
      proto[this.name] = this.override_(proto, this.code);
    },

    function exportAs(obj) {
      var m = obj[this.name];
      /** Bind the method to 'this' when exported so that it still works. **/
      return function exportedMethod() { return m.apply(obj, arguments); };
    }
  ]
});

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

/**

  Methods are only installed on the prototype.
  If the method is overriding a method from a parent class,
  then SUPER support is added.

  Ex.

  foam.CLASS({
    name: 'Parent',
    methods: [
      // short-form
      function sayHello() { console.log('hello'); },

      // long-form
      {
        name: 'sayGoodbye',
        code: function() { console.log('goodbye'); }
      }
    ]
  });

  // Create a subclass of Parent and override the 'sayHello' method.
  // The parent classes 'sayHello' methold is called with 'this.SUPER()'
  foam.CLASS({
    name: 'Child',
    extends: 'Parent',
    methods: [
      function sayHello() { this.SUPER(); console.log('world'); }
    ]
  });

  Child.create().sayHello();
  >> hello
  >> world

*/
foam.CLASS({
  package: 'foam.core',
  name: 'AbstractMethod',
  extends: 'FObject',

  properties: [
    { name: 'name', required: true },
    { name: 'code', required: true },
    'returns',
    'args'
  ],

  methods: [
    /**
      Decorate a method so that it can call the
      method it overrides with this.SUPER().
    */
    function override_(proto, method) {
      var super_ = proto.__proto__[this.name];

      if ( ! method ) return;

      // Not using SUPER, so just return original method
      if ( method.toString().indexOf('SUPER') == -1 ) return method;

      // Not overriding, stub out super_
      if ( ! super_ ) super_ = function() {};

      console.assert(
          typeof super_ === 'function',
          'Attempt to override non-method: ',
          this.name);

      function SUPER() { return super_.apply(this, arguments); }

      var f = function() {
        var oldSuper = this.SUPER;
        this.SUPER = SUPER;

        try {
          return method.apply(this, arguments);
        } finally {
          this.SUPER = oldSuper;
        }

        return ret;
      };

      foam.Function.setName(f, this.name);
      f.toString = function() { return method.toString(); };

      return f;
    },
    function createChildMethod_(child) {
      return child;
    },
    function installInClass(cls) {
      var method = this;

      var superMethod = cls.getSuperAxiomByName(method.name);
      if ( superMethod && foam.core.AbstractMethod.isInstance(superMethod) ) {
        method = superMethod.createChildMethod_(method);
      }

      cls.axiomMap_[method.name] = method;
    }
  ]
});

foam.CLASS({
  package: 'foam.core',
  name: 'Method',
  extends: 'foam.core.AbstractMethod',

  methods: [
    function installInProto(proto) {
      proto[this.name] = this.override_(proto, this.code);
    },

    function exportAs(obj) {
      var m = obj[this.name];
      /** Bind the method to 'this' when exported so that it still works. **/
      return function exportedMethod() { return m.apply(obj, arguments); };
    }
  ]
});

foam.boot.phase2();
<|endoftext|>


<commit_before>var PLR_SHADOW = -5
var PLR_FORCE = 0.8;
var PLR_RADIUS = 20

class Player {
    constructor(menu, image) {
        var shape = new planck.Circle(PLR_RADIUS / PHY_SCALE)
        var body = menu.world.createBody({
            'type': 'dynamic'
        })
        this.world = menu.world
        body.createFixture({
            'shape': shape,
            'restitution': 0.9,
            'm_radius': PLR_RADIUS / PHY_SCALE
        }).setUserData(this)
        body.setLinearDamping(0.3);
        body.setAwake(true);
        body.setActive(true);
        this.body = body;
        this.image = image;
        this.pawn = makeImage('img/pawn.png')
        this.ball = false
        this.boost_dt = 0
    }
    take_ball(ball) {
        if (ball.owned) {
            ball.owned.ball = false;
        }
        ball.body.setActive(false);
        this.ball = ball
        ball.owned = this
    }
    distance_from(x, y) {
        return Math.sqrt(Math.pow(x - this.pos.x, 2) + Math.pow(y - this.pos.y, 2))
    }
    set_position(x, y, randomicity = 0, rotation = 0) {
        let temp = new planck.Vec2(x / PHY_SCALE + (Math.random() * randomicity - randomicity / 2), -y / PHY_SCALE + (Math.random() * randomicity - randomicity / 2))
        this.body.setLinearVelocity({
            x: 0,
            y: 0
        }, 0.0);
        this.body.setTransform(temp, rotation);
    }
    destroy() {
        this.world.destroyBody(this.body)
        this.body = null
        this.image = null
        this.world = null
    }

    targets(coords, coord2, delta) {
        var x = coords[0] - this.pos.x
        var y = coords[1] - this.pos.y
        var distance = Math.sqrt(Math.pow(Math.abs(x), 2) + Math.pow(Math.abs(y), 2))
        var angle = Math.acos(x / distance)
        var myangle = (Math.PI / 2 + this.body.getAngle()) % (2 * Math.PI)
        var sync = Math.abs(angle - myangle) < (delta / 360 * (2 * Math.PI))
        return [sync, angle]
    }
    push(dt) {
        if (!!this.ball) {
            // shooting ball
            this.ball.shot(dt)
            let angle = this.body.getAngle()
            let [x, y] = [Math.sin(-angle), Math.cos(-angle)]
            let temp = new planck.Vec2(this.pos.x + x, this.pos.y + y)
            this.ball.body.setTransform(temp, angle)
            this.ball.body.setActive(true)
            temp = this.body.getLinearVelocity()
            this.ball.body.setLinearVelocity(temp)
            this.ball.body.applyLinearImpulse(this.ball.body.getWorldVector(new planck.Vec2(0, 3 * PLR_FORCE)), this.ball.pos, true)
            this.ball = false
        } else {
            if (dt < this.boost_dt + 2000) // 2s min between 2 boosts
                return
            this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, 5 * PLR_FORCE)), this.pos, true)
        }
        this.boost_dt = dt
    }
    forward(delta) {
        let force = PLR_FORCE * delta
        this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, force)), this.pos, true)
    }
    backward(delta) {
        let force = PLR_FORCE * delta
        this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, -force / 1.25)), this.pos, true)
    }
    left(delta) {
        let angle = 0.37 * delta
        this.body.setTransform(this.pos, this.body.getAngle() + angle)

    }
    right(delta) {
        let angle = 0.37 * delta
        this.body.setTransform(this.pos, this.body.getAngle() - angle)
    }
    draw(dt, delta) {
        this.pos = this.body.getPosition();
        app.display.context.save()
        let x = PHY_SCALE * (this.pos.x)
        let y = -PHY_SCALE * (this.pos.y)
        app.display.context.translate(x, y)
        app.display.blit(this.image, -PLR_RADIUS, -PLR_RADIUS)
        app.display.context.rotate(-this.body.getAngle())
        app.display.context.translate(0, -PLR_RADIUS / 2)
        if (this.ball) {
            app.display.blit(this.ball.image, -this.ball.image.width / 2, -this.ball.image.height / 2)
            let angle = this.body.getAngle()
            let [x, y] = [Math.sin(-angle), Math.cos(-angle)]
            this.ball.pos = new planck.Vec2(this.pos.x + x, this.pos.y + y)
        }
        app.display.context.translate(0, -PLR_RADIUS / 2)
        app.display.blit(this.pawn, -this.pawn.width / 2, -this.pawn.height / 2)
        app.display.context.restore()
    }
}
<commit_msg>distance_from works with planck<commit_after>var PLR_SHADOW = -5
var PLR_FORCE = 0.8;
var PLR_RADIUS = 20

class Player {
    constructor(menu, image) {
        var shape = new planck.Circle(PLR_RADIUS / PHY_SCALE)
        var body = menu.world.createBody({
            'type': 'dynamic'
        })
        this.world = menu.world
        body.createFixture({
            'shape': shape,
            'restitution': 0.9,
            'm_radius': PLR_RADIUS / PHY_SCALE
        }).setUserData(this)
        body.setLinearDamping(0.3);
        body.setAwake(true);
        body.setActive(true);
        this.body = body;
        this.image = image;
        this.pawn = makeImage('img/pawn.png')
        this.ball = false
        this.boost_dt = 0
    }
    take_ball(ball) {
        if (ball.owned) {
            ball.owned.ball = false;
        }
        ball.body.setActive(false);
        this.ball = ball
        ball.owned = this
    }
    distance_from(coords) {
        return Math.sqrt(Math.pow(coords.x - this.pos.x, 2) + Math.pow(coords.y - this.pos.y, 2))
    }
    set_position(x, y, randomicity = 0, rotation = 0) {
        let temp = new planck.Vec2(x / PHY_SCALE + (Math.random() * randomicity - randomicity / 2), -y / PHY_SCALE + (Math.random() * randomicity - randomicity / 2))
        this.body.setLinearVelocity({
            x: 0,
            y: 0
        }, 0.0);
        this.body.setTransform(temp, rotation);
    }
    destroy() {
        this.world.destroyBody(this.body)
        this.body = null
        this.image = null
        this.world = null
    }

    targets(coords, coord2, delta) {
        var x = coords[0] - this.pos.x
        var y = coords[1] - this.pos.y
        var distance = Math.sqrt(Math.pow(Math.abs(x), 2) + Math.pow(Math.abs(y), 2))
        var angle = Math.acos(x / distance)
        var myangle = (Math.PI / 2 + this.body.getAngle()) % (2 * Math.PI)
        var sync = Math.abs(angle - myangle) < (delta / 360 * (2 * Math.PI))
        return [sync, angle]
    }
    push(dt) {
        if (!!this.ball) {
            // shooting ball
            this.ball.shot(dt)
            let angle = this.body.getAngle()
            let [x, y] = [Math.sin(-angle), Math.cos(-angle)]
            let temp = new planck.Vec2(this.pos.x + x, this.pos.y + y)
            this.ball.body.setTransform(temp, angle)
            this.ball.body.setActive(true)
            temp = this.body.getLinearVelocity()
            this.ball.body.setLinearVelocity(temp)
            this.ball.body.applyLinearImpulse(this.ball.body.getWorldVector(new planck.Vec2(0, 3 * PLR_FORCE)), this.ball.pos, true)
            this.ball = false
        } else {
            if (dt < this.boost_dt + 2000) // 2s min between 2 boosts
                return
            this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, 5 * PLR_FORCE)), this.pos, true)
        }
        this.boost_dt = dt
    }
    forward(delta) {
        let force = PLR_FORCE * delta
        this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, force)), this.pos, true)
    }
    backward(delta) {
        let force = PLR_FORCE * delta
        this.body.applyLinearImpulse(this.body.getWorldVector(new planck.Vec2(0, -force / 1.25)), this.pos, true)
    }
    left(delta) {
        let angle = 0.37 * delta
        this.body.setTransform(this.pos, this.body.getAngle() + angle)

    }
    right(delta) {
        let angle = 0.37 * delta
        this.body.setTransform(this.pos, this.body.getAngle() - angle)
    }
    draw(dt, delta) {
        this.pos = this.body.getPosition();
        app.display.context.save()
        let x = PHY_SCALE * (this.pos.x)
        let y = -PHY_SCALE * (this.pos.y)
        app.display.context.translate(x, y)
        app.display.blit(this.image, -PLR_RADIUS, -PLR_RADIUS)
        app.display.context.rotate(-this.body.getAngle())
        app.display.context.translate(0, -PLR_RADIUS / 2)
        if (this.ball) {
            app.display.blit(this.ball.image, -this.ball.image.width / 2, -this.ball.image.height / 2)
            let angle = this.body.getAngle()
            let [x, y] = [Math.sin(-angle), Math.cos(-angle)]
            this.ball.pos = new planck.Vec2(this.pos.x + x, this.pos.y + y)
        }
        app.display.context.translate(0, -PLR_RADIUS / 2)
        app.display.blit(this.pawn, -this.pawn.width / 2, -this.pawn.height / 2)
        app.display.context.restore()
    }
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router';

export default class App extends Component {
  render () {
    return (

<Link to="/authoring">Authoring</Link>

<Link to="/upcoming">Upcoming</Link>

          {this.props.children}

    );
  }
}

App.propTypes = {
  children : React.PropTypes.element
};
<commit_msg>Add site title<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router';

export default class App extends Component {
  render () {
    return (

Firefox Tiles

<Link to="/authoring">Authoring</Link>

<Link to="/upcoming">Upcoming</Link>

          {this.props.children}

    );
  }
}

App.propTypes = {
  children : React.PropTypes.element
};
<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";

var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();

require(['gitbook'], function (gitbook) {
    function addBeforeHeader(element) {
        jQuery('.book-header > h1').before(element);
    }

    function createButton(_ref) {
        var user = _ref.user;
        var repo = _ref.repo;
        var type = _ref.type;
        var size = _ref.size;
        var count = _ref.count;

        var width = size === "large" ? "170px" : "160xp";
        var height = size === "large" ? "30" : "20xp";
        var extraParam = type === "watch" ? "&v=2" : "";
        return '';
    }

    function insertGitHubLink(_ref2) {
        var user = _ref2.user;
        var repo = _ref2.repo;
        var types = _ref2.types;
        var size = _ref2.size;
        var count = _ref2.count;

        types.reverse().forEach(function (type) {
            var elementString = createButton({
                user: user,
                repo: repo,
                type: type,
                size: size,
                count: count
            });
            addBeforeHeader(elementString);
        });
    }

    gitbook.events.bind('start', function (e, config) {
        var repoPath = config.github.repo;

        var _repoPath$split = repoPath.split("/");

        var _repoPath$split2 = _slicedToArray(_repoPath$split, 2);

        var user = _repoPath$split2[0];
        var repo = _repoPath$split2[1];

        if (repoPath == null) {
            console.log("Should set github.repo");
            return;
        }
        var types = config.github.types || ["star", "watch"];
        var size = config.github.size || "large";
        var count = typeof config.github.count === "undefined" ? "true" : "false";
        insertGitHubLink({
            user: user,
            repo: repo,
            types: types,
            size: size,
            count: count
        });
    });

    gitbook.events.bind('page.change', function () {
        insertGitHubLink();
    });
});
//# sourceMappingURL=plugin.js.map<commit_msg>refactor: change<commit_after>// LICENSE : MIT
"use strict";

var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();

require(['gitbook'], function (gitbook) {
    function addBeforeHeader(element) {
        jQuery('.book-header > h1').before(element);
    }

    function createButton(_ref) {
        var user = _ref.user;
        var repo = _ref.repo;
        var type = _ref.type;
        var size = _ref.size;
        var count = _ref.count;

        var width = size === "large" ? "170px" : "160xp";
        var height = size === "large" ? "30" : "20xp";
        var extraParam = type === "watch" ? "&v=2" : "";
        return '';
    }

    function insertGitHubLink(_ref2) {
        var user = _ref2.user;
        var repo = _ref2.repo;
        var types = _ref2.types;
        var size = _ref2.size;
        var count = _ref2.count;

        types.reverse().forEach(function (type) {
            var elementString = createButton({
                user: user,
                repo: repo,
                type: type,
                size: size,
                count: count
            });
            addBeforeHeader(elementString);
        });
    }

    function init(config) {
        var repoPath = config.github.repo;

        var _repoPath$split = repoPath.split("/");

        var _repoPath$split2 = _slicedToArray(_repoPath$split, 2);

        var user = _repoPath$split2[0];
        var repo = _repoPath$split2[1];

        if (repoPath == null) {
            console.log("Should set github.repo");
            return;
        }
        var types = config.github.types || ["star", "watch"];
        var size = config.github.size || "large";
        var count = typeof config.github.count === "undefined" ? "true" : "false";
        insertGitHubLink({
            user: user,
            repo: repo,
            types: types,
            size: size,
            count: count
        });
    }

    /**
     * repo
     * types
     * size
     * count
     */
    gitbook.events.bind('start', function (e, config) {
        init(config);
    });

    gitbook.events.bind('page.change', function (e, config) {
        init(config);
    });
});
//# sourceMappingURL=plugin.js.map<|endoftext|>


<commit_before>var path = require('path'),
    naming = require('bem-naming'),
    vow = require('vow'),
    vfs = require('enb/lib/fs/async-fs'),
    scanner = require('enb-bem-pseudo-levels/lib/level-scanner'),
    configurator = require('./node-configurator'),
    deps = require('enb-bem-techs/lib/deps/deps'),
    MagicConfig = require('enb-magic-factory/lib/magic-config');

function deprecateOption(option, replacement) {
    console.warn('WARNING!');
    console.warn('Option `%s` is deprecated.', option);
    console.warn('Use `%s` option instead.', replacement);
}

module.exports = function (helper, factory, exampleTaskName) {
    return {
        configure: function (options) {
            options || (options = {});
            options.exampleSets || (options.exampleSets = []);
            options.docSuffixes || (options.docSuffixes = ['md', 'wiki']);
            options.docI18NSuffixes = options.langs ? buildI18NSuffixes(options.docSuffixes, options.langs) : [];

            if (options.jsdoc !== false) {
                options.jsSuffixes && deprecateOption('jsSuffixes', 'jsdoc.suffixes');
                options.jsdocParser && deprecateOption('jsdocParser', 'jsdoc.parser');

                options.jsdoc || (options.jsdoc = {});

                options.jsdoc.suffixes || (options.jsdoc.suffixes = (options.jsSuffixes || ['js']));
                options.jsdoc.parser || (options.jsdoc.parser = (options.jsdocParser || 'jsd'));
            }

            options._examples = [];
            this._dependOnExamples(options);
            this._buildSet(options);
            this._configureNodes(options);
        },

        _buildSet: function (options) {
            var root = helper.getRootPath(),
                dstpath = path.resolve(root, options.destPath),
                levels = options.levels.map(function (levelPath) {
                    var level = (typeof levelPath === 'string') ? { path: levelPath } : levelPath;

                    level.path = path.resolve(root, level.path);

                    return level;
                });

            helper.prebuild(function (magic) {
                return scanner.scan(levels)
                    .then(function (files) {
                        var nodes = {},
                            nodeDeps = {};

                        files.forEach(function (file) {
                            var ext = path.extname(file.name);

                            if (options.docSuffixes.indexOf(file.suffix) !== -1 ||
                                options.docI18NSuffixes.indexOf(file.suffix) !== -1 ||
                                ext === '.js'
                            ) {
                                var bemname = file.name.split('.')[0],
                                    notation = naming.parse(bemname),
                                    block = notation.block,
                                    dep = { block: block },
                                    node = path.join(options.destPath, notation.block);

                                notation.elem && (dep.elem = notation.elem);

                                if (notation.modName) {
                                    dep.mod = notation.modName;
                                    dep.val = notation.modVal;
                                }

                                if (magic.isRequiredNode(node)) {
                                    var sourceDeps = nodeDeps[node] || [];

                                    sourceDeps.push(dep);
                                    nodeDeps[node] = sourceDeps;
                                    nodes[node] = true;

                                    magic.registerNode(node);
                                }
                            }
                        });

                        return vow.all(Object.keys(nodes).map(function (node) {
                            var sourceDeps = nodeDeps[node],
                                block = sourceDeps[0].block,
                                dirname = path.join(dstpath, block),
                                bemdeclFilename = path.join(dirname, block + '.bemdecl.js'),
                                bemdeclSource;

                            bemdeclSource = 'exports.blocks = ' + JSON.stringify(deps.toBemdecl(sourceDeps)) + ';';

                            return vfs.makeDir(dirname)
                                .then(function () {
                                    return vfs.write(bemdeclFilename, bemdeclSource, 'utf-8');
                                });
                        }));
                    });
            });
        },

        _configureNodes: function (options) {
            var exampleSets = options.exampleSets,
                exampleChannel = factory.getEventChannel(exampleTaskName);

            if (exampleSets && exampleChannel) {
                exampleChannel.on('examples', function (scope, items) {
                    if (exampleSets.indexOf(scope) !== -1) {
                        options._examples = options._examples.concat(items);
                    }
                });

                exampleChannel.on('inline-examples', function (scope, items) {
                    if (exampleSets.indexOf(scope) !== -1) {
                        options._examples = options._examples.concat(items);
                    }
                });
            }

            helper.configure(function (projectConfig) {
                configurator.configure(projectConfig, options);
            });
        },

        _dependOnExamples: function (options) {
            exampleTaskName && helper.prebuild(function (magic) {
                var requiredTargets = magic.getRequiredTargets(),
                    exampleHelper = factory.getHelper(exampleTaskName),
                    hasExampleSets = false,
                    hasDocSet = false,
                    runInMagicTask = factory.getMetaTaskState() === 'running';

                requiredTargets && requiredTargets.forEach(function (target) {
                    options.exampleSets.forEach(function (exampleSet) {
                        (target.indexOf(exampleSet) !== -1) && (hasExampleSets = true);
                    });
                    (target.indexOf(options.destPath) !== -1) && (hasDocSet = true);
                });

                // Запускаем предсборку примеров, если таск сборки примеров не был запущен пользователем явно
                // или через мета-таск с аргументами, переданными в `options.exampleSets`.
                if ((!runInMagicTask || (runInMagicTask && hasDocSet && !hasExampleSets)) &&
                    options.exampleSets &&
                    options.exampleSets.length
                ) {
                    var projectConfig = helper._projectConfig,
                        exampleTask = projectConfig && projectConfig._tasks[exampleTaskName],
                        logger = exampleTask && exampleTask._logger,
                        magicConfig = new MagicConfig(options.exampleSets);

                    return vow.all(exampleHelper._prebuilds.map(function (callback) {
                        return callback.apply(exampleHelper, [magicConfig, logger]);
                    }));
                // Ожидаем предсборки примеров
                } else {
                    var channel = exampleHelper.getEventChannel(),
                        defer = vow.defer();

                    channel.on('prebuild', function () {
                        defer.resolve();
                    });

                    return defer.promise();
                }
            });
        }
    };
};

function buildI18NSuffixes(suffixes, langs) {
    var res = [];

    suffixes.map(function (suffix) {
        langs.forEach(function (lang) {
            res.push([lang, suffix].join('.'));
        });
    });

    return res;
}
<commit_msg>Fixed bug with prebuild of inline examples<commit_after>var path = require('path'),
    naming = require('bem-naming'),
    vow = require('vow'),
    vfs = require('enb/lib/fs/async-fs'),
    scanner = require('enb-bem-pseudo-levels/lib/level-scanner'),
    configurator = require('./node-configurator'),
    deps = require('enb-bem-techs/lib/deps/deps'),
    MagicConfig = require('enb-magic-factory/lib/magic-config');

function deprecateOption(option, replacement) {
    console.warn('WARNING!');
    console.warn('Option `%s` is deprecated.', option);
    console.warn('Use `%s` option instead.', replacement);
}

module.exports = function (helper, factory, exampleTaskName) {
    return {
        configure: function (options) {
            options || (options = {});
            options.exampleSets || (options.exampleSets = []);
            options.docSuffixes || (options.docSuffixes = ['md', 'wiki']);
            options.docI18NSuffixes = options.langs ? buildI18NSuffixes(options.docSuffixes, options.langs) : [];

            if (options.jsdoc !== false) {
                options.jsSuffixes && deprecateOption('jsSuffixes', 'jsdoc.suffixes');
                options.jsdocParser && deprecateOption('jsdocParser', 'jsdoc.parser');

                options.jsdoc || (options.jsdoc = {});

                options.jsdoc.suffixes || (options.jsdoc.suffixes = (options.jsSuffixes || ['js']));
                options.jsdoc.parser || (options.jsdoc.parser = (options.jsdocParser || 'jsd'));
            }

            options._examples = [];
            this._dependOnExamples(options);
            this._buildSet(options);
            this._configureNodes(options);
        },

        _buildSet: function (options) {
            var root = helper.getRootPath(),
                dstpath = path.resolve(root, options.destPath),
                levels = options.levels.map(function (levelPath) {
                    var level = (typeof levelPath === 'string') ? { path: levelPath } : levelPath;

                    level.path = path.resolve(root, level.path);

                    return level;
                });

            helper.prebuild(function (magic) {
                return scanner.scan(levels)
                    .then(function (files) {
                        var nodes = {},
                            nodeDeps = {};

                        files.forEach(function (file) {
                            var ext = path.extname(file.name);

                            if (options.docSuffixes.indexOf(file.suffix) !== -1 ||
                                options.docI18NSuffixes.indexOf(file.suffix) !== -1 ||
                                ext === '.js'
                            ) {
                                var bemname = file.name.split('.')[0],
                                    notation = naming.parse(bemname),
                                    block = notation.block,
                                    dep = { block: block },
                                    node = path.join(options.destPath, notation.block);

                                notation.elem && (dep.elem = notation.elem);

                                if (notation.modName) {
                                    dep.mod = notation.modName;
                                    dep.val = notation.modVal;
                                }

                                if (magic.isRequiredNode(node)) {
                                    var sourceDeps = nodeDeps[node] || [];

                                    sourceDeps.push(dep);
                                    nodeDeps[node] = sourceDeps;
                                    nodes[node] = true;

                                    magic.registerNode(node);
                                }
                            }
                        });

                        return vow.all(Object.keys(nodes).map(function (node) {
                            var sourceDeps = nodeDeps[node],
                                block = sourceDeps[0].block,
                                dirname = path.join(dstpath, block),
                                bemdeclFilename = path.join(dirname, block + '.bemdecl.js'),
                                bemdeclSource;

                            bemdeclSource = 'exports.blocks = ' + JSON.stringify(deps.toBemdecl(sourceDeps)) + ';';

                            return vfs.makeDir(dirname)
                                .then(function () {
                                    return vfs.write(bemdeclFilename, bemdeclSource, 'utf-8');
                                });
                        }));
                    });
            });
        },

        _configureNodes: function (options) {
            var exampleSets = options.exampleSets,
                exampleChannel = factory.getEventChannel(exampleTaskName);

            if (exampleSets && exampleChannel) {
                exampleChannel.on('examples', function (scope, items) {
                    if (exampleSets.indexOf(scope) !== -1) {
                        options._examples = options._examples.concat(items);
                    }
                });

                exampleChannel.on('inline-examples', function (scope, items) {
                    if (exampleSets.indexOf(scope) !== -1) {
                        options._examples = options._examples.concat(items);
                    }
                });
            }

            helper.configure(function (projectConfig) {
                configurator.configure(projectConfig, options);
            });
        },

        _dependOnExamples: function (options) {
            exampleTaskName && helper.prebuild(function (magic) {
                var requiredTargets = magic.getRequiredTargets(),
                    exampleHelper = factory.getHelper(exampleTaskName),
                    hasExampleSets = false,
                    hasDocSet = false,
                    runInMagicTask = factory.getMetaTaskState() === 'running';

                requiredTargets && requiredTargets.forEach(function (target) {
                    options.exampleSets.forEach(function (exampleSet) {
                        (target.indexOf(exampleSet) !== -1) && (hasExampleSets = true);
                    });
                    (target.indexOf(options.destPath) !== -1) && (hasDocSet = true);
                });

                // Запускаем предсборку примеров, если таск сборки примеров не был запущен пользователем явно
                // или через мета-таск с аргументами, переданными в `options.exampleSets`.
                if ((!runInMagicTask || (runInMagicTask && hasDocSet && !hasExampleSets)) &&
                    options.exampleSets &&
                    options.exampleSets.length
                ) {
                    var projectConfig = helper._projectConfig,
                        exampleTask = projectConfig && projectConfig._tasks[exampleTaskName],
                        logger = exampleTask && exampleTask._logger,
                        magicConfig = new MagicConfig(options.exampleSets);

                    exampleTask._makePlatform || (exampleTask.setMakePlatform(helper._taskConfig._makePlatform));

                    return vow.all(exampleHelper._prebuilds.map(function (callback) {
                        return callback.apply(exampleHelper, [magicConfig, logger]);
                    }));
                // Ожидаем предсборки примеров
                } else {
                    var channel = exampleHelper.getEventChannel(),
                        defer = vow.defer();

                    channel.on('prebuild', function () {
                        defer.resolve();
                    });

                    return defer.promise();
                }
            });
        }
    };
};

function buildI18NSuffixes(suffixes, langs) {
    var res = [];

    suffixes.map(function (suffix) {
        langs.forEach(function (lang) {
            res.push([lang, suffix].join('.'));
        });
    });

    return res;
}
<|endoftext|>


<commit_before>var path = require('path');
var HOOKS = require('./hooks');
var defaultConfig = require('./config');
var configure = require('./configuration');
var configureLoaderPath = require('./configuration/loader').LOADER_PATH;
var Promise = require('bluebird');
var SuperError = require('./utils/SuperError');
var arrayFrom = require('./utils/arrayFrom');
var getConfig = require('./configuration/getConfig');

var generateLoadersString = require('./utils/loader/generateLoaderRequestString');
var getAffectedFiles = require('./compilation/getAffectedFiles');
var findFilesToProcess = require('./processing/findFilesToProcess');
var Source = require('./data/Source');
var extractDocs = require('./processing/extractDocs');
var DocsNotFoundException = require('./processing/DocsNotFoundException');

var readFile = require('./utils/readFile');
var addEntry = require('./compiler/addEntry');

/**
 * @param {DocsPluginConfig} [config]
 * @constructor
 */
function DocsPlugin(config) {
  this.config = {
    initial: configure(config),
    loaders: []
  };

  this.extractors = {};
}

/**
 * @type {Compiler}
 * @private
 */
DocsPlugin.prototype._compiler = null;

/**
 * @type {DocsPluginHooks}
 * @static
 */
DocsPlugin.HOOKS = HOOKS;

/**
 * @type {DocsPluginConfig}
 * @static
 */
DocsPlugin.defaultConfig = defaultConfig;

/**
 * @param {DocsPluginConfig} [config]
 * @param {string} [entryPath]
 * @returns {string}
 * @static
 */
DocsPlugin.extract = function(config, entryPath) {
  return generateLoadersString(configureLoaderPath, config, entryPath);
};

/**
 * @type {Object}
 * @property {DocsPluginConfig} initial
 * @property {Array<DocsPluginConfig>} loaders
 */
DocsPlugin.prototype.config = null;

/**
 * @type {Object<string, DocsPluginExtractor>}
 */
DocsPlugin.prototype.extractors = null;

/**
 * @param {string} [filepath]
 * @returns {DocsPluginConfig}
 */
DocsPlugin.prototype.getConfig = function(filepath) {
  if (!filepath)
    return this.config.initial;

  var config = getConfig(this.config, filepath);
  return config ? config : this.config.initial;
};

/**
 * @param {string} name
 * @param {DocsPluginExtractor} extractor
 */
DocsPlugin.prototype.registerExtractor = function(name, extractor) {
  this.extractors[name] = extractor;
};

/**
 * @param {string} filepath
 * @returns {Promise}
 */
DocsPlugin.prototype.readFile = function(filepath) {
  return readFile(filepath, this._compiler.inputFileSystem);
};

/**
 * @param {string} name
 * @param {string} path Request path to entry. May contain loaders string.
 * @param {string} [contextPath]
 */
DocsPlugin.prototype.addEntry = function(name, path, contextPath) {
  addEntry(this._compiler, name, path, contextPath);
};

/**
 * @param {Compiler} compiler
 */
DocsPlugin.prototype.apply = function (compiler) {
  this._compiler = compiler;
  var plugin = this;

  // Configure loaders config
  var config = plugin.config;
  config.loaders = configure.createConfigFromLoaders(
    compiler.options.module.loaders,
    plugin.config.initial
  );

  config.initial.plugins.forEach(function(plugin) {
    compiler.apply(plugin);
  });

  compiler.plugin('after-plugins', function () {
    this.applyPlugins(HOOKS.CONFIGURE, plugin);
  });

  compiler.plugin('this-compilation', function (compilation) {
    var applyPluginsAsync = Promise.promisify(compilation.applyPluginsAsyncWaterfall, {context: compilation});

    compilation.plugin('optimize-tree', function (chunks, modules, done) {
      var extractorsNames = Object.keys(plugin.extractors);
      if (extractorsNames.length == 0) {
        return done('At least one extractor should be provided');
      }
      else if (extractorsNames.length == 1) {
        config.initial.extractor = config.initial.extractor || extractorsNames[0];
        config.loaders.forEach(function(cfg) {
          cfg.extractor = cfg.extractor || extractorsNames[0];
        })
      }

      var contextPath = this.compiler.options.context;
      var affectedFiles = getAffectedFiles(compilation);
      var filesToProcess = findFilesToProcess(affectedFiles, plugin.config);
      var sourcePromises = [];

      filesToProcess.forEach(function(file) {
        var sourcePromise = plugin.readFile(file.path)

          // Source
          .then(function (content) {

            var source = new Source({
              path: path.relative(contextPath, file.path),
              content: content.toString('utf-8'),
              absolutePath: file.path
            });

            return applyPluginsAsync(HOOKS.SOURCE_CREATED, {source: source, plugin: plugin})
              .then(function () { return source });
          })

          // Extractor
          .then(function(source) {
            var extractorName = plugin.getConfig(source.absolutePath).extractor;
            if (!(extractorName in plugin.extractors))
              return Promise.reject(new SuperError('Extractor "%s" not found', extractorName));

            var extractor = plugin.extractors[extractorName];
            var options = plugin.getConfig(source.absolutePath).extractorOptions;

            return extractDocs(source, extractor, options, compilation)
              .then(function (result) {
                if (result === null)
                  return null;

                result.source = source;
                return result;
              });
          });

        sourcePromises.push(sourcePromise);
      });

      Promise
        .all(sourcePromises)
        .filter(function (result) { return result !== null })
        .each(function (result) {
          console.log(result.source.path);
        })
        .then(function() { done() });

    });
  });
};

module.exports = DocsPlugin;
<commit_msg>Add after extract hook<commit_after>var path = require('path');
var HOOKS = require('./hooks');
var defaultConfig = require('./config');
var configure = require('./configuration');
var configureLoaderPath = require('./configuration/loader').LOADER_PATH;
var Promise = require('bluebird');
var SuperError = require('./utils/SuperError');
var arrayFrom = require('./utils/arrayFrom');
var getConfig = require('./configuration/getConfig');

var generateLoadersString = require('./utils/loader/generateLoaderRequestString');
var getAffectedFiles = require('./compilation/getAffectedFiles');
var findFilesToProcess = require('./processing/findFilesToProcess');
var Source = require('./data/Source');
var extractDocs = require('./processing/extractDocs');
var DocsNotFoundException = require('./processing/DocsNotFoundException');

var readFile = require('./utils/readFile');
var addEntry = require('./compiler/addEntry');

/**
 * @param {DocsPluginConfig} [config]
 * @constructor
 */
function DocsPlugin(config) {
  this.config = {
    initial: configure(config),
    loaders: []
  };

  this.extractors = {};
}

/**
 * @type {Compiler}
 * @private
 */
DocsPlugin.prototype._compiler = null;

/**
 * @type {DocsPluginHooks}
 * @static
 */
DocsPlugin.HOOKS = HOOKS;

/**
 * @type {DocsPluginConfig}
 * @static
 */
DocsPlugin.defaultConfig = defaultConfig;

/**
 * @param {DocsPluginConfig} [config]
 * @param {string} [entryPath]
 * @returns {string}
 * @static
 */
DocsPlugin.extract = function(config, entryPath) {
  return generateLoadersString(configureLoaderPath, config, entryPath);
};

/**
 * @type {Object}
 * @property {DocsPluginConfig} initial
 * @property {Array<DocsPluginConfig>} loaders
 */
DocsPlugin.prototype.config = null;

/**
 * @type {Object<string, DocsPluginExtractor>}
 */
DocsPlugin.prototype.extractors = null;

/**
 * @param {string} [filepath]
 * @returns {DocsPluginConfig}
 */
DocsPlugin.prototype.getConfig = function(filepath) {
  if (!filepath)
    return this.config.initial;

  var config = getConfig(this.config, filepath);
  return config ? config : this.config.initial;
};

/**
 * @param {string} name
 * @param {DocsPluginExtractor} extractor
 */
DocsPlugin.prototype.registerExtractor = function(name, extractor) {
  this.extractors[name] = extractor;
};

/**
 * @param {string} filepath
 * @returns {Promise}
 */
DocsPlugin.prototype.readFile = function(filepath) {
  return readFile(filepath, this._compiler.inputFileSystem);
};

/**
 * @param {string} name
 * @param {string} path Request path to entry. May contain loaders string.
 * @param {string} [contextPath]
 */
DocsPlugin.prototype.addEntry = function(name, path, contextPath) {
  addEntry(this._compiler, name, path, contextPath);
};

/**
 * @param {Compiler} compiler
 */
DocsPlugin.prototype.apply = function (compiler) {
  this._compiler = compiler;
  var plugin = this;

  // Configure loaders config
  var config = plugin.config;
  config.loaders = configure.createConfigFromLoaders(
    compiler.options.module.loaders,
    plugin.config.initial
  );

  config.initial.plugins.forEach(function(plugin) {
    compiler.apply(plugin);
  });

  compiler.plugin('after-plugins', function () {
    this.applyPlugins(HOOKS.CONFIGURE, plugin);
  });

  compiler.plugin('this-compilation', function (compilation) {
    var applyPluginsAsync = Promise.promisify(compilation.applyPluginsAsyncWaterfall, {context: compilation});

    compilation.plugin('optimize-tree', function (chunks, modules, done) {
      var extractorsNames = Object.keys(plugin.extractors);
      if (extractorsNames.length == 0) {
        return done('At least one extractor should be provided');
      }
      else if (extractorsNames.length == 1) {
        config.initial.extractor = config.initial.extractor || extractorsNames[0];
        config.loaders.forEach(function(cfg) {
          cfg.extractor = cfg.extractor || extractorsNames[0];
        })
      }

      var contextPath = this.compiler.options.context;
      var affectedFiles = getAffectedFiles(compilation);
      var filesToProcess = findFilesToProcess(affectedFiles, plugin.config);
      var sourcePromises = [];

      filesToProcess.forEach(function(file) {
        var sourcePromise = plugin.readFile(file.path)

          // Source
          .then(function (content) {

            var source = new Source({
              path: path.relative(contextPath, file.path),
              content: content.toString('utf-8'),
              absolutePath: file.path
            });

            return applyPluginsAsync(HOOKS.SOURCE_CREATED, {source: source, plugin: plugin})
              .then(function () { return source });
          })

          // Extractor
          .then(function(source) {
            var extractorName = plugin.getConfig(source.absolutePath).extractor;
            if (!(extractorName in plugin.extractors))
              return Promise.reject(new SuperError('Extractor "%s" not found', extractorName));

            var extractor = plugin.extractors[extractorName];
            var options = plugin.getConfig(source.absolutePath).extractorOptions;

            return extractDocs(source, extractor, options, compilation)
              .then(function (result) {
                if (result === null)
                  return null;

                result.source = source;
                return result;
              });
          });

        sourcePromises.push(sourcePromise);
      });

      Promise
        .all(sourcePromises)
        .filter(function (result) { return result !== null })
        .each(function (result) {
          return applyPluginsAsync(HOOKS.EXTRACTOR_DONE, {result: result, plugin: plugin});
        })
        .each(function(result) {

        })
        .then(function() { done() });

    });
  });
};

module.exports = DocsPlugin;
<|endoftext|>