<commit_before>const onChangeCallbacks = []

const tokenDidChange = function () {
  // Looking for a better way to refetch all queries
  // window.location.reload(0)
  for (const callback of onChangeCallbacks) {
    try {
      callback()
    } catch (error) {
      console.log('Error on onChangeCallback', error)
    }
  }
}

export const onTokenChange = function (callback) {
  onChangeCallbacks.push(callback)
}

export const storeLoginToken = function (userId, token, tokenExpires) {
  global.localStorage['Meteor.userId'] = userId
  global.localStorage['Meteor.loginToken'] = token
  global.localStorage['Meteor.loginTokenExpires'] = tokenExpires
  tokenDidChange()
}

export const getLoginToken = function () {
  return global.localStorage['Meteor.loginToken']
}

export const getUserId = function () {
  return global.localStorage['Meteor.userId'] || null
}

export const resetStore = function () {
  storeLoginToken('', '', '')
}
<commit_msg>send userId to onTokenChange<commit_after>const onChangeCallbacks = []

export const getLoginToken = function () {
  return global.localStorage['Meteor.loginToken']
}

export const getUserId = function () {
  return global.localStorage['Meteor.userId'] || null
}

const tokenDidChange = function () {
  // Looking for a better way to refetch all queries
  // window.location.reload(0)
  for (const callback of onChangeCallbacks) {
    try {
      callback(getUserId())
    } catch (error) {
      console.log('Error on onChangeCallback', error)
    }
  }
}

export const onTokenChange = function (callback) {
  onChangeCallbacks.push(callback)
}

export const storeLoginToken = function (userId, token, tokenExpires) {
  global.localStorage['Meteor.userId'] = userId
  global.localStorage['Meteor.loginToken'] = token
  global.localStorage['Meteor.loginTokenExpires'] = tokenExpires
  tokenDidChange()
}

export const resetStore = function () {
  storeLoginToken('', '', '')
}
<|endoftext|>


<commit_before>var five = require("../lib/johnny-five");
var board = new five.Board();

board.on("ready", function() {

  var matrix = new five.LedControl({
    pins: {
      data: 2,
      clock: 3,
      cs: 4
    },
    isMatrix: true,
    devices: 2
  });

  matrix.on();

  var message = "h".split("");

  // function rotty(start) {
  //   var result = [0, 0, 0, 0, 0, 0, 0, 0];

  //   // console.log( start );

  //   for (var i = 0; i < 8; i++) {
  //     for (var j = 0; j < 8; j++) {
  //       // result[i] = result[i] & start[j][7-i];
  //       // console.log(  result[i], (result[i] >> 1) );
  //       // result[i] = (result[i] >> 1)
  //       // console.log( i, start[j] >> i );

  //       // (result[i] << 1) | ((start[j] >> (7 - i)) & 0x01);
  //       result[i] = (result[i] << 1) | ((start[j] >> (7 - i)) & 0x01);
  //     }
  //       // result[0] += start[i][7];
  //       // result[1] += start[i][6];
  //       // result[2] += start[i][5];
  //       // result[3] += start[i][4];
  //       // result[4] += start[i][3];
  //       // result[5] += start[i][2];
  //       // result[6] += start[i][1];
  //       // result[7] += start[i][0];
  //   }

  //   return result;
  // }

  function padLeft(s, l, c) {
    s = String(s);
    return (new Array(l - s.length + 1)).join(c || " ") + s;
  }

  rotate.ccw = function(a) {
    var n = a.length;
    for (var i = 0; i < n / 2; i++) {
      for (var j = i; j < n - i - 1; j++) {
        var tmp = a[i][j];
        a[i][j] = a[j][n - i - 1];
        a[j][n - i - 1] = a[n - i - 1][n - j - 1];
        a[n - i - 1][n - j - 1] = a[n - j - 1][i];
        a[n - j - 1][i] = tmp;
      }
    }
    return a;
  };
  rotate.cw = function(a) {
    var n = a.length;
    for (var i = 0; i < n / 2; i++) {
      for (var j = i; j < n - i - 1; j++) {
        var tmp = a[i][j];
        a[i][j] = a[n - j - 1][i];
        a[n - j - 1][i] = a[n - i - 1][n - j - 1];
        a[n - i - 1][n - j - 1] = a[j][n - i - 1];
        a[j][n - i - 1] = tmp;
      }
    }
  };

  function rotate(bitsIn, dir) {
    dir = dir || "ccw";
    return rotate[dir](bitsIn.map(function(num) {
      return padLeft(num.toString(2), 8, "0").split("");
    })).map(function(bits) {
      return parseInt(String(bits), 2);
      // return parseInt(bits.join(""), 2);
    });
  }

  // function rotty(start) {
  //   var result = [0, 0, 0, 0, 0, 0, 0, 0];

  //   // console.log( start );

  //   for (var i = 0; i < 8; i++) {
  //     for (var j = 0; j < 8; j++) {
  //       // result[i] = result[i] & start[j][7-i];
  //       // console.log(  result[i], (result[i] >> 1) );
  //       // result[i] = (result[i] >> 1)
  //       // console.log( i, start[j] >> i );

  //       // (result[i] << 1) | ((start[j] >> (7 - i)) & 0x01);
  //       result[i] = (result[i] << 1) | ((start[j] >> (7 - i)) & 0x01);
  //     }
  //       // result[0] += start[i][7];
  //       // result[1] += start[i][6];
  //       // result[2] += start[i][5];
  //       // result[3] += start[i][4];
  //       // result[4] += start[i][3];
  //       // result[5] += start[i][2];
  //       // result[6] += start[i][1];
  //       // result[7] += start[i][0];
  //   }

  //   return result;
  // }

  // function rotate(bitsIn) {
  //   var bits = bitsIn.map(function(num) {
  //     return padLeft(num.toString(2), 8, "0");
  //   });

  //   var result = ["", "", "", "", "", "", "", ""];

  // console.log( bits );

  //   for (var i = 0; i < 8; i++) {
  //     result[i] += bits[i][7];
  //     result[i] += bits[i][6];
  //     result[i] += bits[i][5];
  //     result[i] += bits[i][4];
  //     result[i] += bits[i][3];
  //     result[i] += bits[i][2];
  //     result[i] += bits[i][1];
  //     result[i] += bits[i][0];

  //     // for (var j = 7; j >= 0; j--) {
  //     //   console.log( bits[j] );
  //     //   result[i] += bits[j];
  //     // }
  //   }

  //   // console.log( result );

  //   return result;
  // }

  // function next() {
  //   var c;

  //   if (c = message.shift()) {
  //     matrix.draw(c);
  //     setTimeout(next, 500);
  //   }
  // }

  // next();

  var injection = {
    r: function(c) {
      var char;
      if (char = five.LedControl.MATRIX_CHARS[c]) {
        matrix.draw(0, rotate(char));
        matrix.draw(1, char);

      }
    },
    d: function(c) {
      matrix.draw(1, c);
    },

    matrix: matrix
  };

  var chars = Object.keys(five.LedControl.MATRIX_CHARS).slice(32);
  var index = 1;

  setInterval(function() {
    injection.r(chars[index++]);
  }, 1000);

  this.repl.inject(injection);
});

// void scrollFont() {
//     for (int counter=0x20;counter<0x80;counter++){
//         loadBufferLong(counter);
//         delay(500);
//     }
// }

// // Scroll Message
// void scrollMessage(prog_uchar * messageString) {
//     int counter = 0;
//     int myChar=0;
//     do {
//         // read back a char
//         myChar =  pgm_read_byte_near(messageString + counter);
//         if (myChar != 0){
//             loadBufferLong(myChar);
//         }
//         counter++;
//     }
//     while (myChar != 0);
// }
// // Load character into scroll buffer
// void loadBufferLong(int ascii){
//     if (ascii >= 0x20 && ascii <=0x7f){
//         for (int a=0;a<7;a++){                      // Loop 7 times for a 5x7 font
//             var c = pgm_read_byte_near(font5x7 + ((ascii - 0x20) * 8) + a);     // Index into character table to get row data
//             var x = bufferLong [a*2];     // Load current scroll buffer
//             x = x | c;                              // OR the new character onto end of current
//             bufferLong [a*2] = x;                   // Store in buffer
//         }
//         byte count = pgm_read_byte_near(font5x7 +((ascii - 0x20) * 8) + 7);     // Index into character table for kerning data
//         for (byte x=0; x<count;x++){
//             rotateBufferLong();
//             printBufferLong();
//             delay(scrollDelay);
//         }
//     }
// }
// // Rotate the buffer
// void rotateBufferLong(){
//     for (int a=0;a<7;a++){                      // Loop 7 times for a 5x7 font
//         var x = bufferLong [a*2];     // Get low buffer entry
//         byte b = bitRead(x,31);                 // Copy high order bit that gets lost in rotation
//         x = x<<1;                               // Rotate left one bit
//         bufferLong [a*2] = x;                   // Store new low buffer
//         x = bufferLong [a*2+1];                 // Get high buffer entry
//         x = x<<1;                               // Rotate left one bit
//         bitWrite(x,0,b);                        // Store saved bit
//         bufferLong [a*2+1] = x;                 // Store new high buffer
//     }
// }
// // Display Buffer on LED matrix
// void printBufferLong(){
//   for (int a=0;a<7;a++){                    // Loop 7 times for a 5x7 font
//     var x = bufferLong[a*2+1];   // Get high buffer entry
//     var y = x;                             // Mask off first character
//     lc.row(3,a,y);                       // Send row to relevent MAX7219 chip
//     x = bufferLong[a*2];                   // Get low buffer entry
//     y = (x>>24);                            // Mask off second character
//     lc.row(2,a,y);                       // Send row to relevent MAX7219 chip
//     y = (x>>16);                            // Mask off third character
//     lc.row(1,a,y);                       // Send row to relevent MAX7219 chip
//     y = (x>>8);                             // Mask off forth character
//     lc.row(0,a,y);                       // Send row to relevent MAX7219 chip
//   }
// }
<commit_msg>Remove garbage file<commit_after><|endoftext|>


