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

module.exports = {
    process: function(gff3_data, types, longest) {
        var features = [];
        gff3_data.split('\n').map(function(line) {
            if (!line.startsWith('#') && line.length != 0) {
                var parts = line.split('\t');

                if (parts.length !== 9) {
                    //the file might use spaces instead of tabs
                    //ill try to split it by spaces
                    parts = line.trim().split(/\s+/);
                }

                if (parts.length == 9) {
                    var attParts = parts[8].split(';');
                    var arrayObject = {};
                    for (var i = 0; i < attParts.length; ++i) {
                        var pair = attParts[i].split("=");
                        arrayObject[pair[0]] = pair[1];
                    }

                    var feature = {
                        seqid: parts[0],
                        source: parts[1],
                        type: parts[2],
                        start: parts[3]/longest * 900,
                        end: parts[4]/longest * 900,
                        score: parts[5],
                        strand: parts[6],
                        phase: parts[7],
                        attributes: arrayObject
                    };
                    // check if user specified feature type
                    if (types === undefined || $.inArray(feature.type, types) != -1) {
                        features.push(feature);
                    }
                } else {
                    var err = new Error('9 parts of feature not found');
                    console.log(err);
                }
            }
        });
        return features;
    },
};
<commit_msg>optimization<commit_after>var $ = require('jquery');

module.exports = {
    process: function(gff3_data, types, longest) {
        var features = [];
        gff3_data.split('\n').map(function(line) {
            if (!line.startsWith('#') && line.length != 0) {
                var parts = line.split('\t');

                if (parts.length !== 9) {
                    //the file might use spaces instead of tabs
                    //ill try to split it by spaces
                    parts = line.trim().split(/\s+/);
                }

                if (parts.length == 9) {
                    var attParts = parts[8].split(';');
                    var arrayObject = {};
                    for (var i = 0; i < attParts.length; ++i) {
                        var pair = attParts[i].split("=");
                        arrayObject[pair[0]] = pair[1];
                    }

                    var feature = {
                        seqid: parts[0],
                        source: parts[1],
                        type: parts[2],
                        start: parts[3]/longest * 900,
                        end: parts[4]/longest * 900,
                        score: parts[5],
                        strand: parts[6],
                        phase: parts[7],
                        attributes: arrayObject
                    };
                    // check if user specified feature type
                    if (types === undefined || types.indexOf(feature.type) > -1) {
                        features.push(feature);
                    }
                } else {
                    var err = new Error('9 parts of feature not found');
                    console.log(err);
                }
            }
        });
        return features;
    },
};
<|endoftext|>


<commit_before>"use strict";
module.exports = parseTito;

var XRegExp = require('xregexp');

var basicInfoRe = new XRegExp('^T00' +
                              '(?<infoLength>                     .     {3}  )' +
                              '(?<version>                        .     {3}  )' +
                              '(?<bban>                           .     {14} )' +
                              '(?<statementNumber>                [0-9] {3}  )' +
                              '(?<startDate>                      [0-9] {6}  )' +
                              '(?<endDate>                        [0-9] {6}  )' +
                              '(?<creationDate>                   [0-9] {6}  )' +
                              '(?<creationTime>                   [0-9] {4}  )' +
                              '(?<contractId>                     .     {17} )' +
                              '(?<devnull>                        .     {31} )' +
                              '(?<currency>                       .     {3}  )' +
                              '(?<accountName>                    .     {30} )' +
                              '(?<devnull2>                       .     {18} )' +
                              '(?<accountOwnerName>               .     {35} )' +
                              '(?<bankContactInformation>        .     {40} )' +
                              '(?<bankContactInformationDetails> .     {40} )' +
                              '(?<devnull3>                       .     {30} )' +
                              '(?<iban>                           .     {18} ) \\ ' +
                              '(?<bic>                            .     {8}  )', 'x');

var entryInfoRe = new XRegExp('^T10' +
                              '(?<infoLength>         .     {3}  )' +
                              '(?<entryNumber>        [0-9] {6}  )' +
                              '(?<archiveId>          .     {18} )' +
                              '(?<bookingDate>        [0-9] {6}  )' +
                              '(?<valueDate>          [0-9] {6}  )' +
                              '(?<paymentDate>        [0-9] {6}  ) (.) ' +
                              '(?<bookingInformation> .     {38} )' +
                              '(?<sign>               .     {1}  )' +
                              '(?<amount>             [0-9] {18} )' +
                              '(?<devnull>            .     {2}  )' +
                              '(?<receiver>           .     {35} ) (.)' +
                              '(?<receiverBban>       .     {14} ) (.)' +
                              '(?<referenceNumber>    .     {20} )', 'x');

var additionalEntryInfoRe = new XRegExp('^T11' +
                                        '(?<infoLength> [0-9] {3} )' +
                                        '(?<infoType>   .     {2} )', 'x');

var balanceRe = new XRegExp('^T40' +
                            '(?<infoLength>          .     {3}  )' +
                            '(?<bookingDate>         [0-9] {6}  )' +
                            '(?<amountSign>          .     {1}  )' +
                            '(?<amount>              [0-9] {18} )' +
                            '(?<availableAmountSign> .     {1}  )' +
                            '(?<availableAmount>     [0-9] {18} )', 'x');

function parseTito(txt) {
  var headerInfo,
      entries = [],
      balances = [];
  txt.split("\n").forEach(function(line) {
    line = line.replace(/\}/g, 'å')
               .replace(/{/g, 'ä')
               .replace(/\|/g, 'ö')
               .replace(/\]/g, 'Å')
               .replace(/\[/g, 'Ä')
               .replace(/\\/g, 'Ö');
    var m;
    if (basicInfoRe.test(line)) {
      m = XRegExp.exec(line, basicInfoRe);
      headerInfo = {
        accountName: m.accountName.trim(),
        accountOwnerName: m.accountOwnerName.trim(),
        bankContactInformation: m.bankContactInformation.trim(),
        bankContactInformationDetails: m.bankContactInformationDetails.trim(),
        bban: m.bban,
        bic: m.bic,
        contractId: m.contractId.trim(),
        creationDate: stringToDateString(m.creationDate),
        creationTime: m.creationTime.substring(0,2) + ':' + m.creationTime.substring(2, 4),
        currency: m.currency,
        endDate: stringToDateString(m.endDate),
        iban: m.iban,
        startDate: stringToDateString(m.startDate),
        statementNumber: m.statementNumber
      };
    } else if (entryInfoRe.test(line)) {
      m = XRegExp.exec(line, entryInfoRe);
      entries.push({
        additionalInformation: [],
        amount: Number(m.amount) / 100 * (m.sign === '-' ? -1 : 1),
        archiveId: m.archiveId.trim(),
        bookingDate: stringToDateString(m.bookingDate),
        bookingInformation: m.bookingInformation.trim(),
        paymentDate: stringToDateString(m.paymentDate),
        receiver: m.receiver.trim(),
        receiverBban: m.receiverBban.trim(),
        referenceNumber: m.referenceNumber.trim() ? parseInt(m.referenceNumber, 10) + '' : '',
        valueDate: stringToDateString(m.valueDate)
      });
    } else if (additionalEntryInfoRe.test(line)) {
      m = XRegExp.exec(line, additionalEntryInfoRe);
      var entry = entries[entries.length - 1];
      if (['00', '07', '06', '08'].indexOf(m.infoType) !== -1 ) {
        var totalLength = Number(m.infoLength), parts = [];
        for (var i = 8; i < totalLength; i=i+35) {
          parts.push(line.substring(i, i+35).trim());
        }
        entry.additionalInformation.push(parts.join(' '));
      }
    } else if (balanceRe.test(line)) {
      m = XRegExp.exec(line, balanceRe);
      balances.push({
        bookingDate: stringToDateString(m.bookingDate),
        amount: Number(m.amount) / 100 * (m.amountSign === '-' ? -1 : 1),
        availableAmount: Number(m.availableAmount) / 100 * (m.availableAmountSign === '-' ? -1 : 1)
      });
    }
  });
  return {
    header: headerInfo,
    entries: entries,
    balances: balances
  };
}

function stringToDateString(str) {
  if (str === '000000') return '0000-00-00';
  var parts = str.match(/.{1,2}/g);
  return '20' + parts[0] + '-' + parts[1] + '-' + parts[2];
}
<commit_msg>Align<commit_after>"use strict";
module.exports = parseTito;

var XRegExp = require('xregexp');

var basicInfoRe = new XRegExp('^T00' +
                              '(?<infoLength>                     .     {3}  )' +
                              '(?<version>                        .     {3}  )' +
                              '(?<bban>                           .     {14} )' +
                              '(?<statementNumber>                [0-9] {3}  )' +
                              '(?<startDate>                      [0-9] {6}  )' +
                              '(?<endDate>                        [0-9] {6}  )' +
                              '(?<creationDate>                   [0-9] {6}  )' +
                              '(?<creationTime>                   [0-9] {4}  )' +
                              '(?<contractId>                     .     {17} )' +
                              '(?<devnull>                        .     {31} )' +
                              '(?<currency>                       .     {3}  )' +
                              '(?<accountName>                    .     {30} )' +
                              '(?<devnull2>                       .     {18} )' +
                              '(?<accountOwnerName>               .     {35} )' +
                              '(?<bankContactInformation>         .     {40} )' +
                              '(?<bankContactInformationDetails>  .     {40} )' +
                              '(?<devnull3>                       .     {30} )' +
                              '(?<iban>                           .     {18} ) \\ ' +
                              '(?<bic>                            .     {8}  )', 'x');

var entryInfoRe = new XRegExp('^T10' +
                              '(?<infoLength>         .     {3}  )' +
                              '(?<entryNumber>        [0-9] {6}  )' +
                              '(?<archiveId>          .     {18} )' +
                              '(?<bookingDate>        [0-9] {6}  )' +
                              '(?<valueDate>          [0-9] {6}  )' +
                              '(?<paymentDate>        [0-9] {6}  ) (.) ' +
                              '(?<bookingInformation> .     {38} )' +
                              '(?<sign>               .     {1}  )' +
                              '(?<amount>             [0-9] {18} )' +
                              '(?<devnull>            .     {2}  )' +
                              '(?<receiver>           .     {35} ) (.)' +
                              '(?<receiverBban>       .     {14} ) (.)' +
                              '(?<referenceNumber>    .     {20} )', 'x');

var additionalEntryInfoRe = new XRegExp('^T11' +
                                        '(?<infoLength> [0-9] {3} )' +
                                        '(?<infoType>   .     {2} )', 'x');

var balanceRe = new XRegExp('^T40' +
                            '(?<infoLength>          .     {3}  )' +
                            '(?<bookingDate>         [0-9] {6}  )' +
                            '(?<amountSign>          .     {1}  )' +
                            '(?<amount>              [0-9] {18} )' +
                            '(?<availableAmountSign> .     {1}  )' +
                            '(?<availableAmount>     [0-9] {18} )', 'x');

function parseTito(txt) {
  var headerInfo,
      entries = [],
      balances = [];
  txt.split("\n").forEach(function(line) {
    line = line.replace(/\}/g, 'å')
               .replace(/{/g, 'ä')
               .replace(/\|/g, 'ö')
               .replace(/\]/g, 'Å')
               .replace(/\[/g, 'Ä')
               .replace(/\\/g, 'Ö');
    var m;
    if (basicInfoRe.test(line)) {
      m = XRegExp.exec(line, basicInfoRe);
      headerInfo = {
        accountName: m.accountName.trim(),
        accountOwnerName: m.accountOwnerName.trim(),
        bankContactInformation: m.bankContactInformation.trim(),
        bankContactInformationDetails: m.bankContactInformationDetails.trim(),
        bban: m.bban,
        bic: m.bic,
        contractId: m.contractId.trim(),
        creationDate: stringToDateString(m.creationDate),
        creationTime: m.creationTime.substring(0,2) + ':' + m.creationTime.substring(2, 4),
        currency: m.currency,
        endDate: stringToDateString(m.endDate),
        iban: m.iban,
        startDate: stringToDateString(m.startDate),
        statementNumber: m.statementNumber
      };
    } else if (entryInfoRe.test(line)) {
      m = XRegExp.exec(line, entryInfoRe);
      entries.push({
        additionalInformation: [],
        amount: Number(m.amount) / 100 * (m.sign === '-' ? -1 : 1),
        archiveId: m.archiveId.trim(),
        bookingDate: stringToDateString(m.bookingDate),
        bookingInformation: m.bookingInformation.trim(),
        paymentDate: stringToDateString(m.paymentDate),
        receiver: m.receiver.trim(),
        receiverBban: m.receiverBban.trim(),
        referenceNumber: m.referenceNumber.trim() ? parseInt(m.referenceNumber, 10) + '' : '',
        valueDate: stringToDateString(m.valueDate)
      });
    } else if (additionalEntryInfoRe.test(line)) {
      m = XRegExp.exec(line, additionalEntryInfoRe);
      var entry = entries[entries.length - 1];
      if (['00', '07', '06', '08'].indexOf(m.infoType) !== -1 ) {
        var totalLength = Number(m.infoLength), parts = [];
        for (var i = 8; i < totalLength; i=i+35) {
          parts.push(line.substring(i, i+35).trim());
        }
        entry.additionalInformation.push(parts.join(' '));
      }
    } else if (balanceRe.test(line)) {
      m = XRegExp.exec(line, balanceRe);
      balances.push({
        bookingDate: stringToDateString(m.bookingDate),
        amount: Number(m.amount) / 100 * (m.amountSign === '-' ? -1 : 1),
        availableAmount: Number(m.availableAmount) / 100 * (m.availableAmountSign === '-' ? -1 : 1)
      });
    }
  });
  return {
    header: headerInfo,
    entries: entries,
    balances: balances
  };
}

function stringToDateString(str) {
  if (str === '000000') return '0000-00-00';
  var parts = str.match(/.{1,2}/g);
  return '20' + parts[0] + '-' + parts[1] + '-' + parts[2];
}
<|endoftext|>


<commit_before>import { Ellipse, Morph, Text } from "./index.js"
import { Color, pt, rect } from "lively.graphics";
import { string, obj, arr, num } from "lively.lang";

export class HaloItem extends Ellipse {

  constructor(props) {
    super(Object.assign({
      fill: Color.gray.withA(.7),
      grabbable: false,
      extent: pt(24, 24)
    }, props));
  }

  get isHaloItem() { return true };

  alignInHalo() {
    const {x: width, y: height} = this.halo.extent,
          {row, col} = this.location,
          collWidth = (width + this.extent.x) / 3,
          rowHeight = height / 3;
    this.position = pt(collWidth * col, rowHeight * row).subPt(pt(26,26));
  }
}

export class Halo extends Morph {

  constructor(pointerId, target) {
    super({
      styleClasses: ["morph", "halo"],
      borderColor: Color.red,
      borderWidth: 2,
      fill: Color.transparent
    });
    this.state = {pointerId, target, draggedButton: null}
    this.initPropertyDisplay();
    this.initButtons();
  }

  get isHalo() { return true }

  get target() { return this.state.target; }

  morphsContainingPoint(list) { return list }

  refocus(newTarget) {
    var owner = this.owner;
    this.remove();
    this.state.target = newTarget;
    owner.addMorphAt(this, 0);
    this.alignWithTarget();
  }

  resizeHalo() {
    return this.getSubmorphNamed("resize") || this.addMorph(new HaloItem({
      name: "resize",
      styleClasses: ["halo-item", "fa", "fa-expand"],
      location: {col: 3, row: 3},
      rotation: -Math.PI / 2,
      origin: pt(12, 12),
      property: 'extent',
      halo: this,
      update: (delta) => {
        this.target.resizeBy(delta);
        this.alignWithTarget();
      },
      init() {
        this.halo.activeButton = this;
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      onDragStart(evt) { this.init() },
      onDrag(evt) { this.update(evt.state.dragDelta) },
      onDragEnd(evt) { this.stop() }
    }));
  }

  closeHalo() {
    return this.getSubmorphNamed("close") || this.addMorph(new HaloItem({
      name: "close",
      styleClasses: ["halo-item", "fa", "fa-close"],
      location: {col: 3, row: 0},
      draggable: false,
      halo: this,
      update: () => {
        this.remove();
        this.target.remove();
      },
      onMouseDown(evt) { this.update(); }
    }));
  }

  grabHalo() {
    return this.getSubmorphNamed("grab") || this.addMorph(new HaloItem({
      name: "grab",
      styleClasses: ["halo-item", "fa", "fa-hand-rock-o"],
      location: {col: 1, row: 0},
      halo: this,
      init: (hand) => {
        hand.grab(this.target);
      },
      update(hand) {
        hand.dropMorphsOn(this.morphBeneath(hand.position));
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.hand)
      },
      onDragEnd(evt) {
        this.update(evt.hand)
      }
    }));
  }

  dragHalo() {
    return this.getSubmorphNamed("drag") || this.addMorph(new HaloItem({
      name: "drag",
      styleClasses: ["halo-item", "fa", "fa-arrows"],
      property: 'position',
      location: {col: 2, row: 0},
      halo: this,
      init() {
        this.halo.activeButton = this;
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      update: (delta) => {
        this.target.globalPosition = this.target.globalPosition.addPt(delta);
        this.alignWithTarget();
      },
      onDragStart(evt) { this.init() },
      onDrag(evt) { this.update(evt.state.dragDelta); },
      onDragEnd(evt) { this.stop() }
    }));
  }

  inspectHalo() {
    return this.getSubmorphNamed("inspect") || this.addMorph(new HaloItem({
      name: "inspect",
      styleClasses: ["halo-item", "fa", "fa-search"],
      draggable: false,
      location: {col: 3, row: 2},
      halo: this,
      onMouseDown: (evt) => {
        this.target.inspect();
      }
    }));
  }

  editHalo() {
    return this.getSubmorphNamed("edit") || this.addMorph(new HaloItem({
      name: "edit",
      styleClasses: ["halo-item", "fa", "fa-pencil"],
      draggable: false,
      location: {col: 3, row: 1},
      halo: this,
      onMouseDown: (evt) => {
        this.target.edit();
      }
    }));
  }

  rotateHalo() {
    var angle = 0;
    return this.getSubmorphNamed("rotate") || this.addMorph(new HaloItem({
      name: "rotate",
      property: "rotation",
      styleClasses: ["halo-item", "fa", "fa-repeat"],
      location: {col: 0, row: 3},
      halo: this,
      init(angleToTarget) {
        this.halo.activeButton = this;
        angle = angleToTarget;
      },
      update: (angleToTarget) => {
        this.target.rotateBy(angleToTarget - angle);
        angle = angleToTarget;
        this.alignWithTarget();
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.position.subPt(this.halo.target.globalPosition).theta());
      },
      onDrag(evt) {
        this.update(evt.position.subPt(this.halo.target.globalPosition).theta());
      },
      onDragEnd(evt) {
        this.stop();
      }
    }));
  }

  copyHalo() {
    return this.getSubmorphNamed("copy") || this.addMorph(new HaloItem({
      name: "copy",
      styleClasses: ["halo-item", "fa", "fa-clone"],
      location: {col: 0, row: 1},
      halo: this,
      init: (hand) => {
        var pos = this.globalPosition,
            copy = this.target.copy();
        hand.grab(copy);
        copy.globalPosition = pos;
        this.refocus(copy);
      },
      update(hand) {
        hand.dropMorphsOn(this.morphBeneath(hand.position));
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.hand)
      },
      onDragEnd(evt) {
        this.update(evt.hand);
      }
    }));
  }

  originHalo() {
    return this.getSubmorphNamed("origin") || this.addMorph(new HaloItem({
      name: "origin", fill: Color.red,
      opacity: 0.9, borderColor: Color.black,
      borderWidth: 2,
      position: this.target.origin.subPt(pt(7.5,7.5)),
      extent: pt(15,15),
      halo: this,
      computePositionAtTarget: () => {
          var world = this.target.world(),
              origin = world.localizePointFrom(
                                this.target.position,
                                this.target.owner)
                            .addPt(this.target.origin);
          const {x,y} = this.target.globalBounds();
          return origin.subPt(pt(x,y)).subPt(pt(7.5,7.5));
      },
      alignInHalo() {
        this.position = this.computePositionAtTarget();
      },
      update: (delta) => {
        this.target.adjustOrigin(this.target.origin.addPt(delta));
        this.alignWithTarget();
      },
      onDrag(evt) { this.update(evt.state.dragDelta); }
    }));;
  }

  stylizeHalo() {
    return this.getSubmorphNamed("style") || this.addMorph(new HaloItem({
      name: "style",
      styleClasses: ["halo-item", "fa", "fa-picture-o"],
      location: {col: 0, row: 2},
      halo: this,
      onMouseDown: (evt) => {
        // stylize
      }
    }));
  }

  initButtons() {
    this.addMorph(this.originHalo());
    this.buttonControls = [
      this.resizeHalo(),
      this.closeHalo(),
      this.dragHalo(),
      this.grabHalo(),
      // this.inspectHalo(),
      // this.editHalo(),
      this.copyHalo(),
      this.rotateHalo(),
      // this.stylizeHalo()
    ];
  }

  initPropertyDisplay() {
    const textField = new Text({
      allowsInput: false,
      position: pt(3,3),
      extent: pt(90, 14),
      fill: Color.red.withA(0),
      fontSize: 12,
      isHaloItem: true
    });
    this.propertyDisplay = this.propertyDisplay || this.addMorph(
      new Morph({
        fill: Color.lightGray.withA(0.5),
        borderRadius: 15,
        extent: pt(100, 20),
        position: pt(0,-22),
        visible: false,
        halo: this,
        isHaloItem: true,
        displayProperty(property) {
          this.visible = true;
          textField.visible = true;
          textField.textString = this.halo.target.getProperty(property).toString();
        },
        disable() {
          this.visible = false;
          textField.visible = false;
        },
        submorphs: [textField]
      }));
  }

  alignWithTarget() {
    const {x, y, width, height} = this.target.globalBounds();
    const origin = this.target.origin;
    this.position = pt(x,y);
    this.extent = pt(width, height);
    this.propertyDisplay.disable();
    this.buttonControls.forEach((button) => {
      if (this.activeButton) {
        if (this.activeButton == button){
          button.visible = true;
          this.propertyDisplay.displayProperty(button.property);
        } else {
          button.visible = false;
        }
      } else {
        button.visible = true;
      }
        button.alignInHalo()});
    this.originHalo().alignInHalo();
    return this;
  }

}
<commit_msg>origin halo applies global delta<commit_after>import { Ellipse, Morph, Text } from "./index.js"
import { Color, pt, rect } from "lively.graphics";
import { string, obj, arr, num } from "lively.lang";