<commit_before>// bitbucket.js
// https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html
// ========
module.exports = {
    parse: function (req, discordPayload) {
        var body = req.body;
        var type = req.get("X-Event-Key");
        var baseLink = 'https://bitbucket.org/';

        discordPayload.embeds = [];

        switch (type) {
            case "repo:push":
                var project = {
                    name: body.repository.name,
                    url: baseLink + body.repository.full_name,
                    branch: null,
                    commits: null
                };
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                for (var i = 0; i < body.push.changes.length; i++) {
                    var change = body.push.changes[i];
                    project.branch = (change.old != null) ? change.old.name : change.new.name;
                    project.commits = change.commits;

                    var commits = "";
                    for (var j = 0; j < project.commits.length; j++) {
                        var commit = project.commits[j];
                        var message = (commit.message.length > 50) ? commit.message.substring(0, 47) + "..." : commit.message;
                        commits = commits + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ") " + message + " - " + commit.author.user.display_name + "\n";
                    }

                    discordPayload.embeds.push({
                        title: "[" + project.name + ":" + project.branch + "] " + project.commits.length + " commit" + ((project.commits.length > 1) ? "s" : ""),
                        url: project.url,
                        author: user,
                        description: commits,
                        footer: {
                            text: "Powered by skyhook",
                            icon_url: ""
                        }
                    });
                }
                break;
            case "repo:fork":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.embeds.push({
                    author: user,
                    description: "Created a [`fork`](" + baseLink + body.fork.full_name + ") of [`" + body.repository.name + "`](" + baseLink + body.repository.full_name + ")",
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                var changes = [];
                if (typeof body.changes.name !== "undefined") {
                    changes.push("**Name:** \"" + body.changes.name.old + "\" -> \"" + body.changes.name.new + "\"");
                }
                if (typeof body.changes.website !== "undefined") {
                    changes.push("**Website:** \"" + body.changes.website.old + "\" -> \"" + body.changes.website.new + "\"");
                }
                if (typeof body.changes.language !== "undefined") {
                    changes.push("**Language:** \"" + body.changes.language.old + "\" -> \"" + body.changes.language.new + "\"");
                }
                if (typeof body.changes.description !== "undefined") {
                    changes.push("**Description:** \"" + body.changes.description.old + "\" -> \"" + body.changes.description.new + "\"");
                }

                discordPayload.embeds.push({
                    author: user,
                    title: "Changed general information of " + body.repository.name,
                    url: baseLink + body.repository.full_name,
                    description: changes.join("\n"),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_comment_created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Wrote a comment to commit " + body.commit.hash.substring(0, 7) + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/commits/" + body.commit.hash,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, ''),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_status_created":
                discordPayload.embeds.push({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description,
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_status_updated":
                discordPayload.embeds.push({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description,
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Created a new Issue on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    fields: [
                        {
                            name: body.issue.title,
                            value: "**State:** " + body.issue.state + "\n" +
                            "**Type:** " + body.issue.type + "\n" +
                            "**Priority:** " + body.issue.priority + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.embeds.push({
                    author: user,
                    title: "Updated Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:comment_created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Wrote a comment to Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, ''),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "pullrequest:created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Created a new pull request on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "pullrequest:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Updated pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
        }
        //TODO: support of the other webhook methods of BitBucket
    }
};
<commit_msg>Added BitBucket pullrequest:approved, pullrequest:unapproved, pullrequest:fulfilled & pullrequest:rejected event<commit_after>// bitbucket.js
// https://confluence.atlassian.com/bitbucket/manage-webhooks-735643732.html
// ========
module.exports = {
    parse: function (req, discordPayload) {
        var body = req.body;
        var type = req.get("X-Event-Key");
        var baseLink = 'https://bitbucket.org/';

        discordPayload.embeds = [];

        switch (type) {
            case "repo:push":
                var project = {
                    name: body.repository.name,
                    url: baseLink + body.repository.full_name,
                    branch: null,
                    commits: null
                };
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                for (var i = 0; i < body.push.changes.length; i++) {
                    var change = body.push.changes[i];
                    project.branch = (change.old != null) ? change.old.name : change.new.name;
                    project.commits = change.commits;

                    var commits = "";
                    for (var j = 0; j < project.commits.length; j++) {
                        var commit = project.commits[j];
                        var message = (commit.message.length > 50) ? commit.message.substring(0, 47) + "..." : commit.message;
                        commits = commits + "[`" + commit.hash.substring(0, 7) + "`](" + commit.links.html.href + ") " + message + " - " + commit.author.user.display_name + "\n";
                    }

                    discordPayload.embeds.push({
                        title: "[" + project.name + ":" + project.branch + "] " + project.commits.length + " commit" + ((project.commits.length > 1) ? "s" : ""),
                        url: project.url,
                        author: user,
                        description: commits,
                        footer: {
                            text: "Powered by skyhook",
                            icon_url: ""
                        }
                    });
                }
                break;
            case "repo:fork":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.embeds.push({
                    author: user,
                    description: "Created a [`fork`](" + baseLink + body.fork.full_name + ") of [`" + body.repository.name + "`](" + baseLink + body.repository.full_name + ")",
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                var changes = [];
                if (typeof body.changes.name !== "undefined") {
                    changes.push("**Name:** \"" + body.changes.name.old + "\" -> \"" + body.changes.name.new + "\"");
                }
                if (typeof body.changes.website !== "undefined") {
                    changes.push("**Website:** \"" + body.changes.website.old + "\" -> \"" + body.changes.website.new + "\"");
                }
                if (typeof body.changes.language !== "undefined") {
                    changes.push("**Language:** \"" + body.changes.language.old + "\" -> \"" + body.changes.language.new + "\"");
                }
                if (typeof body.changes.description !== "undefined") {
                    changes.push("**Description:** \"" + body.changes.description.old + "\" -> \"" + body.changes.description.new + "\"");
                }

                discordPayload.embeds.push({
                    author: user,
                    title: "Changed general information of " + body.repository.name,
                    url: baseLink + body.repository.full_name,
                    description: changes.join("\n"),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_comment_created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Wrote a comment to commit " + body.commit.hash.substring(0, 7) + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/commits/" + body.commit.hash,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, ''),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_status_created":
                discordPayload.embeds.push({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description,
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "repo:commit_status_updated":
                discordPayload.embeds.push({
                    author: {
                        name: body.repository.name,
                        url: baseLink + body.repository.full_name,
                        icon_url: body.repository.links.avatar.href
                    },
                    title: body.commit_status.name,
                    url: body.commit_status.url,
                    description: "**State:** " + body.commit_status.state + "\n" + body.commit_status.description,
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Created a new Issue on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    fields: [
                        {
                            name: body.issue.title,
                            value: "**State:** " + body.issue.state + "\n" +
                            "**Type:** " + body.issue.type + "\n" +
                            "**Priority:** " + body.issue.priority + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };
                discordPayload.embeds.push({
                    author: user,
                    title: "Updated Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: "",
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "issue:comment_created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Wrote a comment to Issue #" + body.issue.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/issues/" + body.issue.id,
                    description: (body.comment.content.html.replace(/<.*?>/g, '').length > 100) ? body.comment.content.html.replace(/<.*?>/g, '').substring(0, 97) + "..." : body.comment.content.html.replace(/<.*?>/g, ''),
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "pullrequest:created":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Created a new pull request on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "pullrequest:updated":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Updated pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: body.pullrequest.description,
                    fields: [
                        {
                            name: body.pullrequest.title,
                            value: "**Destination branch:** " + body.pullrequest.destination.branch.name + "\n" +
                            "**State:** " + body.pullrequest.state + "\n"
                        }
                    ],
                    footer: {
                        text: "Powered by skyhook",
                        icon_url: ""
                    }
                });
                break;
            case "pullrequest:approved":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Approved pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: ""
                });
                break;
            case "pullrequest:unapproved":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Removed his approval for pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: ""
                });
                break;
            case "pullrequest:fulfilled":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Merged pull request #" + body.pullrequest.id + " into " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: ""
                });
                break;
            case "pullrequest:rejected":
                var user = {
                    name: body.actor.display_name,
                    icon_url: body.actor.links.avatar.href,
                    url: baseLink + body.actor.username
                };

                discordPayload.embeds.push({
                    author: user,
                    title: "Declined pull request #" + body.pullrequest.id + " on " + body.repository.name,
                    url: baseLink + body.repository.full_name + "/pull-requests/" + body.pullrequest.id,
                    description: (typeof body.pullrequest.reason !== "undefined") ? body.pullrequest.reason : ""
                });
                break;
        }
        //TODO: support of the other webhook methods of BitBucket
    }
};
<|endoftext|>


<commit_before>/**
 * The Render Engine
 * BillboardComponent
 *
 * @fileoverview A render component which will render the contents of
 *               a generated image until the contents are updated.
 *
 * @author: Brett Fattori (brettf@renderengine.com)
 * @author: $Author: bfattori $
 * @version: $Revision: 1556 $
 *
 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

// The class this file defines and its required classes
R.Engine.define({
   "class": "R.components.render.Billboard2D",
   "requires": [
      "R.components.Render",
      "R.util.RenderUtil",
      "R.text.AbstractTextRenderer",
      "R.math.Point2D"
   ]
});

/**
 * @class The billboard component renders the contents of an image which
 *        was generated by a linked render component.  When the contents
 *        of the linked component are re-rendered, the contents of the
 *        image are updated.  The best usage of this component is for infrequently
 *        changing vector drawn objects.  For example:
 *

 *     // Add component to draw the object
 *     this.add(R.components.Billboard2D.create("draw", R.components.Vector2D.create("vector")));
 *

 *        Accessing the <tt>R.components.Vector2D</tt> within the <tt>R.components.Billboard2D</tt>
 *        is as simple as calling {@link #getComponent}.  If the contents of the linked
 *        component are updated, you will need to call {@link #regenerate} to recreate the
 *        billboard image.
 *
 *
 * @param name {String} The name of the component
 * @param renderComponent {R.components.Render} A render component to create the billboard from
 * @param priority {Number} The priority of the component between 0.0 and 1.0
 * @constructor
 * @extends R.components.Render
 * @description Creates a 2d billboard component.
 */
R.components.render.Billboard2D = function() {
   return R.components.Render.extend(/** @scope R.components.render.Billboard2D.prototype */{

      billboard: null,
      mode: null,
      renderComponent: null,
      hostRect: null,

      /**
       * @private
       */
      constructor: function(name, renderComponent, priority) {
         Assert(renderComponent instanceof R.components.Render ||
               renderComponent instanceof R.text.AbstractTextRenderer, "Attempt to assign a non-render component to a billboard component");
         this.base(name, priority || 0.1);
         this.mode = R.components.render.Billboard2D.REDRAW;
         this.renderComponent = renderComponent;

      },

      /**
       * Destroy the object
       */
      destroy: function() {
         this.renderComponent.destroy();
         this.base();
      },

      /**
       * Releases the component back into the object pool. See {@link R.engine.PooledObject#release}
       * for more information.
       */
      release: function() {
         this.base();
         this.mode = null;
         this.renderComponent = null;
      },

      /**
       * Deprecated in favor of {@link #setGameObject}.
       * @deprecated
       */
      setHostObject: function(hostObject) {
         this.setGameObject(hostObject);
      },

      /**
       * Establishes the link between this component and its game object.
       * When you assign components to a game object, it will call this method
       * so that each component can refer to its game object, the same way
       * a game object can refer to a component with {@link R.engine.GameObject#getComponent}.
       *
       * @param hostObject {R.engine.GameObject} The object which hosts this component
       */
      setGameObject: function(gameObject) {
         this.renderComponent.setGameObject(gameObject);
         this.base(gameObject);
      },

      /**
       * Call this method when the linked render component has been updated
       * to force the billboard to be redrawn.
       */
      regenerate: function() {
         this.mode = R.components.render.Billboard2D.REDRAW;
         this.hostRect = null;
         this.getGameObject().markDirty();
      },

      /**
       * Get the linked render component.
       * @return {R.components.Render}
       */
      getComponent: function() {
         return this.renderComponent;
      },

      /**
       * Draws the contents of the billboard to the render context.  This
       * component operates in one of two modes.  When the contents of the
       * subclassed component are redrawing, a temporary render context is created
       * to which the component renders.  The second mode is where the contents
       * of the context from the first mode are rendered instead of performing
       * all of the operations required to render the component.  This component
       * is only good if the contents don't change often.
       *
       * @param renderContext {R.rendercontexts.AbstractRenderContext} The rendering context
       * @param time {Number} The engine time in milliseconds
       * @param dt {Number} The delta between the world time and the last time the world was updated
       *          in milliseconds.
       */
      execute: function(renderContext, time, dt) {
         if (!this.base(renderContext, time, dt)) {
            return;
         }

         // Get the host object's bounding box
         var hostBox = this.getGameObject().getBoundingBox();
         var o = R.math.Point2D.create(this.getGameObject().getOrigin());

         if (this.mode == R.components.render.Billboard2D.REDRAW) {
            // We'll match the type of context the component is rendering to
            //var ctx = this.getGameObject().getRenderContext().constructor;

            if (!this.billboard) {
               // Due to pooling, we don't need to recreate this each time
               this.billboard = $("");
            }

            this.billboard.attr({
               "src": R.util.RenderUtil.renderComponentToImage(R.rendercontexts.CanvasContext, this.renderComponent,
                       hostBox.w, hostBox.h, null, o),
               "width": hostBox.w,
               "height": hostBox.h
            });

            this.mode = R.components.render.Billboard2D.NORMAL;
         }

         // Render the billboard.  If the bounding box's origin is negative in
         // either X or Y, we'll need to move the transformation there before rendering the object
         this.transformOigin(renderContext, true);
         try {
            renderContext.drawImage(this.getGameObject().getBoundingBox(), this.billboard[0], this.getGameObject());
         }
         catch (ex) {
            // TODO: Find a better way to perform this operation since try/catch is SLOW
            // It appears that Firefox might not have a full image rendered, so calling
            // drawImage fails with a component exception.  To abate this possible issue,
            // we try the call and catch the failure...
         }

         /* pragma:DEBUG_START */
         // Debug the billboard image box
         if (R.Engine.getDebugMode()) {
            renderContext.setLineStyle("green");
            renderContext.drawRectangle(this.getGameObject().getBoundingBox(), this.getGameObject());
         }
         /* pragma:DEBUG_END */

         this.transformOrigin(renderContext, false);
         o.destroy();
      }

   }, /** @scope R.components.render.Billboard2D.prototype */{

      /**
       * Get the class name of this object
       *
       * @return {String} "R.components.render.Billboard2D"
       */
      getClassName: function() {
         return "R.components.render.Billboard2D";
      },

      /**
       * The component will render to a temporary context from which the
       * actual content will be rendered.
       * @type {Number}
       */
      REDRAW: 0,

      /**
       * The component will render the contents of the billboard.
       * @type {Number}
       */
      NORMAL: 1,

      /**
       * A temporary context to which all billboards will render their
       * bitmaps.
       * @private
       */
      tempContext: null

   });
};<commit_msg>Fixed function naming<commit_after>/**
 * The Render Engine
 * BillboardComponent
 *
 * @fileoverview A render component which will render the contents of
 *               a generated image until the contents are updated.
 *
 * @author: Brett Fattori (brettf@renderengine.com)
 * @author: $Author: bfattori $
 * @version: $Revision: 1556 $
 *
 * Copyright (c) 2011 Brett Fattori (brettf@renderengine.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

// The class this file defines and its required classes
R.Engine.define({
   "class": "R.components.render.Billboard2D",
   "requires": [
      "R.components.Render",
      "R.util.RenderUtil",
      "R.text.AbstractTextRenderer",
      "R.math.Point2D"
   ]
});

/**
 * @class The billboard component renders the contents of an image which
 *        was generated by a linked render component.  When the contents
 *        of the linked component are re-rendered, the contents of the
 *        image are updated.  The best usage of this component is for infrequently
 *        changing vector drawn objects.  For example:
 *

 *     // Add component to draw the object
 *     this.add(R.components.Billboard2D.create("draw", R.components.Vector2D.create("vector")));
 *

 *        Accessing the <tt>R.components.Vector2D</tt> within the <tt>R.components.Billboard2D</tt>
 *        is as simple as calling {@link #getComponent}.  If the contents of the linked
 *        component are updated, you will need to call {@link #regenerate} to recreate the
 *        billboard image.
 *
 *
 * @param name {String} The name of the component
 * @param renderComponent {R.components.Render} A render component to create the billboard from
 * @param priority {Number} The priority of the component between 0.0 and 1.0
 * @constructor
 * @extends R.components.Render
 * @description Creates a 2d billboard component.
 */
R.components.render.Billboard2D = function() {
   return R.components.Render.extend(/** @scope R.components.render.Billboard2D.prototype */{

      billboard: null,
      mode: null,
      renderComponent: null,
      hostRect: null,

      /**
       * @private
       */
      constructor: function(name, renderComponent, priority) {
         Assert(renderComponent instanceof R.components.Render ||
               renderComponent instanceof R.text.AbstractTextRenderer, "Attempt to assign a non-render component to a billboard component");
         this.base(name, priority || 0.1);
         this.mode = R.components.render.Billboard2D.REDRAW;
         this.renderComponent = renderComponent;

      },

      /**
       * Destroy the object
       */
      destroy: function() {
         this.renderComponent.destroy();
         this.base();
      },

      /**
       * Releases the component back into the object pool. See {@link R.engine.PooledObject#release}
       * for more information.
       */
      release: function() {
         this.base();
         this.mode = null;
         this.renderComponent = null;
      },

      /**
       * Deprecated in favor of {@link #setGameObject}.
       * @deprecated
       */
      setHostObject: function(hostObject) {
         this.setGameObject(hostObject);
      },

      /**
       * Establishes the link between this component and its game object.
       * When you assign components to a game object, it will call this method
       * so that each component can refer to its game object, the same way
       * a game object can refer to a component with {@link R.engine.GameObject#getComponent}.
       *
       * @param hostObject {R.engine.GameObject} The object which hosts this component
       */
      setGameObject: function(gameObject) {
         this.renderComponent.setGameObject(gameObject);
         this.base(gameObject);
      },

      /**
       * Call this method when the linked render component has been updated
       * to force the billboard to be redrawn.
       */
      regenerate: function() {
         this.mode = R.components.render.Billboard2D.REDRAW;
         this.hostRect = null;
         this.getGameObject().markDirty();
      },

      /**
       * Get the linked render component.
       * @return {R.components.Render}
       */
      getComponent: function() {
         return this.renderComponent;
      },

      /**
       * Draws the contents of the billboard to the render context.  This
       * component operates in one of two modes.  When the contents of the
       * subclassed component are redrawing, a temporary render context is created
       * to which the component renders.  The second mode is where the contents
       * of the context from the first mode are rendered instead of performing
       * all of the operations required to render the component.  This component
       * is only good if the contents don't change often.
       *
       * @param renderContext {R.rendercontexts.AbstractRenderContext} The rendering context
       * @param time {Number} The engine time in milliseconds
       * @param dt {Number} The delta between the world time and the last time the world was updated
       *          in milliseconds.
       */
      execute: function(renderContext, time, dt) {
         if (!this.base(renderContext, time, dt)) {
            return;
         }

         // Get the host object's bounding box
         var hostBox = this.getGameObject().getBoundingBox();
         var o = R.math.Point2D.create(this.getGameObject().getOrigin());

         if (this.mode == R.components.render.Billboard2D.REDRAW) {
            // We'll match the type of context the component is rendering to
            //var ctx = this.getGameObject().getRenderContext().constructor;

            if (!this.billboard) {
               // Due to pooling, we don't need to recreate this each time
               this.billboard = $("");
            }

            this.billboard.attr({
               "src": R.util.RenderUtil.renderComponentToImage(R.rendercontexts.CanvasContext, this.renderComponent,
                       hostBox.w, hostBox.h, null, o),
               "width": hostBox.w,
               "height": hostBox.h
            });

            this.mode = R.components.render.Billboard2D.NORMAL;
         }

         // Render the billboard.  If the bounding box's origin is negative in
         // either X or Y, we'll need to move the transformation there before rendering the object
         this.transformOrigin(renderContext, true);
         try {
            renderContext.drawImage(this.getGameObject().getBoundingBox(), this.billboard[0], this.getGameObject());
         }
         catch (ex) {
            // TODO: Find a better way to perform this operation since try/catch is SLOW
            // It appears that Firefox might not have a full image rendered, so calling
            // drawImage fails with a component exception.  To abate this possible issue,
            // we try the call and catch the failure...
         }

         /* pragma:DEBUG_START */
         // Debug the billboard image box
         if (R.Engine.getDebugMode()) {
            renderContext.setLineStyle("green");
            renderContext.drawRectangle(this.getGameObject().getBoundingBox(), this.getGameObject());
         }
         /* pragma:DEBUG_END */

         this.transformOrigin(renderContext, false);
         o.destroy();
      }

   }, /** @scope R.components.render.Billboard2D.prototype */{

      /**
       * Get the class name of this object
       *
       * @return {String} "R.components.render.Billboard2D"
       */
      getClassName: function() {
         return "R.components.render.Billboard2D";
      },

      /**
       * The component will render to a temporary context from which the
       * actual content will be rendered.
       * @type {Number}
       */
      REDRAW: 0,

      /**
       * The component will render the contents of the billboard.
       * @type {Number}
       */
      NORMAL: 1,

      /**
       * A temporary context to which all billboards will render their
       * bitmaps.
       * @private
       */
      tempContext: null

   });
};<|endoftext|>


<commit_before>DV.model.Annotations = function(viewer) {
  this.LEFT_MARGIN              = 25;
  this.PAGE_NOTE_FUDGE          = window.dc && dc.account && (dc.account.isOwner || dc.account.isReviewer) ? 46 : 26;
  this.viewer                   = viewer;
  this.offsetsAdjustments       = [];
  this.offsetAdjustmentSum      = 0;
  this.saveCallbacks            = [];
  this.deleteCallbacks          = [];
  this.byId                     = this.viewer.schema.data.annotationsById;
  this.byPage                   = this.viewer.schema.data.annotationsByPage;
  this.bySortOrder              = this.sortAnnotations();
};

DV.model.Annotations.prototype = {

  // Render an annotation model to HTML, calculating all of the dimenstions
  // and offsets, and running a template function.
  render: function(annotation){
    var documentModel             = this.viewer.models.document;
    var pageModel                 = this.viewer.models.pages;
    var zoom                      = pageModel.zoomFactor();
    var adata                     = annotation;
    var x1, x2, y1, y2;

    if(adata.type === 'page'){
      x1 = x2 = y1 = y2           = 0;
      adata.top                   = 0;
    }else{
      y1                          = Math.round(adata.y1 * zoom);
      y2                          = Math.round(adata.y2 * zoom);
      if (x1 < this.LEFT_MARGIN) x1 = this.LEFT_MARGIN;
      x1                          = Math.round(adata.x1 * zoom);
      x2                          = Math.round(adata.x2 * zoom);
      adata.top                   = y1 - 5;
    }

    adata.owns_note               = adata.owns_note || false;
    adata.width                   = pageModel.width;
    adata.pageNumber              = adata.page;
    adata.author                  = adata.author || "";
    adata.author_organization     = adata.author_organization || "";
    adata.bgWidth                 = adata.width;
    adata.bWidth                  = adata.width - 66;
    adata.excerptWidth            = (x2 - x1) - 8;
    adata.excerptMarginLeft       = x1 - 3;
    adata.excerptHeight           = y2 - y1;
    adata.index                   = adata.page - 1;
    adata.image                   = pageModel.imageURL(adata.index);
    adata.imageTop                = y1 + 1;
    adata.tabTop                  = (y1 < 35 ? 35 - y1 : 0) + 8;
    adata.imageWidth              = pageModel.width;
    adata.imageHeight             = Math.round(pageModel.height * zoom);
    adata.regionLeft              = x1;
    adata.regionWidth             = x2 - x1 ;
    adata.regionHeight            = y2 - y1;
    adata.excerptDSHeight         = adata.excerptHeight - 6;
    adata.DSOffset                = 3;

    if (adata.access == 'public')         adata.accessClass = 'DV-accessPublic';
    else if (adata.access =='exclusive')  adata.accessClass = 'DV-accessExclusive';
    else if (adata.access =='private')    adata.accessClass = 'DV-accessPrivate';

    adata.orderClass = '';
    adata.options = this.viewer.options;
    if (adata.position == 1) adata.orderClass += ' DV-firstAnnotation';
    if (adata.position == this.bySortOrder.length) adata.orderClass += ' DV-lastAnnotation';

    var template = (adata.type === 'page') ? 'pageAnnotation' : 'annotation';
    return JST[template](adata);
  },

  // Re-sort the list of annotations when its contents change. Annotations
  // are ordered by page primarily, and then their y position on the page.
  sortAnnotations : function() {
    return this.bySortOrder = _.sortBy(_.values(this.byId), function(anno) {
      return anno.page * 10000 + anno.y1;
    });
  },

  // Renders each annotation into it's HTML format.
  renderAnnotations: function(){
    for (var i=0; i<this.bySortOrder.length; i++) {
      var anno      = this.bySortOrder[i];
      anno.of       = _.indexOf(this.byPage[anno.page - 1], anno);
      anno.position = i + 1;
      anno.html     = this.render(anno);
    }
    this.renderAnnotationsByIndex();
  },

  // Renders each annotation for the "Annotation List" tab, in order.
  renderAnnotationsByIndex: function(){
    var rendered  = _.map(this.bySortOrder, function(anno){ return anno.html; });
    var html      = rendered.join('')
                    .replace(/src="/g, 'data-src="')
                    .replace(/id="DV-annotation-(\d+)"/g, function(match, id) {
      return 'id="DV-listAnnotation-' + id + '" rel="aid-' + id + '"';
    });

    this.viewer.$('div.DV-allAnnotations').html(html);

    this.renderAnnotationsByIndex.rendered  = true;
    this.renderAnnotationsByIndex.zoomLevel = this.zoomLevel;

    // TODO: This is hacky, but seems to be necessary. When fixing, be sure to
    // test with both autozoom and page notes.
    this.updateAnnotationOffsets();
    _.defer(_.bind(this.updateAnnotationOffsets, this));
  },

  // Refresh the annotation's title and content from the model, in both
  // The document and list views.
  refreshAnnotation : function(anno) {
    var viewer = this.viewer;
    anno.html = this.render(anno);
    DV.jQuery.$('#DV-annotation-' + anno.id).replaceWith(anno.html);
  },

  // Removes a given annotation from the Annotations model (and DOM).
  removeAnnotation : function(anno) {
    delete this.byId[anno.id];
    var i = anno.page - 1;
    this.byPage[i] = _.without(this.byPage[i], anno);
    this.sortAnnotations();
    DV.jQuery('#DV-annotation-' + anno.id + ', #DV-listAnnotation-' + anno.id).remove();
    this.viewer.api.redraw(true);
    if (_.isEmpty(this.byId)) this.viewer.open('ViewDocument');
  },

  // Offsets all document pages based on interleaved page annotations.
  updateAnnotationOffsets: function(){
    this.offsetsAdjustments   = [];
    this.offsetAdjustmentSum  = 0;
    var documentModel         = this.viewer.models.document;
    var annotationsContainer  = this.viewer.$('div.DV-allAnnotations');
    var pageAnnotationEls     = annotationsContainer.find('.DV-pageNote');
    var pageNoteHeights       = this.viewer.models.pages.pageNoteHeights;
    var me = this;

    if(this.viewer.$('div.DV-docViewer').hasClass('DV-viewAnnotations') == false){
      annotationsContainer.addClass('DV-getHeights');
    }

    // First, collect the list of page annotations, and associate them with
    // their DOM elements.
    var pageAnnos = [];
    _.each(_.select(this.bySortOrder, function(anno) {
      return anno.type == 'page';
    }), function(anno, i) {
      anno.el = pageAnnotationEls[i];
      pageAnnos[anno.pageNumber] = anno;
    });

    // Then, loop through the pages and store the cumulative offset due to
    // page annotations.
    for (var i = 0, len = documentModel.totalPages; i <= len; i++) {
      pageNoteHeights[i] = 0;
      if (pageAnnos[i]) {
        var height = (this.viewer.$(pageAnnos[i].el).height() + this.PAGE_NOTE_FUDGE);
        pageNoteHeights[i - 1] = height;
        this.offsetAdjustmentSum += height;
      }
      this.offsetsAdjustments[i] = this.offsetAdjustmentSum;
    }
    annotationsContainer.removeClass('DV-getHeights');
  },

  // When an annotation is successfully saved, fire any registered
  // save callbacks.
  fireSaveCallbacks : function(anno) {
    _.each(this.saveCallbacks, function(c){ c(anno); });
  },

  // When an annotation is successfully removed, fire any registered
  // delete callbacks.
  fireDeleteCallbacks : function(anno) {
    _.each(this.deleteCallbacks, function(c){ c(anno); });
  },

  // Returns the list of annotations on a given page.
  getAnnotations: function(_index){
    return this.byPage[_index];
  },

  getFirstAnnotation: function(){
    return _.first(this.bySortOrder);
  },

  getNextAnnotation: function(currentId) {
    var anno = this.byId[currentId];
    return this.bySortOrder[_.indexOf(this.bySortOrder, anno) + 1];
  },

  getPreviousAnnotation: function(currentId) {
    var anno = this.byId[currentId];
    return this.bySortOrder[_.indexOf(this.bySortOrder, anno) - 1];
  },

  // Get an annotation by id, with backwards compatibility for argument hashes.
  getAnnotation: function(identifier) {
    if (identifier.id) return this.byId[identifier.id];
    if (identifier.index && !identifier.id) throw new Error('looked up an annotation without an id');
    return this.byId[identifier];
  }

};
<commit_msg>doing a sketchy fix for images-in-annotation-text.<commit_after>DV.model.Annotations = function(viewer) {
  this.LEFT_MARGIN              = 25;
  this.PAGE_NOTE_FUDGE          = window.dc && dc.account && (dc.account.isOwner || dc.account.isReviewer) ? 46 : 26;
  this.viewer                   = viewer;
  this.offsetsAdjustments       = [];
  this.offsetAdjustmentSum      = 0;
  this.saveCallbacks            = [];
  this.deleteCallbacks          = [];
  this.byId                     = this.viewer.schema.data.annotationsById;
  this.byPage                   = this.viewer.schema.data.annotationsByPage;
  this.bySortOrder              = this.sortAnnotations();
};

DV.model.Annotations.prototype = {

  // Render an annotation model to HTML, calculating all of the dimenstions
  // and offsets, and running a template function.
  render: function(annotation){
    var documentModel             = this.viewer.models.document;
    var pageModel                 = this.viewer.models.pages;
    var zoom                      = pageModel.zoomFactor();
    var adata                     = annotation;
    var x1, x2, y1, y2;

    if(adata.type === 'page'){
      x1 = x2 = y1 = y2           = 0;
      adata.top                   = 0;
    }else{
      y1                          = Math.round(adata.y1 * zoom);
      y2                          = Math.round(adata.y2 * zoom);
      if (x1 < this.LEFT_MARGIN) x1 = this.LEFT_MARGIN;
      x1                          = Math.round(adata.x1 * zoom);
      x2                          = Math.round(adata.x2 * zoom);
      adata.top                   = y1 - 5;
    }

    adata.owns_note               = adata.owns_note || false;
    adata.width                   = pageModel.width;
    adata.pageNumber              = adata.page;
    adata.author                  = adata.author || "";
    adata.author_organization     = adata.author_organization || "";
    adata.bgWidth                 = adata.width;
    adata.bWidth                  = adata.width - 66;
    adata.excerptWidth            = (x2 - x1) - 8;
    adata.excerptMarginLeft       = x1 - 3;
    adata.excerptHeight           = y2 - y1;
    adata.index                   = adata.page - 1;
    adata.image                   = pageModel.imageURL(adata.index);
    adata.imageTop                = y1 + 1;
    adata.tabTop                  = (y1 < 35 ? 35 - y1 : 0) + 8;
    adata.imageWidth              = pageModel.width;
    adata.imageHeight             = Math.round(pageModel.height * zoom);
    adata.regionLeft              = x1;
    adata.regionWidth             = x2 - x1 ;
    adata.regionHeight            = y2 - y1;
    adata.excerptDSHeight         = adata.excerptHeight - 6;
    adata.DSOffset                = 3;

    if (adata.access == 'public')         adata.accessClass = 'DV-accessPublic';
    else if (adata.access =='exclusive')  adata.accessClass = 'DV-accessExclusive';
    else if (adata.access =='private')    adata.accessClass = 'DV-accessPrivate';

    adata.orderClass = '';
    adata.options = this.viewer.options;
    if (adata.position == 1) adata.orderClass += ' DV-firstAnnotation';
    if (adata.position == this.bySortOrder.length) adata.orderClass += ' DV-lastAnnotation';

    var template = (adata.type === 'page') ? 'pageAnnotation' : 'annotation';
    return JST[template](adata);
  },

  // Re-sort the list of annotations when its contents change. Annotations
  // are ordered by page primarily, and then their y position on the page.
  sortAnnotations : function() {
    return this.bySortOrder = _.sortBy(_.values(this.byId), function(anno) {
      return anno.page * 10000 + anno.y1;
    });
  },

  // Renders each annotation into it's HTML format.
  renderAnnotations: function(){
    for (var i=0; i<this.bySortOrder.length; i++) {
      var anno      = this.bySortOrder[i];
      anno.of       = _.indexOf(this.byPage[anno.page - 1], anno);
      anno.position = i + 1;
      anno.html     = this.render(anno);
    }
    this.renderAnnotationsByIndex();
  },

  // Renders each annotation for the "Annotation List" tab, in order.
  renderAnnotationsByIndex: function(){
    var rendered  = _.map(this.bySortOrder, function(anno){ return anno.html; });
    var html      = rendered.join('')
                    .replace(/class="DV-img" src="/g, 'class="DV-img" data-src="')
                    .replace(/id="DV-annotation-(\d+)"/g, function(match, id) {
      return 'id="DV-listAnnotation-' + id + '" rel="aid-' + id + '"';
    });

    this.viewer.$('div.DV-allAnnotations').html(html);

    this.renderAnnotationsByIndex.rendered  = true;
    this.renderAnnotationsByIndex.zoomLevel = this.zoomLevel;

    // TODO: This is hacky, but seems to be necessary. When fixing, be sure to
    // test with both autozoom and page notes.
    this.updateAnnotationOffsets();
    _.defer(_.bind(this.updateAnnotationOffsets, this));
  },

  // Refresh the annotation's title and content from the model, in both
  // The document and list views.
  refreshAnnotation : function(anno) {
    var viewer = this.viewer;
    anno.html = this.render(anno);
    DV.jQuery.$('#DV-annotation-' + anno.id).replaceWith(anno.html);
  },

  // Removes a given annotation from the Annotations model (and DOM).
  removeAnnotation : function(anno) {
    delete this.byId[anno.id];
    var i = anno.page - 1;
    this.byPage[i] = _.without(this.byPage[i], anno);
    this.sortAnnotations();
    DV.jQuery('#DV-annotation-' + anno.id + ', #DV-listAnnotation-' + anno.id).remove();
    this.viewer.api.redraw(true);
    if (_.isEmpty(this.byId)) this.viewer.open('ViewDocument');
  },

  // Offsets all document pages based on interleaved page annotations.
  updateAnnotationOffsets: function(){
    this.offsetsAdjustments   = [];
    this.offsetAdjustmentSum  = 0;
    var documentModel         = this.viewer.models.document;
    var annotationsContainer  = this.viewer.$('div.DV-allAnnotations');
    var pageAnnotationEls     = annotationsContainer.find('.DV-pageNote');
    var pageNoteHeights       = this.viewer.models.pages.pageNoteHeights;
    var me = this;

    if(this.viewer.$('div.DV-docViewer').hasClass('DV-viewAnnotations') == false){
      annotationsContainer.addClass('DV-getHeights');
    }

    // First, collect the list of page annotations, and associate them with
    // their DOM elements.
    var pageAnnos = [];
    _.each(_.select(this.bySortOrder, function(anno) {
      return anno.type == 'page';
    }), function(anno, i) {
      anno.el = pageAnnotationEls[i];
      pageAnnos[anno.pageNumber] = anno;
    });

    // Then, loop through the pages and store the cumulative offset due to
    // page annotations.
    for (var i = 0, len = documentModel.totalPages; i <= len; i++) {
      pageNoteHeights[i] = 0;
      if (pageAnnos[i]) {
        var height = (this.viewer.$(pageAnnos[i].el).height() + this.PAGE_NOTE_FUDGE);
        pageNoteHeights[i - 1] = height;
        this.offsetAdjustmentSum += height;
      }
      this.offsetsAdjustments[i] = this.offsetAdjustmentSum;
    }
    annotationsContainer.removeClass('DV-getHeights');
  },

  // When an annotation is successfully saved, fire any registered
  // save callbacks.
  fireSaveCallbacks : function(anno) {
    _.each(this.saveCallbacks, function(c){ c(anno); });
  },

  // When an annotation is successfully removed, fire any registered
  // delete callbacks.
  fireDeleteCallbacks : function(anno) {
    _.each(this.deleteCallbacks, function(c){ c(anno); });
  },

  // Returns the list of annotations on a given page.
  getAnnotations: function(_index){
    return this.byPage[_index];
  },

  getFirstAnnotation: function(){
    return _.first(this.bySortOrder);
  },

  getNextAnnotation: function(currentId) {
    var anno = this.byId[currentId];
    return this.bySortOrder[_.indexOf(this.bySortOrder, anno) + 1];
  },

  getPreviousAnnotation: function(currentId) {
    var anno = this.byId[currentId];
    return this.bySortOrder[_.indexOf(this.bySortOrder, anno) - 1];
  },

  // Get an annotation by id, with backwards compatibility for argument hashes.
  getAnnotation: function(identifier) {
    if (identifier.id) return this.byId[identifier.id];
    if (identifier.index && !identifier.id) throw new Error('looked up an annotation without an id');
    return this.byId[identifier];
  }

};
<|endoftext|>


<commit_before>const PropTypes = require('prop-types');
/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react')

const SocialFooter = props => (

Social

        {props.config.projectName}

    {props.config.twitterUsername && (

        <a
          href={`https://twitter.com/${props.config.twitterUsername}`}
          className="twitter-follow-button">
          Follow @{props.config.twitterUsername}

    )}
    {props.config.facebookAppId && (

    )}

);

SocialFooter.propTypes = {
  config: PropTypes.object,
};

class Footer extends React.Component {
  docUrl(doc, language) {
    const baseUrl = this.props.config.baseUrl
    return baseUrl + 'docs/' + (language ? language + '/' : '') + doc
  }

  pageUrl(doc, language) {
    const baseUrl = this.props.config.baseUrl
    return baseUrl + (language ? language + '/' : '') + doc
  }

  render() {
    const currentYear = new Date().getFullYear()
    return (

            {this.props.config.footerIcon && (

            )}

Docs

              Getting Started

              Usage

            Other

Community

              User Showcase

              Stack Overflow

            Project Chat
            Donate
            Blog

          <SocialFooter config={this.props.config} />

{this.props.config.copyright}

    )
  }
}

module.exports = Footer
<commit_msg>Update Footer.js<commit_after>const PropTypes = require('prop-types');
/**
 * Copyright (c) 2017-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

const React = require('react')

const SocialFooter = props => (

Social

        {props.config.projectName}

    {props.config.twitterUsername && (

        <a
          href={`https://twitter.com/${props.config.twitterUsername}`}
          className="twitter-follow-button">
          Follow @{props.config.twitterUsername}

    )}
    {props.config.facebookAppId && (

    )}

);

SocialFooter.propTypes = {
  config: PropTypes.object,
};

class Footer extends React.Component {
  docUrl(doc, language) {
    const baseUrl = this.props.config.baseUrl
    return baseUrl + 'docs/' + (language ? language + '/' : '') + doc
  }

  pageUrl(doc, language) {
    const baseUrl = this.props.config.baseUrl
    return baseUrl + (language ? language + '/' : '') + doc
  }

  render() {
    const currentYear = new Date().getFullYear()
    return (

            {this.props.config.footerIcon && (

            )}

Docs

              Getting Started

              Usage

            Other

Community

              User Showcase

              Stack Overflow

            Project Chat
            Donate
            Blog

          <SocialFooter config={this.props.config} />

{this.props.config.copyright}

    )
  }
}

module.exports = Footer
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
 * ALL RIGHTS RESERVED.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
 * nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 *
 * This work has been performed in the framework of the SONATA project,
 * funded by the European Commission under Grant number 671517 through
 * the Horizon 2020 and 5G-PPP programmes. The authors would like to
 * acknowledge the contributions of their colleagues of the SONATA
 * partner consortium (www.sonata-nfv.eu).* dirPagination - AngularJS module for paginating (almost) anything.
 */

 describe('SonataBSS User Management.', function() {

    describe('Register View:', function(){

        beforeEach(function() {
            browser.driver.manage().window().maximize();
            browser.get('https://'+browser.params.host+':'+browser.params.port);
        });

        it('title must be SonataBSS', function() {
            expect(browser.getTitle()).toEqual('SonataBSS');
        });

        it('redirection to login page', function() {
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });

        it('registration successful', function() {
            browser.driver.findElement(by.xpath('//a[. = "Register"]')).click();
            browser.driver.findElement(by.id('firstName')).sendKeys('sonata');
            browser.driver.findElement(by.id('lastName')).sendKeys('sonata');
            browser.driver.findElement(by.id('username')).sendKeys('sonata');
            browser.driver.findElement(by.id('password')).sendKeys('sonata');
            browser.driver.findElement(by.id('userEmail')).sendKeys('sonata@mail.com');
            browser.driver.findElement(by.xpath('//button[. = "Register"]')).click();
            modal = element(by.id('success'));
            expect(modal.isDisplayed()).toBe(true);
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });
    });

    describe('Login View:', function(){

        beforeEach(function() {
            browser.driver.manage().window().maximize();
            browser.get('https://'+browser.params.host+':'+browser.params.port);
        });

        it('title must be SonataBSS', function() {
            expect(browser.getTitle()).toEqual('SonataBSS');
        });

        it('redirection to login page', function() {
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });

        it('login successful; redirection to NSDs page', function() {
            browser.driver.findElement(by.id('username')).sendKeys('sonata');
            browser.driver.findElement(by.id('password')).sendKeys('sonata');
            browser.driver.findElement(by.xpath('//button[. = "Login"]')).click();
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/nSDs');
        });
    });
});<commit_msg>usr-management: new registration fields<commit_after>/**
 * Copyright (c) 2015 SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
 * ALL RIGHTS RESERVED.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Neither the name of the SONATA-NFV [, ANY ADDITIONAL AFFILIATION]
 * nor the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 *
 * This work has been performed in the framework of the SONATA project,
 * funded by the European Commission under Grant number 671517 through
 * the Horizon 2020 and 5G-PPP programmes. The authors would like to
 * acknowledge the contributions of their colleagues of the SONATA
 * partner consortium (www.sonata-nfv.eu).* dirPagination - AngularJS module for paginating (almost) anything.
 */

 describe('SonataBSS User Management.', function() {

    describe('Register View:', function(){

        beforeEach(function() {
            browser.driver.manage().window().maximize();
            browser.get('https://'+browser.params.host+':'+browser.params.port);
        });

        it('title must be SonataBSS', function() {
            expect(browser.getTitle()).toEqual('SonataBSS');
        });

        it('redirection to login page', function() {
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });

        it('registration successful', function() {
            browser.driver.findElement(by.xpath('//a[. = "Register"]')).click();
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/register');
            browser.driver.findElement(by.id('firstName')).sendKeys('sonata');
            browser.driver.findElement(by.id('lastName')).sendKeys('sonata');
            browser.driver.findElement(by.id('username')).sendKeys('sonata');
            browser.driver.findElement(by.id('password')).sendKeys('sonata');
            browser.driver.findElement(by.id('userEmail')).sendKeys('sonata@mail.com');
            browser.driver.findElement(by.xpath('//button[. = "Register"]')).click();
            modal = element(by.id('success'));
            expect(modal.isDisplayed()).toBe(true);
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });
    });

    describe('Login View:', function(){

        beforeEach(function() {
            browser.driver.manage().window().maximize();
            browser.get('https://'+browser.params.host+':'+browser.params.port);
        });

        it('title must be SonataBSS', function() {
            expect(browser.getTitle()).toEqual('SonataBSS');
        });

        it('redirection to login page', function() {
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/login');
        });

        it('login successful; redirection to NSDs page', function() {
            browser.driver.findElement(by.id('username')).sendKeys('sonata');
            browser.driver.findElement(by.id('password')).sendKeys('sonata');
            browser.driver.findElement(by.xpath('//button[. = "Login"]')).click();
            expect(browser.getCurrentUrl()).toBe('https://'+browser.params.host+':'+browser.params.port+'/#/nSDs');
        });
    });
});<|endoftext|>


<commit_before>'use strict';
module.exports = function(resolve) { // eslint-disable-line func-names
  // Global variables
  const gulp    = this.gulp,
        plugins = this.opts.plugins,
        config  = this.opts.configs,
        themes  = plugins.getThemes();

  plugins.path                 = require('path');
  plugins.helper               = {};
  plugins.helper.babel         = require('../helper/babel');
  plugins.helper.cssLint       = require('../helper/css-lint');
  plugins.helper.dependecyTree = require('../helper/dependency-tree-builder');
  plugins.helper.inheritance   = require('../helper/inheritance-resolver');
  plugins.helper.sass          = require('../helper/scss');
  plugins.helper.sassLint      = require('../helper/sass-lint');

  plugins.util.log(
    plugins.util.colors.yellow('Initializing watcher...')
  );

  themes.forEach(name => {
    const theme = config.themes[name],
          themeTempSrc = config.tempPath + theme.dest.replace('pub/static', ''),
          themeDest = config.projectPath + theme.dest,
          themeSrc = [config.projectPath + theme.src];

    // Add modules source directeoried to theme source paths array
    if (theme.modules) {
      Object.keys(theme.modules).forEach(module => {
        themeSrc.push(config.projectPath + theme.modules[module]);
      });
    }

    // Initialize watchers
    const tempWatcher = plugins.chokidar.watch(themeTempSrc, {
            ignoreInitial: true
          }),
          srcWatcher = plugins.chokidar.watch(themeSrc, {
            ignoreInitial: true
          }),
          destWatcher = plugins.chokidar.watch(themeDest, {
            ignoreInitial: true
          });

    let reinitTimeout = false,
        sassDependecyTree = {};

    function generateSassDependencyTree() {
      // Cleanup tree
      sassDependecyTree = {};

      // Find all main SASS files
      plugins.globby.sync([
        themeTempSrc + '/**/*.scss',
        '!/**/_*.scss'
      ]).forEach(file => {
        // Generate array of main file dependecies
        sassDependecyTree[file] = plugins.helper.dependecyTree(plugins, file);
      });
    }

    generateSassDependencyTree();

    function reinitialize(path) {
      // Reset previously set timeout
      clearTimeout(reinitTimeout);

      // Timeout to run only once while moving or renaming files
      reinitTimeout = setTimeout(() => {
        plugins.util.log(
          plugins.util.colors.yellow('Change detected.') + ' ' +
          plugins.util.colors.green('Theme:') + ' ' +
          plugins.util.colors.blue(name) + ' ' +
          plugins.util.colors.green('File:') + ' ' +
          plugins.util.colors.blue(plugins.path.relative(config.projectPath, path))
        );

        plugins.util.log(
          plugins.util.colors.yellow('Resolving inheritance.') + ' ' +
          plugins.util.colors.green('Theme:') + ' ' +
          plugins.util.colors.blue(name)
        );

        // Disable watcher to not fire tons of events while solving inheritance
        tempWatcher.unwatch(themeTempSrc);

        // Run inheritance resolver just for one theme without parent(s)
        plugins.helper.inheritance(plugins, config, name, false);

        // Regenerate SASS Dependency Tree
        generateSassDependencyTree();

        // Add all files to watch again after solving inheritance
        tempWatcher.add(themeTempSrc);

        // Emit event on added / moved / renamed / deleted file to trigger regualr pipeline
        plugins.globby.sync(themeTempSrc + '/**/' + plugins.path.basename(path))
          .forEach(file => {
            tempWatcher.emit('change', file);
          });
      }, 100);
    }

    // Watch add / move / rename / delete events on source files
    srcWatcher
      .on('add', reinitialize)
      .on('addDir', reinitialize)
      .on('unlink', reinitialize)
      .on('unlinkDir', reinitialize);

    // print msg when temp dir watcher is initialized
    tempWatcher.on('ready', () => {
      plugins.util.log(
        plugins.util.colors.yellow('Watcher initialized!') + ' ' +
        plugins.util.colors.green('Theme:') + ' ' +
        plugins.util.colors.blue(name) + ' ' +
        plugins.util.colors.green('and dependencies...')
      );
    });

    // Events handling
    tempWatcher.on('change', path => {
      // Print message to know what's going on
      plugins.util.log(
        plugins.util.colors.yellow('Change detected.') + ' ' +
        plugins.util.colors.green('Theme:') + ' ' +
        plugins.util.colors.blue(name) + ' ' +
        plugins.util.colors.green('File:') + ' ' +
        plugins.util.colors.blue(plugins.path.relative(config.projectPath, path))
      );

      // SASS Lint
      if (!plugins.util.env.disableLinting) {
        if (plugins.path.extname(path) === '.scss') {
          plugins.helper.sassLint(gulp, plugins, config, name, path);
        }
      }
      // SASS Compilation
      if (plugins.path.extname(path) === '.scss') {
        Object.keys(sassDependecyTree).forEach(file => {
          if (sassDependecyTree[file].includes(path)) {
            plugins.helper.sass(gulp, plugins, config, name, file);
          }
        });
      }

      // Babel
      if (plugins.path.basename(path).includes('.babel.js')) {
        plugins.helper.babel(gulp, plugins, config, name, path);
      }

      // Files that require reload after save
      if (['.html', '.phtml', '.xml', '.csv', '.js'].some(ext => {
        return plugins.path.extname(path) === ext;
      })) {
        plugins.browserSync.reload();
      }
    });

    destWatcher.on('change', path => {
      // CSS Lint
      if (plugins.path.extname(path) === '.css') {
        plugins.helper.cssLint(gulp, plugins, config, name, path);
      }
    });
  });

  return resolve;
};
<commit_msg>Fix for issues reported by ESLint <commit_after>'use strict';
module.exports = function(resolve) { // eslint-disable-line func-names
  // Global variables
  const gulp    = this.gulp,
        plugins = this.opts.plugins,
        config  = this.opts.configs,
        themes  = plugins.getThemes();

  plugins.path                 = require('path');
  plugins.helper               = {};
  plugins.helper.babel         = require('../helper/babel');
  plugins.helper.cssLint       = require('../helper/css-lint');
  plugins.helper.dependecyTree = require('../helper/dependency-tree-builder');
  plugins.helper.inheritance   = require('../helper/inheritance-resolver');
  plugins.helper.sass          = require('../helper/scss');
  plugins.helper.sassLint      = require('../helper/sass-lint');

  plugins.util.log(
    plugins.util.colors.yellow('Initializing watcher...')
  );

  themes.forEach(name => {
    const theme = config.themes[name],
          themeTempSrc = config.tempPath + theme.dest.replace('pub/static', ''),
          themeDest = config.projectPath + theme.dest,
          themeSrc = [config.projectPath + theme.src];

    // Add modules source directeoried to theme source paths array
    if (theme.modules) {
      Object.keys(theme.modules).forEach(module => {
        themeSrc.push(config.projectPath + theme.modules[module]);
      });
    }

    // Initialize watchers
    const tempWatcher = plugins.chokidar.watch(themeTempSrc, { // eslint-disable-line one-var
            ignoreInitial: true
          }),
          srcWatcher = plugins.chokidar.watch(themeSrc, {
            ignoreInitial: true
          }),
          destWatcher = plugins.chokidar.watch(themeDest, {
            ignoreInitial: true
          });

    let reinitTimeout = false,
        sassDependecyTree = {};

    function generateSassDependencyTree() {
      // Cleanup tree
      sassDependecyTree = {};

      // Find all main SASS files
      plugins.globby.sync([
        themeTempSrc + '/**/*.scss',
        '!/**/_*.scss'
      ]).forEach(file => {
        // Generate array of main file dependecies
        sassDependecyTree[file] = plugins.helper.dependecyTree(plugins, file);
      });
    }

    generateSassDependencyTree();

    function reinitialize(path) {
      // Reset previously set timeout
      clearTimeout(reinitTimeout);

      // Timeout to run only once while moving or renaming files
      reinitTimeout = setTimeout(() => {
        plugins.util.log(
          plugins.util.colors.yellow('Change detected.') + ' ' +
          plugins.util.colors.green('Theme:') + ' ' +
          plugins.util.colors.blue(name) + ' ' +
          plugins.util.colors.green('File:') + ' ' +
          plugins.util.colors.blue(plugins.path.relative(config.projectPath, path))
        );

        plugins.util.log(
          plugins.util.colors.yellow('Resolving inheritance.') + ' ' +
          plugins.util.colors.green('Theme:') + ' ' +
          plugins.util.colors.blue(name)
        );

        // Disable watcher to not fire tons of events while solving inheritance
        tempWatcher.unwatch(themeTempSrc);

        // Run inheritance resolver just for one theme without parent(s)
        plugins.helper.inheritance(plugins, config, name, false);

        // Regenerate SASS Dependency Tree
        generateSassDependencyTree();

        // Add all files to watch again after solving inheritance
        tempWatcher.add(themeTempSrc);

        // Emit event on added / moved / renamed / deleted file to trigger regualr pipeline
        plugins.globby.sync(themeTempSrc + '/**/' + plugins.path.basename(path))
          .forEach(file => {
            tempWatcher.emit('change', file);
          });
      }, 100);
    }

    // Watch add / move / rename / delete events on source files
    srcWatcher
      .on('add', reinitialize)
      .on('addDir', reinitialize)
      .on('unlink', reinitialize)
      .on('unlinkDir', reinitialize);

    // print msg when temp dir watcher is initialized
    tempWatcher.on('ready', () => {
      plugins.util.log(
        plugins.util.colors.yellow('Watcher initialized!') + ' ' +
        plugins.util.colors.green('Theme:') + ' ' +
        plugins.util.colors.blue(name) + ' ' +
        plugins.util.colors.green('and dependencies...')
      );
    });

    // Events handling
    tempWatcher.on('change', path => {
      // Print message to know what's going on
      plugins.util.log(
        plugins.util.colors.yellow('Change detected.') + ' ' +
        plugins.util.colors.green('Theme:') + ' ' +
        plugins.util.colors.blue(name) + ' ' +
        plugins.util.colors.green('File:') + ' ' +
        plugins.util.colors.blue(plugins.path.relative(config.projectPath, path))
      );

      // SASS Lint
      if (!plugins.util.env.disableLinting) {
        if (plugins.path.extname(path) === '.scss') {
          plugins.helper.sassLint(gulp, plugins, config, name, path);
        }
      }
      // SASS Compilation
      if (plugins.path.extname(path) === '.scss') {
        Object.keys(sassDependecyTree).forEach(file => {
          if (sassDependecyTree[file].includes(path)) {
            plugins.helper.sass(gulp, plugins, config, name, file);
          }
        });
      }

      // Babel
      if (plugins.path.basename(path).includes('.babel.js')) {
        plugins.helper.babel(gulp, plugins, config, name, path);
      }

      // Files that require reload after save
      if (['.html', '.phtml', '.xml', '.csv', '.js'].some(ext => {
        return plugins.path.extname(path) === ext;
      })) {
        plugins.browserSync.reload();
      }
    });

    destWatcher.on('change', path => {
      // CSS Lint
      if (plugins.path.extname(path) === '.css') {
        plugins.helper.cssLint(gulp, plugins, config, name, path);
      }
    });
  });

  return resolve;
};
<|endoftext|>


<commit_before>var logger = (require('../logging/vip-winston')).Logger;
var edn = require("jsedn");
var sender = require ("./sender");

var sendAddressFileMessage = null;

var logAndThrowPossibleError = function(err) {
  if (err !== null) {
    logger.error(err);
    throw err;
  }
}

var generateUUID = function() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
};

var submitAddressFile = function(bucketName, fileName, groupName) {
  var transactionId = generateUUID();
  console.log(transactionId);
  if (sendAddressFileMessage != null) {
    sendAddressFileMessage(new Buffer(edn.encode({"bucketName": bucketName,
                                                  "fileName": fileName,
                                                  "groupName": groupName,
                                                  "transactionId": transactionId})));
  } else {
    throw "Not connected to message queue for address file processing."
  }
};

var setupAddressFileRequest = function(ch) {
  ch.assertQueue('batch-address.file.submit', {}, function(err, ok) {
    logAndThrowPossibleError(err);

    var queue = ok.queue;
    sendAddressFileMessage = function(contents) {
      ch.sendToQueue(queue, contents);
    };
    logger.info("Connected to batch-address.file.submit queue");
  });
};

var processAddressFileResponse = function(msg) {
  var message = edn.toJS(edn.parse(msg.content.toString()));
  logger.info(message);
  sender.sendNotifications(message);
};

var setupAddressFileResponse = function(ch) {
  ch.assertQueue('batch-address.file.complete', {}, function(err, ok) {
    logAndThrowPossibleError(err);

    var queue = ok.queue;

    // TODO: remove noAck and do actual acknowledgement
    ch.consume(queue, processAddressFileResponse, {noAck: true}, logAndThrowPossibleError);
    logger.info("Connected to batch-address.file.complete queue");
  });
};

exports.submitAddressFile = submitAddressFile;
exports.setupAddressFileRequest = setupAddressFileRequest;
exports.setupAddressFileResponse = setupAddressFileResponse;
<commit_msg>better name for transaction id function, added attribution<commit_after>var logger = (require('../logging/vip-winston')).Logger;
var edn = require("jsedn");
var sender = require ("./sender");

var sendAddressFileMessage = null;

var logAndThrowPossibleError = function(err) {
  if (err !== null) {
    logger.error(err);
    throw err;
  }
}

var generatePseudoRandomRequestID = function() {
  // function used to generate pseudo-random numbers to be used as transactionIds
  // adapted from here: https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript#2117523
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
    return v.toString(16);
  });
};

var submitAddressFile = function(bucketName, fileName, groupName) {
  var transactionId = generatePseudoRandomRequestID();
  console.log(transactionId);
  if (sendAddressFileMessage != null) {
    sendAddressFileMessage(new Buffer(edn.encode({"bucketName": bucketName,
                                                  "fileName": fileName,
                                                  "groupName": groupName,
                                                  "transactionId": transactionId})));
  } else {
    throw "Not connected to message queue for address file processing."
  }
};

var setupAddressFileRequest = function(ch) {
  ch.assertQueue('batch-address.file.submit', {}, function(err, ok) {
    logAndThrowPossibleError(err);

    var queue = ok.queue;
    sendAddressFileMessage = function(contents) {
      ch.sendToQueue(queue, contents);
    };
    logger.info("Connected to batch-address.file.submit queue");
  });
};

var processAddressFileResponse = function(msg) {
  var message = edn.toJS(edn.parse(msg.content.toString()));
  logger.info(message);
  sender.sendNotifications(message);
};

var setupAddressFileResponse = function(ch) {
  ch.assertQueue('batch-address.file.complete', {}, function(err, ok) {
    logAndThrowPossibleError(err);

    var queue = ok.queue;

    // TODO: remove noAck and do actual acknowledgement
    ch.consume(queue, processAddressFileResponse, {noAck: true}, logAndThrowPossibleError);
    logger.info("Connected to batch-address.file.complete queue");
  });
};

exports.submitAddressFile = submitAddressFile;
exports.setupAddressFileRequest = setupAddressFileRequest;
exports.setupAddressFileResponse = setupAddressFileResponse;
<|endoftext|>


<commit_before>define(['require'],function(require){
	var page_type=window.tu_page_type;
	return {
		init:function(){
			require(['css!template/css/common.css']);
			if(page_type =="index"){
				require(['css!template/css/page.css']);
			}
		}
	}
});
<commit_msg>added<commit_after>define(['require'],function(require){
	var page_type=window.tu_page_type;
	return {
		init:function(){
			require(['css!template/css/common.css','scripts']);
			if(page_type =="index"){
				require(['home','css!template/css/page.css']);
			}
		}
	}
});
<|endoftext|>