export class HaloItem extends Ellipse {

  constructor(props) {
    super(Object.assign({
      fill: Color.gray.withA(.7),
      grabbable: false,
      extent: pt(24, 24)
    }, props));
  }

  get isHaloItem() { return true };

  alignInHalo() {
    const {x: width, y: height} = this.halo.extent,
          {row, col} = this.location,
          collWidth = (width + this.extent.x) / 3,
          rowHeight = height / 3;
    this.position = pt(collWidth * col, rowHeight * row).subPt(pt(26,26));
  }
}

export class Halo extends Morph {

  constructor(pointerId, target) {
    super({
      styleClasses: ["morph", "halo"],
      borderColor: Color.red,
      borderWidth: 2,
      fill: Color.transparent
    });
    this.state = {pointerId, target, draggedButton: null}
    this.initPropertyDisplay();
    this.initButtons();
  }

  get isHalo() { return true }

  get target() { return this.state.target; }

  morphsContainingPoint(list) { return list }

  refocus(newTarget) {
    var owner = this.owner;
    this.remove();
    this.state.target = newTarget;
    owner.addMorphAt(this, 0);
    this.alignWithTarget();
  }

  resizeHalo() {
    return this.getSubmorphNamed("resize") || this.addMorph(new HaloItem({
      name: "resize",
      styleClasses: ["halo-item", "fa", "fa-expand"],
      location: {col: 3, row: 3},
      rotation: -Math.PI / 2,
      origin: pt(12, 12),
      property: 'extent',
      halo: this,
      update: (delta) => {
        this.target.resizeBy(delta);
        this.alignWithTarget();
      },
      init() {
        this.halo.activeButton = this;
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      onDragStart(evt) { this.init() },
      onDrag(evt) { this.update(evt.state.dragDelta) },
      onDragEnd(evt) { this.stop() }
    }));
  }

  closeHalo() {
    return this.getSubmorphNamed("close") || this.addMorph(new HaloItem({
      name: "close",
      styleClasses: ["halo-item", "fa", "fa-close"],
      location: {col: 3, row: 0},
      draggable: false,
      halo: this,
      update: () => {
        this.remove();
        this.target.remove();
      },
      onMouseDown(evt) { this.update(); }
    }));
  }

  grabHalo() {
    return this.getSubmorphNamed("grab") || this.addMorph(new HaloItem({
      name: "grab",
      styleClasses: ["halo-item", "fa", "fa-hand-rock-o"],
      location: {col: 1, row: 0},
      halo: this,
      init: (hand) => {
        hand.grab(this.target);
      },
      update(hand) {
        hand.dropMorphsOn(this.morphBeneath(hand.position));
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.hand)
      },
      onDragEnd(evt) {
        this.update(evt.hand)
      }
    }));
  }

  dragHalo() {
    return this.getSubmorphNamed("drag") || this.addMorph(new HaloItem({
      name: "drag",
      styleClasses: ["halo-item", "fa", "fa-arrows"],
      property: 'position',
      location: {col: 2, row: 0},
      halo: this,
      init() {
        this.halo.activeButton = this;
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      update: (delta) => {
        this.target.globalPosition = this.target.globalPosition.addPt(delta);
        this.alignWithTarget();
      },
      onDragStart(evt) { this.init() },
      onDrag(evt) { this.update(evt.state.dragDelta); },
      onDragEnd(evt) { this.stop() }
    }));
  }

  inspectHalo() {
    return this.getSubmorphNamed("inspect") || this.addMorph(new HaloItem({
      name: "inspect",
      styleClasses: ["halo-item", "fa", "fa-search"],
      draggable: false,
      location: {col: 3, row: 2},
      halo: this,
      onMouseDown: (evt) => {
        this.target.inspect();
      }
    }));
  }

  editHalo() {
    return this.getSubmorphNamed("edit") || this.addMorph(new HaloItem({
      name: "edit",
      styleClasses: ["halo-item", "fa", "fa-pencil"],
      draggable: false,
      location: {col: 3, row: 1},
      halo: this,
      onMouseDown: (evt) => {
        this.target.edit();
      }
    }));
  }

  rotateHalo() {
    var angle = 0;
    return this.getSubmorphNamed("rotate") || this.addMorph(new HaloItem({
      name: "rotate",
      property: "rotation",
      styleClasses: ["halo-item", "fa", "fa-repeat"],
      location: {col: 0, row: 3},
      halo: this,
      init(angleToTarget) {
        this.halo.activeButton = this;
        angle = angleToTarget;
      },
      update: (angleToTarget) => {
        this.target.rotateBy(angleToTarget - angle);
        angle = angleToTarget;
        this.alignWithTarget();
      },
      stop() {
        this.halo.activeButton = null;
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.position.subPt(this.halo.target.globalPosition).theta());
      },
      onDrag(evt) {
        this.update(evt.position.subPt(this.halo.target.globalPosition).theta());
      },
      onDragEnd(evt) {
        this.stop();
      }
    }));
  }

  copyHalo() {
    return this.getSubmorphNamed("copy") || this.addMorph(new HaloItem({
      name: "copy",
      styleClasses: ["halo-item", "fa", "fa-clone"],
      location: {col: 0, row: 1},
      halo: this,
      init: (hand) => {
        var pos = this.globalPosition,
            copy = this.target.copy();
        hand.grab(copy);
        copy.globalPosition = pos;
        this.refocus(copy);
      },
      update(hand) {
        hand.dropMorphsOn(this.morphBeneath(hand.position));
        this.halo.alignWithTarget();
      },
      onDragStart(evt) {
        this.init(evt.hand)
      },
      onDragEnd(evt) {
        this.update(evt.hand);
      }
    }));
  }

  originHalo() {
    return this.getSubmorphNamed("origin") || this.addMorph(new HaloItem({
      name: "origin", fill: Color.red,
      opacity: 0.9, borderColor: Color.black,
      borderWidth: 2,
      position: this.target.origin.subPt(pt(7.5,7.5)),
      extent: pt(15,15),
      halo: this,
      computePositionAtTarget: () => {
          var world = this.target.world(),
              origin = world.localizePointFrom(
                                this.target.position,
                                this.target.owner)
                            .addPt(this.target.origin);
          const {x,y} = this.target.globalBounds();
          return origin.subPt(pt(x,y)).subPt(pt(7.5,7.5));
      },
      alignInHalo() {
        this.position = this.computePositionAtTarget();
      },
      update: (delta) => {
        var oldOrigin = this.target.origin,
            globalOrigin = this.target.worldPoint(oldOrigin),
            newOrigin = this.target.localize(globalOrigin.addPt(delta));
        delta = newOrigin.subPt(oldOrigin);
        this.target.adjustOrigin(this.target.origin.addPt(delta));
        this.alignWithTarget();
      },
      onDrag(evt) { this.update(evt.state.dragDelta); }
    }));;
  }

  stylizeHalo() {
    return this.getSubmorphNamed("style") || this.addMorph(new HaloItem({
      name: "style",
      styleClasses: ["halo-item", "fa", "fa-picture-o"],
      location: {col: 0, row: 2},
      halo: this,
      onMouseDown: (evt) => {
        // stylize
      }
    }));
  }

  initButtons() {
    this.addMorph(this.originHalo());
    this.buttonControls = [
      this.resizeHalo(),
      this.closeHalo(),
      this.dragHalo(),
      this.grabHalo(),
      // this.inspectHalo(),
      // this.editHalo(),
      this.copyHalo(),
      this.rotateHalo(),
      // this.stylizeHalo()
    ];
  }

  initPropertyDisplay() {
    const textField = new Text({
      allowsInput: false,
      position: pt(3,3),
      extent: pt(90, 14),
      fill: Color.red.withA(0),
      fontSize: 12,
      isHaloItem: true
    });
    this.propertyDisplay = this.propertyDisplay || this.addMorph(
      new Morph({
        fill: Color.lightGray.withA(0.5),
        borderRadius: 15,
        extent: pt(100, 20),
        position: pt(0,-22),
        visible: false,
        halo: this,
        isHaloItem: true,
        displayProperty(property) {
          this.visible = true;
          textField.visible = true;
          textField.textString = this.halo.target.getProperty(property).toString();
        },
        disable() {
          this.visible = false;
          textField.visible = false;
        },
        submorphs: [textField]
      }));
  }

  alignWithTarget() {
    const {x, y, width, height} = this.target.globalBounds();
    const origin = this.target.origin;
    this.position = pt(x,y);
    this.extent = pt(width, height);
    this.propertyDisplay.disable();
    this.buttonControls.forEach((button) => {
      if (this.activeButton) {
        if (this.activeButton == button){
          button.visible = true;
          this.propertyDisplay.displayProperty(button.property);
        } else {
          button.visible = false;
        }
      } else {
        button.visible = true;
      }
        button.alignInHalo()});
    this.originHalo().alignInHalo();
    return this;
  }

}
<|endoftext|>


<commit_before>/**
 * Heir v1.0.0 - http://git.io/F87mKg
 * Oliver Caldwell
 * MIT license
 */

;(function(root) {
	// JSHint config - http://www.jshint.com/
	/*jshint laxcomma:true*/
	/*global define:true*/

	// Place the script into strict mode
	'use strict';

	/**
	 * Works out if a variable is a true object (created with {} etc) and not an array or anything else that usually shows up as an object.
	 *
	 * @param {Mixed} chk The variable to check to see if it is an object. It must be a pure object, not even a prototype.
	 * @return {Boolean} True if it is a true object, false if it is anything else.
	 */
	function isObject(chk) {
		return (chk && Object.prototype.toString.call(chk) === '[object Object]') === true;
	}

	/**
	 * Recursively merges two objects. Object `a` will be overridden by the values in object `b`.
	 * Please run the values through a cloning function first, this function does not try to clone them for you.
	 * The base object will be edited directly, please be careful!
	 *
	 * @param {Object} a The base object to merge into.
	 * @param {Object} b The object to merge down into object `a`.
	 * @return {Object} This is object `a` but merged with `b`.
	 */
	function merge(a, b) {
		// Loop over all values in b. If they are not found in a then set them
		// If both values are objects then recursively merge them
		for(var key in b) {
			// Make sure the value is not in __proto__ or something like that
			if(b.hasOwnProperty(key)) {
				// If they are both objects then merge recursively
				if(isObject(a[key]) && isObject(b[key])) {
					merge(a[key], b[key]);
				}

				// Otherwise just replace the base value
				else {
					a[key] = b[key];
				}
			}
		}

		// Return the merged object
		return a;
	}

	/**
	 * Returns a recursive clone of the passed object.
	 * So when you edit the original the clone will not change.
	 * Used in prototypical inheritance.
	 * It will not clone arrays.
	 *
	 * @param {Object} orig The original object to clone.
	 * @return {Object} The cloned version of orig that can be edited without changing the original.
	 */
	function clone(orig) {
		// Initialise variables
		var cl = {}
		  , key;

		// Loop over all values in the object
		// If the value is an object then clone recursively
		// Otherwise just copy the value
		for(key in orig) {
			if(orig.hasOwnProperty(key)) {
				cl[key] = isObject(orig[key]) ? clone(orig[key]) : orig[key];
			}
		}

		// Return the clone
		return cl;
	}

	/**
	 * Inherits other functions prototype objects into the current function.
	 *
	 * @param {Function|Function[]} parent A function which should have it's prototype cloned and placed into the current functions prototype. If you pass an array of functions they will all be inherited from.
	 * @param {Function} [forceFn] Optional function to use as the current function which is inheriting the other prototypes. It will default to `this`.
	 * @return {Function} The current function to allow chaining.
	 */
	function inherit(parent, forceFn) {
		// Initialise variables
		var fn = forceFn || this
		  , i;

		// If the parent variable is not a function then it must be an array
		// So we have to loop over it and inherit each of them
		// Remember to pass the current function instance!
		if(typeof parent !== 'function') {
			i = parent.length;
			while(i--) {
				inherit(parent[i], fn);
			}
		}
		else {
			// It is not an array, it is a plain function
			// Merge it's prototype into this one
			merge(fn.prototype, clone(parent.prototype));
		}

		// Return the current function to allow chaining
		return fn;
	}

	// Expose the inherit function by placing it in the Function prototype
	Function.prototype.inherit = inherit;

	// Create a nice little namespace to expose
	var ns = {
		isObject: isObject,
		merge: merge,
		clone: clone,
		inherit: inherit
	};

	// And expose everything else either via AMD or a global object
	if(typeof define === 'function' && define.amd) {
		define(function() {
			return ns;
		});
	}
	else if (typeof module === 'object') {
		module.exports = ns;
	}
	else {
		root.heir = ns;
	}
}(this));<commit_msg>Converted a few more bits to my new linting.<commit_after>/**
 * Heir v1.0.0 - http://git.io/F87mKg
 * Oliver Caldwell
 * MIT license
 */

;(function () {
	// JSHint config - http://www.jshint.com/
	/*jshint laxcomma:true*/
	/*global define:true*/

	// Place the script into strict mode
	'use strict';

	/**
	 * Works out if a variable is a true object (created with {} etc) and not an array or anything else that usually shows up as an object.
	 *
	 * @param {Mixed} chk The variable to check to see if it is an object. It must be a pure object, not even a prototype.
	 * @return {Boolean} True if it is a true object, false if it is anything else.
	 */
	function isObject(chk) {
		return (chk && Object.prototype.toString.call(chk) === '[object Object]') === true;
	}

	/**
	 * Recursively merges two objects. Object `a` will be overridden by the values in object `b`.
	 * Please run the values through a cloning function first, this function does not try to clone them for you.
	 * The base object will be edited directly, please be careful!
	 *
	 * @param {Object} a The base object to merge into.
	 * @param {Object} b The object to merge down into object `a`.
	 * @return {Object} This is object `a` but merged with `b`.
	 */
	function merge(a, b) {
		// Loop over all values in b. If they are not found in a then set them
		// If both values are objects then recursively merge them
		for (var key in b) {
			// Make sure the value is not in __proto__ or something like that
			if (b.hasOwnProperty(key)) {
				// If they are both objects then merge recursively
				if (isObject(a[key]) && isObject(b[key])) {
					merge(a[key], b[key]);
				}

				// Otherwise just replace the base value
				else {
					a[key] = b[key];
				}
			}
		}

		// Return the merged object
		return a;
	}

	/**
	 * Returns a recursive clone of the passed object.
	 * So when you edit the original the clone will not change.
	 * Used in prototypical inheritance.
	 * It will not clone arrays.
	 *
	 * @param {Object} orig The original object to clone.
	 * @return {Object} The cloned version of orig that can be edited without changing the original.
	 */
	function clone(orig) {
		// Initialise variables
		var cl = {};
		var key;

		// Loop over all values in the object
		// If the value is an object then clone recursively
		// Otherwise just copy the value
		for (key in orig) {
			if (orig.hasOwnProperty(key)) {
				cl[key] = isObject(orig[key]) ? clone(orig[key]) : orig[key];
			}
		}

		// Return the clone
		return cl;
	}

	/**
	 * Inherits other functions prototype objects into the current function.
	 *
	 * @param {Function|Function[]} parent A function which should have it's prototype cloned and placed into the current functions prototype. If you pass an array of functions they will all be inherited from.
	 * @param {Function} [forceFn] Optional function to use as the current function which is inheriting the other prototypes. It will default to `this`.
	 * @return {Function} The current function to allow chaining.
	 */
	function inherit(parent, forceFn) {
		// Initialise variables
		var fn = forceFn || this;
		var i;

		// If the parent variable is not a function then it must be an array
		// So we have to loop over it and inherit each of them
		// Remember to pass the current function instance!
		if (typeof parent !== 'function') {
			i = parent.length;
			while (i--) {
				inherit(parent[i], fn);
			}
		}
		else {
			// It is not an array, it is a plain function
			// Merge it's prototype into this one
			merge(fn.prototype, clone(parent.prototype));
		}

		// Return the current function to allow chaining
		return fn;
	}

	// Expose the inherit function by placing it in the Function prototype
	Function.prototype.inherit = inherit;

	// Create a nice little namespace to expose
	var ns = {
		isObject: isObject,
		merge: merge,
		clone: clone,
		inherit: inherit
	};

	// And expose everything else either via AMD or a global object
	if (typeof define === 'function' && define.amd) {
		define(function () {
			return ns;
		});
	}
	else if (typeof module === 'object' && module.exports) {
		module.exports = ns;
	}
	else {
		this.heir = ns;
	}
}.call(this));<|endoftext|>


<commit_before>import React from 'react';
import Helmet from 'react-helmet';
import { Analytics } from './components/';

const BUILD_TIME = new Date().getTime();

export default React.createClass({
  render() {
    const head = Helmet.rewind();
    const attrs = head.htmlAttributes.toComponent();

    let css;
    if (process.env.NODE_ENV !== 'development') {
      css = <style dangerouslySetInnerHTML={{ __html: require('!raw!./public/styles.css') }} />;
    }

    return (
      <html
        lang="en"
        {...attrs}
      >
        <head>
          <meta charSet="utf-8" />
          <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
          <meta httpEquiv="Cache-Control" content="private" />
          {head.title.toComponent()}
          {head.meta.toComponent()}
          {css}
          <link rel="preload" href={require('./components/Modals/images/close.svg')} as="image" />
          <link rel="preload" href={require('./components/Modals/images/close-small.svg')} as="image" />
          <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,400italic,500,700" />
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/plugins/line-numbers/prism-line-numbers.min.css" />
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-twilight.min.css" />
          <link rel="apple-touch-icon" sizes="57x57" href={require('./images/favicons/apple-touch-icon-57x57.png')} />
          <link rel="apple-touch-icon" sizes="60x60" href={require('./images/favicons/apple-touch-icon-60x60.png')} />
          <link rel="apple-touch-icon" sizes="72x72" href={require('./images/favicons/apple-touch-icon-72x72.png')} />
          <link rel="apple-touch-icon" sizes="76x76" href={require('./images/favicons/apple-touch-icon-76x76.png')} />
          <link rel="apple-touch-icon" sizes="114x114" href={require('./images/favicons/apple-touch-icon-114x114.png')} />
          <link rel="apple-touch-icon" sizes="120x120" href={require('./images/favicons/apple-touch-icon-120x120.png')} />
          <link rel="apple-touch-icon" sizes="144x144" href={require('./images/favicons/apple-touch-icon-144x144.png')} />
          <link rel="apple-touch-icon" sizes="152x152" href={require('./images/favicons/apple-touch-icon-152x152.png')} />
          <link rel="apple-touch-icon" sizes="180x180" href={require('./images/favicons/apple-touch-icon-180x180.png')} />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-32x32.png')} sizes="32x32" />
          <link rel="icon" type="image/png" href={require('./images/favicons/android-chrome-192x192.png')} sizes="192x192" />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-96x96.png')} sizes="96x96" />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-16x16.png')} sizes="16x16" />
          <link rel="manifest" href={require('!file-loader?name=/[hash].[ext]!./images/favicons/manifest.json')} />
          <link rel="mask-icon" href={require('./images/favicons/safari-pinned-tab.svg')} color="#0070D3" />
          <meta name="msapplication-TileColor" content="#0070D3" />
          <meta name="msapplication-TileImage" content={require('./images/favicons/mstile-144x144.png')} />
          <meta name="theme-color" content="#0070D3" />
          <meta name="msapplication-navbutton-color" content="#0070D3" />

          <meta property="og:site_name" content="Syncano" />
          <meta property="og:type" content="website" />

          <meta name="twitter:card" content="summary_large_image" />
          <meta name="twitter:site" content="@Syncano" />

          {head.link.toComponent()}
          <script src="https://cdn.optimizely.com/js/3962180131.js" />
          <script dangerouslySetInnerHTML={{ __html: `
            (function(h,o,t,j,a,r){
            h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
            h._hjSettings={hjid:108213,hjsv:5};
            a=o.getElementsByTagName('head')[0];
            r=o.createElement('script');r.async=1;
            r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
            a.appendChild(r);
            })(window,document,'//static.hotjar.com/c/hotjar-','.js?sv=');` }}
          />
        </head>
        <body>
          <div
            id="react-mount"
            dangerouslySetInnerHTML={{ __html: this.props.body }}
          />
          <Analytics writeKey={APP_CONFIG.analyticsKey} />
          <script src="https://cdn.jsdelivr.net/g/prism@1.5.1(prism.js+components/prism-bash.min.js+components/prism-clike.min.js+components/prism-c.min.js+components/prism-objectivec.min.js+components/prism-java.min.js+components/prism-javascript.min.js+components/prism-swift.min.js+components/prism-cpp.min.js+components/prism-python.min.js+components/prism-ruby.min.js+plugins/line-numbers/prism-line-numbers.min.js)" />
          <script src={`/bundle.js?t=${BUILD_TIME}`} />
        </body>
      </html>
    );
  }
});
<commit_msg>[WEB-567] Fix broken links on website<commit_after>import React from 'react';
import Helmet from 'react-helmet';
import { Analytics } from './components/';

const BUILD_TIME = new Date().getTime();

export default React.createClass({
  render() {
    const head = Helmet.rewind();
    const attrs = head.htmlAttributes.toComponent();

    let css;
    if (process.env.NODE_ENV !== 'development') {
      css = <style dangerouslySetInnerHTML={{ __html: require('!raw!./public/styles.css') }} />;
    }

    return (
      <html
        lang="en"
        {...attrs}
      >
        <head>
          <meta charSet="utf-8" />
          <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
          <meta httpEquiv="Cache-Control" content="private" />
          {head.title.toComponent()}
          {head.meta.toComponent()}
          {css}
          <link rel="preload" href={require('./components/Modals/images/close.svg')} as="image" />
          <link rel="preload" href={require('./components/Modals/images/close-small.svg')} as="image" />
          <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:400,400italic,500,700" />
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/plugins/line-numbers/prism-line-numbers.min.css" />
          <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.4.1/themes/prism-twilight.min.css" />
          <link rel="apple-touch-icon" sizes="57x57" href={require('./images/favicons/apple-touch-icon-57x57.png')} />
          <link rel="apple-touch-icon" sizes="60x60" href={require('./images/favicons/apple-touch-icon-60x60.png')} />
          <link rel="apple-touch-icon" sizes="72x72" href={require('./images/favicons/apple-touch-icon-72x72.png')} />
          <link rel="apple-touch-icon" sizes="76x76" href={require('./images/favicons/apple-touch-icon-76x76.png')} />
          <link rel="apple-touch-icon" sizes="114x114" href={require('./images/favicons/apple-touch-icon-114x114.png')} />
          <link rel="apple-touch-icon" sizes="120x120" href={require('./images/favicons/apple-touch-icon-120x120.png')} />
          <link rel="apple-touch-icon" sizes="144x144" href={require('./images/favicons/apple-touch-icon-144x144.png')} />
          <link rel="apple-touch-icon" sizes="152x152" href={require('./images/favicons/apple-touch-icon-152x152.png')} />
          <link rel="apple-touch-icon" sizes="180x180" href={require('./images/favicons/apple-touch-icon-180x180.png')} />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-32x32.png')} sizes="32x32" />
          <link rel="icon" type="image/png" href={require('./images/favicons/android-chrome-192x192.png')} sizes="192x192" />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-96x96.png')} sizes="96x96" />
          <link rel="icon" type="image/png" href={require('./images/favicons/favicon-16x16.png')} sizes="16x16" />
          <link rel="manifest" href={require('!file-loader?name=[hash].[ext]!./images/favicons/manifest.json')} />
          <link rel="mask-icon" href={require('./images/favicons/safari-pinned-tab.svg')} color="#0070D3" />
          <meta name="msapplication-TileColor" content="#0070D3" />
          <meta name="msapplication-TileImage" content={require('./images/favicons/mstile-144x144.png')} />
          <meta name="theme-color" content="#0070D3" />
          <meta name="msapplication-navbutton-color" content="#0070D3" />

          <meta property="og:site_name" content="Syncano" />
          <meta property="og:type" content="website" />

          <meta name="twitter:card" content="summary_large_image" />
          <meta name="twitter:site" content="@Syncano" />

          {head.link.toComponent()}
          <script src="https://cdn.optimizely.com/js/3962180131.js" />
          <script dangerouslySetInnerHTML={{ __html: `
            (function(h,o,t,j,a,r){
            h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
            h._hjSettings={hjid:108213,hjsv:5};
            a=o.getElementsByTagName('head')[0];
            r=o.createElement('script');r.async=1;
            r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
            a.appendChild(r);
            })(window,document,'//static.hotjar.com/c/hotjar-','.js?sv=');` }}
          />
        </head>
        <body>
          <div
            id="react-mount"
            dangerouslySetInnerHTML={{ __html: this.props.body }}
          />
          <Analytics writeKey={APP_CONFIG.analyticsKey} />
          <script src="https://cdn.jsdelivr.net/g/prism@1.5.1(prism.js+components/prism-bash.min.js+components/prism-clike.min.js+components/prism-c.min.js+components/prism-objectivec.min.js+components/prism-java.min.js+components/prism-javascript.min.js+components/prism-swift.min.js+components/prism-cpp.min.js+components/prism-python.min.js+components/prism-ruby.min.js+plugins/line-numbers/prism-line-numbers.min.js)" />
          <script src={`/bundle.js?t=${BUILD_TIME}`} />
        </body>
      </html>
    );
  }
});
<|endoftext|>


<commit_before>/**
 * @author      Created by Marcus Spiegel <marcus.spiegel@gmail.com> on 2011-03-25.
 * @link        https://github.com/mashpie/i18n-node
 * @license     http://opensource.org/licenses/MIT
 *
 * @version     0.3.9
 */

// dependencies and "private" vars
var vsprintf = require('sprintf').vsprintf,
    fs = require('fs'),
    url = require('url'),
    path = require('path'),
    debug = require('debug')('i18n:debug'),
    warn = require('debug')('i18n:warn'),
    error = require('debug')('i18n:error'),
    locales = {},
    defaultLocale, updateFiles, cookiename, debug, extension, directory;

// public exports
var i18n = exports;

i18n.version = '0.3.9';

i18n.configure = function i18nConfigure(opt) {

  // you may register helpers in global scope, up to you
  if (typeof opt.register === 'object') {
    opt.register.__ = i18n.__;
    opt.register.__n = i18n.__n;
    opt.register.getLocale = i18n.getLocale;
    opt.register.setLocale = i18n.setLocale;
  }

  // sets a custom cookie name to parse locale settings from
  cookiename = (typeof opt.cookie === 'string') ? opt.cookie : null;

  // where to store json files
  directory = (typeof opt.directory === 'string') ? opt.directory : __dirname + path.sep + 'locales';

  // write new locale information to disk
  updateFiles = (typeof opt.updateFiles === 'boolean') ? opt.updateFiles : true;

  // where to store json files
  extension = (typeof opt.extension === 'string') ? opt.extension : '.json';

  // setting defaultLocale
  defaultLocale = (typeof opt.defaultLocale === 'string') ? opt.defaultLocale : 'en';

  // implicitly read all locales
  if (typeof opt.locales === 'object') {
    opt.locales.forEach(function (l) {
      read(l);
    });
  }
};

i18n.init = function i18nInit(request, response, next) {
  if (typeof request === 'object') {
    guessLanguage(request);
  }
  if (typeof next === 'function') {
    next();
  }
};

i18n.__ = function i18nTranslate(phrase) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), phrase);

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 1) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
  }
  return msg;
};

i18n.__n = function i18nTranslatePlural(singular, plural, count) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), singular, plural);

  // parse translation and replace all digets '%d' by `count`
  // this also replaces extra strings '%%s' to parseble '%s' for next step
  // simplest 2 form implementation of plural, like https://developer.mozilla.org/en/docs/Localization_and_Plurals#Plural_rule_.231_.282_forms.29
  if (parseInt(count, 10) > 1) {
    msg = vsprintf(msg.other, [count]);
  } else {
    msg = vsprintf(msg.one, [count]);
  }

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 3) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
  }

  return msg;
};

i18n.setLocale = function i18nSetLocale(locale_or_request, locale) {
  var target_locale = locale_or_request,
      request;
  // called like setLocale(req, 'en')
  if (locale_or_request && typeof locale === 'string' && locales[locale]) {
    request = locale_or_request;
    target_locale = locale;
  }
  // called like req.setLocale('en')
  if (locale === undefined && typeof this.locale === 'string' && typeof locale_or_request === 'string') {
    request = this;
    target_locale = locale_or_request;
  }
  if (locales[target_locale]) {
    // called like setLocale('en')
    if (request === undefined) {
      defaultLocale = target_locale;
    }
    else {
      request.locale = target_locale;
    }
  }
  return i18n.getLocale(request);
};

i18n.getLocale = function i18nGetLocale(request) {
  // called like getLocale(req)
  if (request && request.locale) {
    return request.locale;
  }
  // called like req.getLocale()
  if (request === undefined && typeof this.locale === 'string') {
    return this.locale;
  }
  // called like getLocale()
  return defaultLocale;
};

i18n.overrideLocaleFromQuery = function (req) {
  if (req === null) {
    return;
  }
  var urlObj = url.parse(req.url, true);
  if (urlObj.query.locale) {
    logDebug("Overriding locale from query: " + urlObj.query.locale);
    i18n.setLocale(req, urlObj.query.locale.toLowerCase());
  }
};

// ===================
// = private methods =
// ===================
/**
 * guess language setting based on http headers
 */

function guessLanguage(request) {
  if (typeof request === 'object') {
    var language_header = request.headers['accept-language'],
        languages = [],
        regions = [];

    request.languages = [defaultLocale];
    request.regions = [defaultLocale];
    request.language = defaultLocale;
    request.region = defaultLocale;

    if (language_header) {
      language_header.split(',').forEach(function (l) {
        var header = l.split(';', 1)[0],
            lr = header.split('-', 2);
        if (lr[0]) {
          languages.push(lr[0].toLowerCase());
        }
        if (lr[1]) {
          regions.push(lr[1].toLowerCase());
        }
      });

      if (languages.length > 0) {
        request.languages = languages;
        request.language = languages[0];
      }

      if (regions.length > 0) {
        request.regions = regions;
        request.region = regions[0];
      }
    }

    // setting the language by cookie
    if (cookiename && request.cookies && request.cookies[cookiename]) {
      request.language = request.cookies[cookiename];
    }

    i18n.setLocale(request, request.language);
  }
}

/**
 * searches for locale in given object
 */

function getLocaleFromObject(obj) {
  var locale;
  if (obj && obj.scope) {
    locale = obj.scope.locale;
  }
  if (obj && obj.locale) {
    locale = obj.locale;
  }
  return locale;
}

/**
 * read locale file, translate a msg and write to fs if new
 */

function translate(locale, singular, plural) {
  if (locale === undefined) {
    logWarn("WARN: No locale found - check the context of the call to __(). Using " + defaultLocale + " as current locale");
    locale = defaultLocale;
  }

  if (!locales[locale]) {
    read(locale);
  }

  if (plural) {
    if (!locales[locale][singular]) {
      locales[locale][singular] = {
        'one': singular,
        'other': plural
      };
      write(locale);
    }
  }

  if (!locales[locale][singular]) {
    locales[locale][singular] = singular;
    write(locale);
  }
  return locales[locale][singular];
}

/**
 * try reading a file
 */

function read(locale) {
  var localeFile = {},
      file = getStorageFilePath(locale);
  try {
    logDebug('read ' + file + ' for locale: ' + locale);
    localeFile = fs.readFileSync(file);
    try {
      // parsing filecontents to locales[locale]
      locales[locale] = JSON.parse(localeFile);
    } catch (parseError) {
      logError('unable to parse locales from file (maybe ' + file + ' is empty or invalid json?): ', e);
    }
  } catch (readError) {
    // unable to read, so intialize that file
    // locales[locale] are already set in memory, so no extra read required
    // or locales[locale] are empty, which initializes an empty locale.json file
    logDebug('initializing ' + file);
    write(locale);
  }
}

/**
 * try writing a file in a created directory
 */

function write(locale) {
  var stats, target, tmp;

  // don't write new locale information to disk if updateFiles isn't true
  if (!updateFiles) {
    return;
  }

  // creating directory if necessary
  try {
    stats = fs.lstatSync(directory);
  } catch (e) {
    logDebug('creating locales dir in: ' + directory);
    fs.mkdirSync(directory, parseInt('755', 8));
  }

  // first time init has an empty file
  if (!locales[locale]) {
    locales[locale] = {};
  }

  // writing to tmp and rename on success
  try {
    target = getStorageFilePath(locale);
    tmp = target + ".tmp";
    fs.writeFileSync(tmp, JSON.stringify(locales[locale], null, "\t"), "utf8");
    stats = fs.statSync(tmp);
    if (stats.isFile()) {
      fs.renameSync(tmp, target);
    } else {
      logError('unable to write locales to file (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
    }
  } catch (e) {
    logError('unexpected error writing files (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
  }
}

/**
 * basic normalization of filepath
 */

function getStorageFilePath(locale) {
  // changed API to use .json as default, #16
  var ext = extension || '.json',
      filepath = path.normalize(directory + path.sep + locale + ext),
      filepathJS = path.normalize(directory + path.sep + locale + '.js');
  // use .js as fallback if already existing
  try {
    if (fs.statSync(filepathJS)) {
      logDebug('using existing file ' + filepathJS);
      extension = '.js';
      return filepathJS;
    }
  } catch (e) {
    logDebug('will write to ' + filepath);
  }
  return filepath;
}

/**
 * Logging proxies
 */

function logDebug(msg) {
  debug(msg);
}

function logWarn(msg) {
  warn(msg);
}

function logError(msg) {
  error(msg);
}
<commit_msg>quick patch (no win support) for missing path.sep in node < 0.8<commit_after>/**
 * @author      Created by Marcus Spiegel <marcus.spiegel@gmail.com> on 2011-03-25.
 * @link        https://github.com/mashpie/i18n-node
 * @license     http://opensource.org/licenses/MIT
 *
 * @version     0.3.9
 */

// dependencies and "private" vars
var vsprintf = require('sprintf').vsprintf,
    fs = require('fs'),
    url = require('url'),
    path = require('path'),
    debug = require('debug')('i18n:debug'),
    warn = require('debug')('i18n:warn'),
    error = require('debug')('i18n:error'),
    locales = {},
    pathsep = path.sep || '/', // ---> means win support will be available in 0.8.x and above
    defaultLocale, updateFiles, cookiename, debug, extension, directory;

// public exports
var i18n = exports;

i18n.version = '0.3.9';

i18n.configure = function i18nConfigure(opt) {

  // you may register helpers in global scope, up to you
  if (typeof opt.register === 'object') {
    opt.register.__ = i18n.__;
    opt.register.__n = i18n.__n;
    opt.register.getLocale = i18n.getLocale;
    opt.register.setLocale = i18n.setLocale;
  }

  // sets a custom cookie name to parse locale settings from
  cookiename = (typeof opt.cookie === 'string') ? opt.cookie : null;

  // where to store json files
  directory = (typeof opt.directory === 'string') ? opt.directory : __dirname + pathsep + 'locales';

  // write new locale information to disk
  updateFiles = (typeof opt.updateFiles === 'boolean') ? opt.updateFiles : true;

  // where to store json files
  extension = (typeof opt.extension === 'string') ? opt.extension : '.json';

  // setting defaultLocale
  defaultLocale = (typeof opt.defaultLocale === 'string') ? opt.defaultLocale : 'en';

  // implicitly read all locales
  if (typeof opt.locales === 'object') {
    opt.locales.forEach(function (l) {
      read(l);
    });
  }
};

i18n.init = function i18nInit(request, response, next) {
  if (typeof request === 'object') {
    guessLanguage(request);
  }
  if (typeof next === 'function') {
    next();
  }
};

i18n.__ = function i18nTranslate(phrase) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), phrase);

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 1) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 1));
  }
  return msg;
};

i18n.__n = function i18nTranslatePlural(singular, plural, count) {
  // get translated message with locale from scope (deprecated) or object
  var msg = translate(getLocaleFromObject(this), singular, plural);

  // parse translation and replace all digets '%d' by `count`
  // this also replaces extra strings '%%s' to parseble '%s' for next step
  // simplest 2 form implementation of plural, like https://developer.mozilla.org/en/docs/Localization_and_Plurals#Plural_rule_.231_.282_forms.29
  if (parseInt(count, 10) > 1) {
    msg = vsprintf(msg.other, [count]);
  } else {
    msg = vsprintf(msg.one, [count]);
  }

  // if we have extra arguments with strings to get replaced,
  // an additional substition injects those strings afterwards
  if (arguments.length > 3) {
    msg = vsprintf(msg, Array.prototype.slice.call(arguments, 3));
  }

  return msg;
};

i18n.setLocale = function i18nSetLocale(locale_or_request, locale) {
  var target_locale = locale_or_request,
      request;
  // called like setLocale(req, 'en')
  if (locale_or_request && typeof locale === 'string' && locales[locale]) {
    request = locale_or_request;
    target_locale = locale;
  }
  // called like req.setLocale('en')
  if (locale === undefined && typeof this.locale === 'string' && typeof locale_or_request === 'string') {
    request = this;
    target_locale = locale_or_request;
  }
  if (locales[target_locale]) {
    // called like setLocale('en')
    if (request === undefined) {
      defaultLocale = target_locale;
    }
    else {
      request.locale = target_locale;
    }
  }
  return i18n.getLocale(request);
};

i18n.getLocale = function i18nGetLocale(request) {
  // called like getLocale(req)
  if (request && request.locale) {
    return request.locale;
  }
  // called like req.getLocale()
  if (request === undefined && typeof this.locale === 'string') {
    return this.locale;
  }
  // called like getLocale()
  return defaultLocale;
};

i18n.overrideLocaleFromQuery = function (req) {
  if (req === null) {
    return;
  }
  var urlObj = url.parse(req.url, true);
  if (urlObj.query.locale) {
    logDebug("Overriding locale from query: " + urlObj.query.locale);
    i18n.setLocale(req, urlObj.query.locale.toLowerCase());
  }
};

// ===================
// = private methods =
// ===================
/**
 * guess language setting based on http headers
 */

function guessLanguage(request) {
  if (typeof request === 'object') {
    var language_header = request.headers['accept-language'],
        languages = [],
        regions = [];

    request.languages = [defaultLocale];
    request.regions = [defaultLocale];
    request.language = defaultLocale;
    request.region = defaultLocale;

    if (language_header) {
      language_header.split(',').forEach(function (l) {
        var header = l.split(';', 1)[0],
            lr = header.split('-', 2);
        if (lr[0]) {
          languages.push(lr[0].toLowerCase());
        }
        if (lr[1]) {
          regions.push(lr[1].toLowerCase());
        }
      });

      if (languages.length > 0) {
        request.languages = languages;
        request.language = languages[0];
      }

      if (regions.length > 0) {
        request.regions = regions;
        request.region = regions[0];
      }
    }

    // setting the language by cookie
    if (cookiename && request.cookies && request.cookies[cookiename]) {
      request.language = request.cookies[cookiename];
    }

    i18n.setLocale(request, request.language);
  }
}

/**
 * searches for locale in given object
 */

function getLocaleFromObject(obj) {
  var locale;
  if (obj && obj.scope) {
    locale = obj.scope.locale;
  }
  if (obj && obj.locale) {
    locale = obj.locale;
  }
  return locale;
}

/**
 * read locale file, translate a msg and write to fs if new
 */

function translate(locale, singular, plural) {
  if (locale === undefined) {
    logWarn("WARN: No locale found - check the context of the call to __(). Using " + defaultLocale + " as current locale");
    locale = defaultLocale;
  }

  if (!locales[locale]) {
    read(locale);
  }

  if (plural) {
    if (!locales[locale][singular]) {
      locales[locale][singular] = {
        'one': singular,
        'other': plural
      };
      write(locale);
    }
  }

  if (!locales[locale][singular]) {
    locales[locale][singular] = singular;
    write(locale);
  }
  return locales[locale][singular];
}

/**
 * try reading a file
 */

function read(locale) {
  var localeFile = {},
      file = getStorageFilePath(locale);
  try {
    logDebug('read ' + file + ' for locale: ' + locale);
    localeFile = fs.readFileSync(file);
    try {
      // parsing filecontents to locales[locale]
      locales[locale] = JSON.parse(localeFile);
    } catch (parseError) {
      logError('unable to parse locales from file (maybe ' + file + ' is empty or invalid json?): ', e);
    }
  } catch (readError) {
    // unable to read, so intialize that file
    // locales[locale] are already set in memory, so no extra read required
    // or locales[locale] are empty, which initializes an empty locale.json file
    logDebug('initializing ' + file);
    write(locale);
  }
}

/**
 * try writing a file in a created directory
 */

function write(locale) {
  var stats, target, tmp;

  // don't write new locale information to disk if updateFiles isn't true
  if (!updateFiles) {
    return;
  }

  // creating directory if necessary
  try {
    stats = fs.lstatSync(directory);
  } catch (e) {
    logDebug('creating locales dir in: ' + directory);
    fs.mkdirSync(directory, parseInt('755', 8));
  }

  // first time init has an empty file
  if (!locales[locale]) {
    locales[locale] = {};
  }

  // writing to tmp and rename on success
  try {
    target = getStorageFilePath(locale);
    tmp = target + ".tmp";
    fs.writeFileSync(tmp, JSON.stringify(locales[locale], null, "\t"), "utf8");
    stats = fs.statSync(tmp);
    if (stats.isFile()) {
      fs.renameSync(tmp, target);
    } else {
      logError('unable to write locales to file (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
    }
  } catch (e) {
    logError('unexpected error writing files (either ' + tmp + ' or ' + target + ' are not writeable?): ', e);
  }
}

/**
 * basic normalization of filepath
 */

function getStorageFilePath(locale) {
  // changed API to use .json as default, #16
  var ext = extension || '.json',
      filepath = path.normalize(directory + pathsep + locale + ext),
      filepathJS = path.normalize(directory + pathsep + locale + '.js');
  // use .js as fallback if already existing
  try {
    if (fs.statSync(filepathJS)) {
      logDebug('using existing file ' + filepathJS);
      extension = '.js';
      return filepathJS;
    }
  } catch (e) {
    logDebug('will write to ' + filepath);
  }
  return filepath;
}

/**
 * Logging proxies
 */

function logDebug(msg) {
  debug(msg);
}

function logWarn(msg) {
  warn(msg);
}

function logError(msg) {
  error(msg);
}
<|endoftext|>


<commit_before>// Various data on the icosahedral group H_3 = Alt_5 x Z/2
// and its irreducible representation on Z^6 < R^6 = R^3 (+) R^3.

var Icos = (function () {

// Basis for the representation.
// * In each R^3 summand the basis axes project to long diagonals of an
//   icosahedron, and H_3 acts by permutations and flips.
// * Each basis vector has length sqrt(2) in the Euclidean metric.
// * Written as a matrix of column vectors to facilitate taking linear
//   combinations via matrix multiplication.
var ICOS_BASIS = (function () {
	var c = 1/Math.sqrt(5);
	var s = 2/Math.sqrt(5);
	var c2 = (Math.sqrt(5) - 1)/4;
	var s2 = Math.sqrt(10 + 2*Math.sqrt(5))/4;
	var c4 = (-Math.sqrt(5) - 1)/4;
	var s4 = Math.sqrt(10 - 2*Math.sqrt(5))/4;
	return [
		[0,  s,  s*c2,  s*c4,  s*c4,  s*c2],
		[0,  0,  s*s2,  s*s4, -s*s4, -s*s2],
		[1,  c,  c,     c,     c,     c],
		[0, -s, -s*c4, -s*c2, -s*c2, -s*c4],
		[0,  0, -s*s4,  s*s2, -s*s2,  s*s4],
		[1, -c, -c,    -c,    -c,    -c],
	];
})();

var Icos = {
	BASIS: ICOS_BASIS,
	testBasisOrthogonality: function () {
		// Self-test for orthogonality
		var m = M.mulMats(M.transpose(this.BASIS), this.BASIS);
		var id = function (i, j) { if (i == j) { return 2; } else { return 0; } };
		for (var i = 0; i < 6; i++) {
			for (var j = 0; j < 6; j++) {
				if (Math.abs(m[i][j] - id(i,j)) > 1e-9) { return [i, j]; }
			}
		}
		return false;
	},

	// Test whether a point is in the fundamental domain
	// attached to point 0, on edge 01, and in triangle 012.
	isFundamental: function (coords) {
		var dots = M.mul(this.BASIS, coords.slice(0,3));
		return dots[2] > dots[5] &&
			dots[1] > dots[2] &&
			dots[0] > dots[1];
	},

	// Two matrices acting on Z^6 which act by scaling with
	// reciprocal factors on the R^3 summands.
	M_EXPAND: [
		[2, 1, 1, 1, 1, 1],
		[1, 2, 1, -1, -1, 1],
		[1, 1, 2, 1, -1, -1],
		[1, -1, 1, 2, 1, -1],
		[1, -1, -1, 1, 2, 1],
		[1, 1, -1, -1, 1, 2],
	],
	M_SHRINK: [
		[-2, 1, 1, 1, 1, 1],
		[1, -2, 1, -1, -1, 1],
		[1, 1, -2, 1, -1, -1],
		[1, -1, 1, -2, 1, -1],
		[1, -1, -1, 1, -2, 1],
		[1, 1, -1, -1, 1, -2],
	],

	// The group action
	GROUP: (function () {
		var ans = new Array(120);
		function product() {
			var p = ans[arguments[0] || 0];
			for (var i = 1; i < arguments.length; i++) {
				p = M.mulMats(p, ans[arguments[i] || 0]);
			}
			return p;
		}
		ans[0] = [ // identity
			[1, 0, 0, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 0, 0, 1, 0, 0],
			[0, 0, 0, 0, 1, 0],
			[0, 0, 0, 0, 0, 1],
		];
		ans[1] = [ // a rotation in S_3 on triangle 012
			[0, 0, 1, 0, 0, 0],
			[1, 0, 0, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 0, 0, -1, 0],
			[0, 0, 0, 0, 0, -1],
			[0, 0, 0, 1, 0, 0],
		];
		ans[2] = [ // a reflection in S_3 on triangle 012
			[1, 0, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 0, 0, 0, 1],
			[0, 0, 0, 0, 1, 0],
			[0, 0, 0, 1, 0, 0],
		];
		// fill out the rest of S_3
		ans[3] = product(1, 1);
		ans[4] = product(1, 2);
		ans[5] = product(2, 1);
		// take triangle 012 to other triangles
		ans[6] = [
			[0, 0, 0, 0, -1, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 0, 0, 0, 0, -1],
			[-1, 0, 0, 0, 0, 0],
			[0, 0, 0, -1, 0, 0],
		];
		ans[7] = product(1, 6);
		ans[8] = product(3, 6);
		ans[9] = product(6, 7);
		for (var i = 1; i < 6; i++) {
			ans[9+i] = product(i, 9);
		};
		// fill each of the other triangles
		var k = 15;
		for (var i = 1; i < 6; i++) {
			for (var j = 6; j < 15; j++) {
				ans[k] = product(j, i);
				k++;
			}
		}
		// reflect everything through the origin
		ans[60] = [ // antipodal
			[-1, 0, 0, 0, 0, 0],
			[0, -1, 0, 0, 0, 0],
			[0, 0, -1, 0, 0, 0],
			[0, 0, 0, -1, 0, 0],
			[0, 0, 0, 0, -1, 0],
			[0, 0, 0, 0, 0, -1],
		];
		for (var i = 1; i < 60; i++) {
			ans[60+i] = product(60, i);
		}
		return ans;
	})(),
	testGroup: function () {
		// Group self-test for no duplicates and correct matrix sizes
		for (var i = 0; i < 120; i++) {
			var a = this.GROUP[i];
			// Test for matrix sizes
			if (!a || (a.length != 6)) { return i; }
			for (var y = 0; y < 6; y++) {
				if (!a[y] || (a[y].length != 6)) { return i; }
			}
			// Test for duplicates
			for (var j = 0; j < i; j++) {
				var b = this.GROUP[j];
				var different = false;
				for (var y = 0; y < 6; y++) {
					for (var x = 0; x < 6; x++) {
						if (a[y][x] != b[y][x]) { different = true; }
					}
				}
				if (!different) { return [i, j]; }
			}
		}
		return false;
	},
};

return Icos;

})();
<commit_msg>Icos.isFundamental: Tolerate rounding errors.<commit_after>// Various data on the icosahedral group H_3 = Alt_5 x Z/2
// and its irreducible representation on Z^6 < R^6 = R^3 (+) R^3.

var Icos = (function () {

// Basis for the representation.
// * In each R^3 summand the basis axes project to long diagonals of an
//   icosahedron, and H_3 acts by permutations and flips.
// * Each basis vector has length sqrt(2) in the Euclidean metric.
// * Written as a matrix of column vectors to facilitate taking linear
//   combinations via matrix multiplication.
var ICOS_BASIS = (function () {
	var c = 1/Math.sqrt(5);
	var s = 2/Math.sqrt(5);
	var c2 = (Math.sqrt(5) - 1)/4;
	var s2 = Math.sqrt(10 + 2*Math.sqrt(5))/4;
	var c4 = (-Math.sqrt(5) - 1)/4;
	var s4 = Math.sqrt(10 - 2*Math.sqrt(5))/4;
	return [
		[0,  s,  s*c2,  s*c4,  s*c4,  s*c2],
		[0,  0,  s*s2,  s*s4, -s*s4, -s*s2],
		[1,  c,  c,     c,     c,     c],
		[0, -s, -s*c4, -s*c2, -s*c2, -s*c4],
		[0,  0, -s*s4,  s*s2, -s*s2,  s*s4],
		[1, -c, -c,    -c,    -c,    -c],
	];
})();

var Icos = {
	EPSILON: 1e-9,
	BASIS: ICOS_BASIS,
	testBasisOrthogonality: function () {
		// Self-test for orthogonality
		var m = M.mulMats(M.transpose(this.BASIS), this.BASIS);
		var id = function (i, j) { if (i == j) { return 2; } else { return 0; } };
		for (var i = 0; i < 6; i++) {
			for (var j = 0; j < 6; j++) {
				if (Math.abs(m[i][j] - id(i,j)) > 1e-9) { return [i, j]; }
			}
		}
		return false;
	},

	// Test whether a point is in the fundamental domain
	// attached to point 0, on edge 01, and in triangle 012.
	isFundamental: function (coords) {
		var dots = M.mul(this.BASIS, coords.slice(0,3));
		return dots[2] >= dots[5] - EPSILON &&
			dots[1] >= dots[2] - EPSILON &&
			dots[0] >= dots[1] - EPSILON;
	},

	// Two matrices acting on Z^6 which act by scaling with
	// reciprocal factors on the R^3 summands.
	M_EXPAND: [
		[2, 1, 1, 1, 1, 1],
		[1, 2, 1, -1, -1, 1],
		[1, 1, 2, 1, -1, -1],
		[1, -1, 1, 2, 1, -1],
		[1, -1, -1, 1, 2, 1],
		[1, 1, -1, -1, 1, 2],
	],
	M_SHRINK: [
		[-2, 1, 1, 1, 1, 1],
		[1, -2, 1, -1, -1, 1],
		[1, 1, -2, 1, -1, -1],
		[1, -1, 1, -2, 1, -1],
		[1, -1, -1, 1, -2, 1],
		[1, 1, -1, -1, 1, -2],
	],

	// The group action
	GROUP: (function () {
		var ans = new Array(120);
		function product() {
			var p = ans[arguments[0] || 0];
			for (var i = 1; i < arguments.length; i++) {
				p = M.mulMats(p, ans[arguments[i] || 0]);
			}
			return p;
		}
		ans[0] = [ // identity
			[1, 0, 0, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 0, 0, 1, 0, 0],
			[0, 0, 0, 0, 1, 0],
			[0, 0, 0, 0, 0, 1],
		];
		ans[1] = [ // a rotation in S_3 on triangle 012
			[0, 0, 1, 0, 0, 0],
			[1, 0, 0, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 0, 0, -1, 0],
			[0, 0, 0, 0, 0, -1],
			[0, 0, 0, 1, 0, 0],
		];
		ans[2] = [ // a reflection in S_3 on triangle 012
			[1, 0, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 0, 0, 0, 1],
			[0, 0, 0, 0, 1, 0],
			[0, 0, 0, 1, 0, 0],
		];
		// fill out the rest of S_3
		ans[3] = product(1, 1);
		ans[4] = product(1, 2);
		ans[5] = product(2, 1);
		// take triangle 012 to other triangles
		ans[6] = [
			[0, 0, 0, 0, -1, 0],
			[0, 1, 0, 0, 0, 0],
			[0, 0, 1, 0, 0, 0],
			[0, 0, 0, 0, 0, -1],
			[-1, 0, 0, 0, 0, 0],
			[0, 0, 0, -1, 0, 0],
		];
		ans[7] = product(1, 6);
		ans[8] = product(3, 6);
		ans[9] = product(6, 7);
		for (var i = 1; i < 6; i++) {
			ans[9+i] = product(i, 9);
		};
		// fill each of the other triangles
		var k = 15;
		for (var i = 1; i < 6; i++) {
			for (var j = 6; j < 15; j++) {
				ans[k] = product(j, i);
				k++;
			}
		}
		// reflect everything through the origin
		ans[60] = [ // antipodal
			[-1, 0, 0, 0, 0, 0],
			[0, -1, 0, 0, 0, 0],
			[0, 0, -1, 0, 0, 0],
			[0, 0, 0, -1, 0, 0],
			[0, 0, 0, 0, -1, 0],
			[0, 0, 0, 0, 0, -1],
		];
		for (var i = 1; i < 60; i++) {
			ans[60+i] = product(60, i);
		}
		return ans;
	})(),
	testGroup: function () {
		// Group self-test for no duplicates and correct matrix sizes
		for (var i = 0; i < 120; i++) {
			var a = this.GROUP[i];
			// Test for matrix sizes
			if (!a || (a.length != 6)) { return i; }
			for (var y = 0; y < 6; y++) {
				if (!a[y] || (a[y].length != 6)) { return i; }
			}
			// Test for duplicates
			for (var j = 0; j < i; j++) {
				var b = this.GROUP[j];
				var different = false;
				for (var y = 0; y < 6; y++) {
					for (var x = 0; x < 6; x++) {
						if (a[y][x] != b[y][x]) { different = true; }
					}
				}
				if (!different) { return [i, j]; }
			}
		}
		return false;
	},
};

return Icos;

})();
<|endoftext|>


<commit_before>/*global define:false */
/**
 * Copyright 2014 Nigel Greenway
 *
 * 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.
 *
 * For use with Inuit CSS, this creates a Modal dialog for your project. Build
 * in vanilla Javascript, it allows you to not have to worry about any required
 * external dependencies.
 *
 * NOTE: Iglu has an optional dependancy of Mousetrap for optional key binding.
 * This will be installed if you installed IgluJS via Bower.
 * For more info visit: http://craig.is/killing/mice
 *
 * @version 0.0.1a
 * @url https://github.com/smilinmonki666/inuitcss.plugins.iglu
 */
(function(window, document, undefined) {
   /*
    * Show the container after it has been created
    */
    function show() {
        this.Iglu.container.style.display="block";
        this.Iglu.documentBody.className += ' ' + this.Iglu.documentBodyClassName;

        this.Iglu.container.getElementsByClassName('modal__close')[0].addEventListener('click', function() {
            destroy();
        });
        this.Iglu.container.addEventListener('click', function(event) {
            // Check it is the Iglu container that has triggered the event and
            // then allow for the Iglu object to be destroyed.
            if(this === event.target){
                destroy();
            }
        }, false);

        if (typeof Mousetrap !== 'undefined') {
            Mousetrap.bind('esc', function(e) {
                destroy();
            });
        };
    };

    /*
     * Destroy the container content and hide the container
     */
     function destroy() {
         this.Iglu.documentBody.className=this.Iglu.documentBody.className.replace(' ' + this.Iglu.documentBodyClassName, '');
         this.Iglu.container.style.display="none";
         this.Iglu.container.innerHTML="";

         if (typeof Mousetrap !== 'undefined') {
             Mousetrap.unbind('esc');
         }
     }

     // Factory methods:
     var factory = {
         /*
          * Create the Iglu modal and its content via the passed params
          */
          iglu: function(title, content, size, alignRight) {

              title = title === null ? '' : '
' + title + '
';

              Iglu.container.innerHTML=''+
              '
' +
                  '
' +
                      '' +
                      title +
                  '
' +
                  '
' +
                      '' + content + '' +
                  '
' +
                  '

' +
              '
';

              return Iglu;
          },

         /*
          * Create a button with the details from the button object
          */
          button: function(button) {

              footer = Iglu.container.getElementsByClassName('modal__footer')[0];

              btn = document.createElement('button');

              if (typeof button.type === 'undefined') {
                  btn.setAttribute('type', 'button');
              } else {
                  btn.setAttribute('type', button.type);
              }

              alignRight = button.alignRight === false || typeof button.alignRight === 'undefined' ? '' : ' right';

              btn.setAttribute('class', button.class + ' ' + alignRight);

              btn.textContent=button.content;

              if (button.attr) {
                  Object.keys(button.attr).forEach(function(key) {
                      btn.setAttribute(button.attr[key].name, button.attr[key].value);
                  });
              }

              if (button.removeOnCallback === true) {
                  btn.addEventListener('click', function(event) {
                      event.target.parentNode.removeChild(event.target);
                  });
              }

              footer.appendChild(btn);

              if (button.dismiss === true) {
                  btn.addEventListener('click', function() {
                      destroy();
                  });
              }
          }
     };

     // Iglue Object
     var Iglu = {
         options:               null,
         container:             null,
         title:                 null,
         content:               null,
         documentBody:          null,
         documentBodyClassName: null,

        /*
         * Generator for the Iglu object.

         * @param string|null title
         * @param string      content
         * @param object      options
         */
         generate: function(title, content, options) {
             this.documentBody          = document.getElementsByTagName('body')[0];
             this.documentBodyClassName = 'modal--active';

             if (typeof title !== 'string' && title !== null) {
                 throw new TypeError('The `title` must be a String type.');
             }

             if (typeof content !== 'string') {
                 throw new TypeError('The `content` must be a String type.');
             }

             if (options === null) {
                 throw new TypeError('`options` must be an Object type.');
             }

             this.container = document.getElementById('modal');
             this.options   = options;

             factory.iglu(title, content, options.size, options.alignRight);

             Object.keys(options.buttons).forEach(function(key){
                 factory.button(options.buttons[key]);
             });

             show(this.container);

             return this;
         },

         notify: function(title, content) {

             var options = {
                 buttons: [
                     {
                         class:      'btn btn--primary',
                         content:    'Ok',
                         dismiss:    true,
                         alignRight: true
                     }
                 ],
                 size: 'notification'
             };

             this.generate(title, '
' + content + '
', options);
         },

        /*
         * Replace the content of the Iglu whilst the Iglu is active
         * @param string content
         */
         replaceContent: function(content) {
             this.container.getElementsByClassName('modal__content')[0].innerHTML=content;
         }
    };

    // expose Iglu as a global object
    window.Iglu = Iglu;

    // expose iglu as an AMD module
    if (typeof define === 'function' && define.amd) {
        define(Iglu);
    }

}) (window, document);<commit_msg>Update  spacing<commit_after>/*global define:false */
/**
 * Copyright 2014 Nigel Greenway
 *
 * 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.
 *
 * For use with Inuit CSS, this creates a Modal dialog for your project. Build
 * in vanilla Javascript, it allows you to not have to worry about any required
 * external dependencies.
 *
 * NOTE: Iglu has an optional dependancy of Mousetrap for optional key binding.
 * This will be installed if you installed IgluJS via Bower.
 * For more info visit: http://craig.is/killing/mice
 *
 * @version 0.0.1a
 * @url https://github.com/smilinmonki666/inuitcss.plugins.iglu
 */
(function(window, document, undefined) {
   /*
    * Show the container after it has been created
    */
    function show() {
        this.Iglu.container.style.display="block";
        this.Iglu.documentBody.className += ' ' + this.Iglu.documentBodyClassName;

        this.Iglu.container.getElementsByClassName('modal__close')[0].addEventListener('click', function() {
            destroy();
        });
        this.Iglu.container.addEventListener('click', function(event) {
            // Check it is the Iglu container that has triggered the event and
            // then allow for the Iglu object to be destroyed.
            if(this === event.target){
                destroy();
            }
        }, false);

        if (typeof Mousetrap !== 'undefined') {
            Mousetrap.bind('esc', function(e) {
                destroy();
            });
        }
    }

    /*
     * Destroy the container content and hide the container
     */
     function destroy() {
         this.Iglu.documentBody.className=this.Iglu.documentBody.className.replace(' ' + this.Iglu.documentBodyClassName, '');
         this.Iglu.container.style.display="none";
         this.Iglu.container.innerHTML="";

         if (typeof Mousetrap !== 'undefined') {
             Mousetrap.unbind('esc');
         }
     }

     // Factory methods:
     var factory = {
         /*
          * Create the Iglu modal and its content via the passed params
          */
          iglu: function(title, content, size, alignRight) {

              title = title === null ? '' : '
' + title + '
';

              Iglu.container.innerHTML=''+
              '
' +
                  '
' +
                      '' +
                      title +
                  '
' +
                  '
' +
                      '' + content + '' +
                  '
' +
                  '

' +
              '
';

              return Iglu;
          },

         /*
          * Create a button with the details from the button object
          */
          button: function(button) {

              footer = Iglu.container.getElementsByClassName('modal__footer')[0];

              btn = document.createElement('button');

              if (typeof button.type === 'undefined') {
                  btn.setAttribute('type', 'button');
              } else {
                  btn.setAttribute('type', button.type);
              }

              alignRight = button.alignRight === false || typeof button.alignRight === 'undefined' ? '' : ' right';

              btn.setAttribute('class', button.class + ' ' + alignRight);

              btn.textContent=button.content;

              if (button.attr) {
                  Object.keys(button.attr).forEach(function(key) {
                      btn.setAttribute(button.attr[key].name, button.attr[key].value);
                  });
              }

              if (button.removeOnCallback === true) {
                  btn.addEventListener('click', function(event) {
                      event.target.parentNode.removeChild(event.target);
                  });
              }

              footer.appendChild(btn);

              if (button.dismiss === true) {
                  btn.addEventListener('click', function() {
                      destroy();
                  });
              }
          }
     };

     // Iglu Object
     var Iglu = {
         options:               null,
         container:             null,
         title:                 null,
         content:               null,
         documentBody:          null,
         documentBodyClassName: null,

        /*
         * Generator for the Iglu object.

         * @param string|null title
         * @param string      content
         * @param object      options
         */
         generate: function(title, content, options) {
             this.documentBody          = document.getElementsByTagName('body')[0];
             this.documentBodyClassName = 'modal--active';

             if (typeof title !== 'string' && title !== null) {
                 throw new TypeError('The `title` must be a String type.');
             }

             if (typeof content !== 'string') {
                 throw new TypeError('The `content` must be a String type.');
             }

             if (options === null) {
                 throw new TypeError('`options` must be an Object type.');
             }

             this.container = document.getElementById('modal');
             this.options   = options;

             factory.iglu(title, content, options.size, options.alignRight);

             Object.keys(options.buttons).forEach(function(key){
                 factory.button(options.buttons[key]);
             });

             show(this.container);

             return this;
         },

         notify: function(title, content) {

             var options = {
                 buttons: [
                     {
                         class:      'btn btn--primary',
                         content:    'Ok',
                         dismiss:    true,
                         alignRight: true
                     }
                 ],
                 size: 'notification'
             };

             this.generate(title, '
' + content + '
', options);
         },

        /*
         * Replace the content of the Iglu whilst the Iglu is active
         * @param string content
         */
         replaceContent: function(content) {
             this.container.getElementsByClassName('modal__content')[0].innerHTML=content;
         }
    };

    // expose Iglu as a global object
    window.Iglu = Iglu;

    // expose iglu as an AMD module
    if (typeof define === 'function' && define.amd) {
        define(Iglu);
    }

}) (window, document);<|endoftext|>