<commit_before>
$.get("/vendor/product", function(data) {
  // Grab product list container tbody element
  $list = $("#listBody");

  // Initialize counter (for auto-UPN population) and htmlString (for table row population)
  var counter = 1;
  var htmlString = '';

  // Loop through product data from DB and format
  data.forEach(function(curr, i, arr) {
    htmlString += '
';

    // Remove button generated by checking product's _id property
    htmlString += '<form action="/vendor/product/' + curr._id + '" method="POST"><input type="submit" value="Remove"></input></form>	';

    // Loop through each product to fill s
    for(var j = 1; j < Object.keys(curr).length - 1; j++) {
                                      // Here, using the 'numeral' library to format 2nd column as currency
      j === 2 ? htmlString += '' + numeral(Number(curr[Object.keys(curr)[j]])).format('$0,0.00') + ' /	'
              : htmlString += '' + curr[Object.keys(curr)[j]] + '	';
    }
    htmlString += '
';
    counter++;
  });

  // Fill the table with the new string
  $list.append(htmlString);

  // Set UPN automatically to the new number of products + 1
  $('#UPN').val(counter);
});

var displayResults = function(data) {
  $result = $('#searchResult');
  var htmlString = '';
  data.forEach(function(curr, i, arr) {
    htmlString += '
';
    for(var j = 1; j < Object.keys(curr).length - 1; j++) {
      j === 2 ? htmlString += '' + numeral(Number(curr[Object.keys(curr)[j]])).format('$0,0.00') + ' /	'
              : htmlString += '' + curr[Object.keys(curr)[j]] + '	';
    }
    htmlString += '
';
  });
  $result.append(htmlString);
};
<commit_msg>changed search to only allow one result at a time<commit_after>
$.get("/vendor/product", function(data) {
  // Grab product list container tbody element
  $list = $("#listBody");

  // Initialize counter (for auto-UPN population) and htmlString (for table row population)
  var counter = 1;
  var htmlString = '';

  // Loop through product data from DB and format
  data.forEach(function(curr, i, arr) {
    htmlString += '
';

    // Remove button generated by checking product's _id property
    htmlString += '<form action="/vendor/product/' + curr._id + '" method="POST"><input type="submit" value="Remove"></input></form>	';

    // Loop through each product to fill s
    for(var j = 1; j < Object.keys(curr).length - 1; j++) {
                                      // Here, using the 'numeral' library to format 2nd column as currency
      j === 2 ? htmlString += '' + numeral(Number(curr[Object.keys(curr)[j]])).format('$0,0.00') + ' /	'
              : htmlString += '' + curr[Object.keys(curr)[j]] + '	';
    }
    htmlString += '
';
    counter++;
  });

  // Fill the table with the new string
  $list.append(htmlString);

  // Set UPN automatically to the new number of products + 1
  $('#UPN').val(counter);
});

// Display search results function (sans button)
var displayResults = function(data) {
  $result = $('#searchResult');
  var htmlString = '';
  data.forEach(function(curr, i, arr) {
    htmlString += '
';
    for(var j = 1; j < Object.keys(curr).length - 1; j++) {
      j === 2 ? htmlString += '' + numeral(Number(curr[Object.keys(curr)[j]])).format('$0,0.00') + ' /	'
              : htmlString += '' + curr[Object.keys(curr)[j]] + '	';
    }
    htmlString += '
';
  });
  $result.html(htmlString);
};
<|endoftext|>


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

RED.settings = (function () {
    var loadedSettings = {};
    var hasLocalStorage = function () {
        try {
            return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
            return false;
        }
    };

    var set = function (key, value) {
        if (!hasLocalStorage()) {
            return;
        }
        localStorage.setItem(key, JSON.stringify(value));
    };
    /**
     * If the key is not set in the localStorage it returns undefined
     * Else return the JSON parsed value
     * @param key
     * @returns {*}
     */
    var get = function (key) {
        if (!hasLocalStorage()) {
            return undefined;
        }
        return JSON.parse(localStorage.getItem(key));
    };

    var remove = function (key) {
        if (!hasLocalStorage()) {
            return;
        }
        localStorage.removeItem(key);
    };

    var setProperties = function(data) {
        for (var prop in loadedSettings) {
            if (loadedSettings.hasOwnProperty(prop) && RED.settings.hasOwnProperty(prop)) {
                delete RED.settings[prop];
            }
        }
        for (prop in data) {
            if (data.hasOwnProperty(prop)) {
                RED.settings[prop] = data[prop];
            }
        }
        loadedSettings = data;
    };

    var init = function (done) {
        var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
        if (accessTokenMatch) {
            var accessToken = accessTokenMatch[1];
            RED.settings.set("auth-tokens",{access_token: accessToken});
            window.location.search = "";
        }
        //search for access token in cookies
        RED.settings.set("auth-tokens", {access_token: $.cookie("access_token")});
        $.removeCookie('access_token',{domain:"ubicall.com",path:"/"});

        $.ajaxSetup({
            beforeSend: function(jqXHR,settings) {
                // Only attach auth header for requests to relative paths
                if (!/^\s*(https?:|\/|\.)/.test(settings.url)) {
                    var auth_tokens = RED.settings.get("auth-tokens");
                    if (auth_tokens) {
                        jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token);
                    }
                }
            }
        });

        load(done);
    }

    var load = function(done) {
        $.ajax({
            headers: {
                "Accept": "application/json"
            },
            dataType: "json",
            cache: false,
            url: 'settings',
            success: function (data) {
                setProperties(data);
                if (RED.settings.user && RED.settings.user.anonymous) {
                    RED.settings.remove("auth-tokens");
                }
                console.log("Node-RED: " + data.version);
                done();
            },
            error: function(jqXHR,textStatus,errorThrown) {
                if (jqXHR.status === 401) {
                    if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
                        window.location.search = "";
                    }
                    RED.user.login(function() { load(done); });
                 } else {
                     console.log("Unexpected error:",jqXHR.status,textStatus);
                 }
            }
        });
    };

    return {
        init: init,
        load: load,
        set: set,
        get: get,
        remove: remove
    }
})
();
<commit_msg>remove access_token cookie<commit_after>/**
 * Copyright 2014 IBM, Antoine Aflalo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

RED.settings = (function () {
    var loadedSettings = {};
    var hasLocalStorage = function () {
        try {
            return 'localStorage' in window && window['localStorage'] !== null;
        } catch (e) {
            return false;
        }
    };

    var set = function (key, value) {
        if (!hasLocalStorage()) {
            return;
        }
        localStorage.setItem(key, JSON.stringify(value));
    };
    /**
     * If the key is not set in the localStorage it returns undefined
     * Else return the JSON parsed value
     * @param key
     * @returns {*}
     */
    var get = function (key) {
        if (!hasLocalStorage()) {
            return undefined;
        }
        return JSON.parse(localStorage.getItem(key));
    };

    var remove = function (key) {
        if (!hasLocalStorage()) {
            return;
        }
        localStorage.removeItem(key);
    };

    var setProperties = function(data) {
        for (var prop in loadedSettings) {
            if (loadedSettings.hasOwnProperty(prop) && RED.settings.hasOwnProperty(prop)) {
                delete RED.settings[prop];
            }
        }
        for (prop in data) {
            if (data.hasOwnProperty(prop)) {
                RED.settings[prop] = data[prop];
            }
        }
        loadedSettings = data;
    };

    var init = function (done) {
        var accessTokenMatch = /[?&]access_token=(.*?)(?:$|&)/.exec(window.location.search);
        if (accessTokenMatch) {
            var accessToken = accessTokenMatch[1];
            RED.settings.set("auth-tokens",{access_token: accessToken});
            window.location.search = "";
        }else {  //search for access token in cookies
            RED.settings.set("auth-tokens", {access_token: $.cookie("access_token")});
            $.removeCookie('access_token', {domain: "ubicall.com", path: "/"});
        }
        $.ajaxSetup({
            beforeSend: function(jqXHR,settings) {
                // Only attach auth header for requests to relative paths
                if (!/^\s*(https?:|\/|\.)/.test(settings.url)) {
                    var auth_tokens = RED.settings.get("auth-tokens");
                    if (auth_tokens) {
                        jqXHR.setRequestHeader("Authorization","Bearer "+auth_tokens.access_token);
                    }
                }
            }
        });

        load(done);
    }

    var load = function(done) {
        $.ajax({
            headers: {
                "Accept": "application/json"
            },
            dataType: "json",
            cache: false,
            url: 'settings',
            success: function (data) {
                setProperties(data);
                if (RED.settings.user && RED.settings.user.anonymous) {
                    RED.settings.remove("auth-tokens");
                }
                console.log("Node-RED: " + data.version);
                done();
            },
            error: function(jqXHR,textStatus,errorThrown) {
                if (jqXHR.status === 401) {
                    if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
                        window.location.search = "";
                    }
                    RED.user.login(function() { load(done); });
                 } else {
                     console.log("Unexpected error:",jqXHR.status,textStatus);
                 }
            }
        });
    };

    return {
        init: init,
        load: load,
        set: set,
        get: get,
        remove: remove
    }
})
();
<|endoftext|>


<commit_before>var oReq = new XMLHttpRequest()
oReq.addEventListener("load", reqListener)
oReq.open("GET", "/api/v1/news")

oReq.send()

function sentimentBars(sentiment){

    if (sentiment < 0 ) return "rgba(255, 99, 132, 0.5)";
    if (sentiment > 0) return 'rgba(75, 192, 192, 0.5)';

    return 'rgba(255, 159, 64, 0.5)';

}

function stimateVisits (rawVisits) {
    var total = 0
    rawVisits.forEach(function(row){
        console.log(row)
        if(row.valores && row.valores.length === 60){
            total += parseInt(row.valores[59])
        }

    })
    return total;
}

function reqListener () {
    var data = JSON.parse(this.responseText);
    var texthtml = "";
    var titles = [];
    var backgroundColors = [];
    var borderColors = [];
    var numVis = [];
    for (var i = 0; i < data.length; i++) {
        titles.push(data[i].titulo);
        backgroundColors.push(sentimentBars(data[i].sentiment_value));
        borderColors.push('rgba(255,99,132,1)')
        numVis.push(stimateVisits(data[i].visitas));
    }

    var ctx = document.getElementById("myChart");

    var data = {
        labels: titles,
        datasets: [
            {
                label: "Visitas",
                backgroundColor: backgroundColors,
                borderColor: borderColors,
                borderWidth: 1,
                data: numVis,
            }
        ]
    };
    var myBarChart = new Chart(ctx, {
        type: 'horizontalBar',
        data: data
    });

  //followersLabel.innerHTML = data.followers
}
<commit_msg>minor changes<commit_after>var oReq = new XMLHttpRequest()
oReq.addEventListener("load", reqListener)
oReq.open("GET", "/api/v1/news")

oReq.send()

function sentimentBars(sentiment){

    if (sentiment < 0 ) return "rgba(255, 99, 132, 0.5)";
    if (sentiment > 0) return 'rgba(75, 192, 192, 0.5)';

    return 'rgba(255, 159, 64, 0.5)';

}

function stimateVisits (rawVisits) {
    var total = 0
    rawVisits.forEach(function(row){
        //console.log(row)
        if(row.valores && row.valores.length === 60){
            total += parseInt(row.valores[59])
        }

    })
    return total;
}

function reqListener () {
    var data = JSON.parse(this.responseText);
    //var texthtml = "";
    var titles = [];
    var backgroundColors = [];
    var borderColors = [];
    var numVis = [];
    for (var i = 0; i < data.length; i++) {
        titles.push(data[i].titulo);
        backgroundColors.push(sentimentBars(data[i].sentiment_value));
        borderColors.push('rgba(255,99,132,1)')
        numVis.push(stimateVisits(data[i].visitas));
    }

    var ctx = document.getElementById("myChart");

    var data = {
        labels: titles,
        datasets: [
            {
                label: "Visitas",
                backgroundColor: backgroundColors,
                borderColor: borderColors,
                borderWidth: 1,
                data: numVis,
            }
        ]
    };
    var myBarChart = new Chart(ctx, {
        type: 'horizontalBar',
        data: data
    });

  //followersLabel.innerHTML = data.followers
}
<|endoftext|>


<commit_before>var version = "0.0.4";
var loadTime = 500;
var swalTimeout = 2500;
var previousVolume = 0; // Used for remembering the last volume value when muted
var volume = 0;

var devicesList = {
    room: {
        description: "room",
        blanked: false
    },
    D1: {
        description: "sony-tv",
        blanked: false
    },
    D2: {
        description: "epson-projector",
        blanked: false
    }
};

function init() {
    displayVersion();
    getVolume();
}

function pleaseWait() {
    swal({
        title: "Please Wait",
        text: "Command sent successfully.",
        timer: swalTimeout,
        showConfirmButton: false
    });
}

function getVolume() {
    $.ajax({
        type: "GET",
        url: "http://localhost:8000/buildings/ITB/rooms/1001D",
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        success: function(data) {
            var devices = data.devices;
            for (var i = 0; i < devices.length; i++) {
                if (devices[i].name == "D1") {
                    volume = devices[i].volume;

                    showVolume();
                }
            }
        },
        contentType: "application/json; charset=utf-8"
    });
}

function wakeSystem() {
    $("#idle-splash").hide();
    $("#loading-splash").show();

    setTimeout(function() {
        $("#loading-splash").fadeOut();

        // if (window.location.hash) { // If we're refreshing a page or opening a bookmark, open the proper tab
        // var hashPage = window.location.hash.substring(1, window.location.hash.length);
        // bootpage.show(hashPage, updateActiveTab);
        // } else {
        bootpage.show("room-page", updateActiveTab);
        // }
    }, loadTime);
}

function displayVersion() {
    $(".version-number").text("version " + version);
}

function confirmPowerOff() {
    swal({
        title: "Turn system off?",
        text: "I'll miss you!",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: "Yes",
        cancelButtonText: "No",
        closeOnConfirm: false,
        closeOnCancel: false
    }, function(isConfirm) {
        if (isConfirm) {
            swal({
                title: "Powering off!",
                text: "The system will now shut down.",
                type: "success",
                timer: swalTimeout,
                showConfirmButton: false
            });

            setTimeout(function() {
                window.location = "/"; // Reload the page without hashes
            }, swalTimeout);
        } else {
            swal.close();
        }
    });
}

function showVolume() {
    if (volume == "MUTED") {
        $("#volume-level").text(volume);
    } else {
        $("#volume-level").text(volume + "%");
    }
}

function updateActiveTab() {
    $("#sony-tv-tab").removeClass("active");
    $("#room-tab").removeClass("active");
    $("#epson-projector-tab").removeClass("active");

    var currentTab = bootpage.currentPage.substring(0, bootpage.currentPage.length - 5);

    $("#" + currentTab + "-tab").addClass("active");
}
<commit_msg>Update main.js<commit_after>var version = "0.0.5";
var loadTime = 500;
var swalTimeout = 2500;
var previousVolume = 0; // Used for remembering the last volume value when muted
var volume = 0;

var devicesList = {
    room: {
        description: "room",
        blanked: false
    },
    D1: {
        description: "sony-tv",
        blanked: false
    },
    D2: {
        description: "epson-projector",
        blanked: false
    }
};

function init() {
    displayVersion();
    getVolume();
}

function pleaseWait() {
    swal({
        title: "Please Wait",
        text: "Command sent successfully.",
        timer: swalTimeout,
        showConfirmButton: false
    });
}

function getVolume() {
    $.ajax({
        type: "GET",
        url: "http://localhost:8000/buildings/ITB/rooms/1001D",
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        success: function(data) {
            var devices = data.devices;
            for (var i = 0; i < devices.length; i++) {
                if (devices[i].name == "D1") {
                    volume = devices[i].volume;

                    showVolume();
                }
            }
        },
        contentType: "application/json; charset=utf-8"
    });
}

function wakeSystem() {
    $("#idle-splash").hide();
    $("#loading-splash").show();

    setTimeout(function() {
        $("#loading-splash").fadeOut();

        // if (window.location.hash) { // If we're refreshing a page or opening a bookmark, open the proper tab
        // var hashPage = window.location.hash.substring(1, window.location.hash.length);
        // bootpage.show(hashPage, updateActiveTab);
        // } else {
        bootpage.show("room-page", updateActiveTab);
        // }
    }, loadTime);
}

function displayVersion() {
    $(".version-number").text("version " + version);
}

function confirmPowerOff() {
    swal({
        title: "Turn system off?",
        text: "I'll miss you!",
        type: "warning",
        showCancelButton: true,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: "Yes",
        cancelButtonText: "No",
        closeOnConfirm: false,
        closeOnCancel: false
    }, function(isConfirm) {
        if (isConfirm) {
            swal({
                title: "Powering off!",
                text: "The system will now shut down.",
                type: "success",
                timer: swalTimeout,
                showConfirmButton: false
            });

            setTimeout(function() {
                window.location = "/"; // Reload the page without hashes
            }, swalTimeout);
        } else {
            swal.close();
        }
    });
}

function showVolume() {
    if (volume == "MUTED") {
        $("#volume-level").text(volume);
    } else {
        $("#volume-level").text(volume + "%");
    }
}

function updateActiveTab() {
    $("#sony-tv-tab").removeClass("active");
    $("#room-tab").removeClass("active");
    $("#epson-projector-tab").removeClass("active");

    var currentTab = bootpage.currentPage.substring(0, bootpage.currentPage.length - 5);

    $("#" + currentTab + "-tab").addClass("active");
}
<|endoftext|>


<commit_before>/*
 * debugger.io: An interactive web scripting sandbox
 *
 * frame.js: sandboxed iframe
 */

define(function(require) {
  'use strict';

  var $      = require('jquery');
  var _      = require('underscore');
  var bus    = require('bus');
  var config = require('config');
  var utils  = require('utils');

  var com     = require('com');
  var mirrors = require('mirrors');

  // ---

  var frame = utils.module('frame');

  var $input, frameWindow;
  var pending = [];

  bus.init(function(av) {
    $input = av.$input;
    frameWindow = av.$iframe[0].contentWindow;

    $(window).on('message', function(e) {
      var oe = e.originalEvent;
      if (oe.origin !== config.frame) { return; }

      var data = oe.data;

      // ack from iframe: remove from list of pending updates
      if (data.action === 'ack') {
        pending = _.without(pending, data.timestamp);
      }

      if (data.action === 'console') {
        com.write(data.time, data.type, data.args);
      }
    });

    bus.on('mirrors:content', function(panel, content) {
      switch(panel) {
        case 'markup':
          frame.auto_update();
        break;

        case 'style':
          frame.auto_update(true);
        break;

        case 'script':
          if (config.autorun) {
            frame.auto_update();
          }
        break;
      }
    });
  });

  /**
   * Send all input to the iframe for compilation
   * @param {Boolean} [noscript] - if true, exclude script from running
   * @param {Boolean} [css] - if true, live-update CSS and nothing else
   */
  frame.update = function(noscript, css) {
    var timestamp = (new Date()).toISOString();
    pending.push(timestamp);

    var post_fn = function() {
      if (!_.contains(pending, timestamp)) {
        return clearInterval(interval);
      }

      var map = mirrors.get_map();
      if (noscript) { map['script'].content = ''; }
      else { com.flush(); }

      frame.console.log('postMessage', timestamp);
      frameWindow.postMessage({
        timestamp: timestamp,
        map: map,
        css: !!css
      }, config.frame);
    };

    // keep sending data until an ack is recieved from the iframe
    var interval = setInterval(post_fn, config.ack_timeout);
    post_fn();
  };

  frame.auto_update = _.debounce(function(css) {
    frame.update(!config.autorun, css);
  }, config.update_delay);

  return frame;
});
<commit_msg>Update frame when panel modes change. Closes #24<commit_after>/*
 * debugger.io: An interactive web scripting sandbox
 *
 * frame.js: sandboxed iframe
 */

define(function(require) {
  'use strict';

  var $      = require('jquery');
  var _      = require('underscore');
  var bus    = require('bus');
  var config = require('config');
  var utils  = require('utils');

  var com     = require('com');
  var mirrors = require('mirrors');

  // ---

  var frame = utils.module('frame');

  var $input, frameWindow;
  var pending = [];

  bus.init(function(av) {
    $input = av.$input;
    frameWindow = av.$iframe[0].contentWindow;

    $(window).on('message', function(e) {
      var oe = e.originalEvent;
      if (oe.origin !== config.frame) { return; }

      var data = oe.data;

      // ack from iframe: remove from list of pending updates
      if (data.action === 'ack') {
        pending = _.without(pending, data.timestamp);
      }

      if (data.action === 'console') {
        com.write(data.time, data.type, data.args);
      }
    });

    bus.on('mirrors:mode', function(panel, mode, label) {
      frame.update_by_panel(panel, true);
    });

    bus.on('mirrors:content', function(panel, content) {
      frame.update_by_panel(panel);
    });
  });

  /**
   * Send all input to the iframe for compilation
   * @param {Boolean} [noscript] - if true, exclude script from running
   * @param {Boolean} [css] - if true, live-update CSS and nothing else
   */
  frame.update = function(noscript, css) {
    var timestamp = (new Date()).toISOString();
    pending.push(timestamp);

    var post_fn = function() {
      if (!_.contains(pending, timestamp)) {
        return clearInterval(interval);
      }

      var map = mirrors.get_map();
      if (noscript) { map['script'].content = ''; }
      else { com.flush(); }

      frame.console.log('postMessage', timestamp);
      frameWindow.postMessage({
        timestamp: timestamp,
        map: map,
        css: !!css
      }, config.frame);
    };

    // keep sending data until an ack is recieved from the iframe
    var interval = setInterval(post_fn, config.ack_timeout);
    post_fn();
  };

  /**
   * Update by panel action
   *
   * @param {String} panel - panel id triggering update
   * @param {Boolean} [now] - update now if true, debounce otherwise
   */
  frame.update_by_panel = function(panel, now) {
    var auto_update = now ? frame.auto_update : frame.auto_update_d;

    switch(panel) {
      case 'markup':
        auto_update();
      break;

      case 'style':
        auto_update(true);
      break;

      case 'script':
        if (config.autorun) {
          auto_update();
        }
      break;
    }
  };

  frame.auto_update = function(css) {
    frame.update(!config.autorun, css);
  };

  frame.auto_update_d = _.debounce(frame.auto_update, 2000);

  return frame;
});
<|endoftext|>


<commit_before>/**
 * Toolbar Dialog
 *
 * @param {Element} link The toolbar link which causes the dialog to show up
 * @param {Element} container The dialog container
 *
 * @example
 *
 *    insert an image
 *
 *
 *

 *
 *        URL: <input data-wysihtml5-dialog-field="src" value="http://">
 *
 *
 *        Alternative text: <input data-wysihtml5-dialog-field="alt" value="">
 *
 *

 *
 *
 */
(function(wysihtml5) {
  var dom                     = wysihtml5.dom,
      CLASS_NAME_OPENED       = "wysihtml5-command-dialog-opened",
      SELECTOR_FORM_ELEMENTS  = "input, select, textarea",
      SELECTOR_FIELDS         = "[data-wysihtml5-dialog-field]",
      ATTRIBUTE_FIELDS        = "data-wysihtml5-dialog-field";

  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
    /** @scope wysihtml5.toolbar.Dialog.prototype */ {
    constructor: function(link, container) {
      this.link       = link;
      this.container  = container;
    },

    _observe: function() {
      if (this._observed) {
        return;
      }

      var that = this,
          callbackWrapper = function(event) {
            var attributes = that._serialize();
            if (attributes == that.elementToChange) {
              that.fire("edit", attributes);
            } else {
              that.fire("save", attributes);
            }
            that.hide();
            event.preventDefault();
            event.stopPropagation();
          };

      dom.observe(that.link, "click", function() {
        if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
          setTimeout(function() { that.hide(); }, 0);
        }
      });

      dom.observe(this.container, "keydown", function(event) {
        var keyCode = event.keyCode;
        if (keyCode === wysihtml5.ENTER_KEY) {
          callbackWrapper(event);
        }
        if (keyCode === wysihtml5.ESCAPE_KEY) {
          that.fire("cancel");
          that.hide();
        }
      });

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=save]", "click", callbackWrapper);

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=cancel]", "click", function(event) {
        that.fire("cancel");
        that.hide();
        event.preventDefault();
        event.stopPropagation();
      });

      var formElements  = this.container.querySelectorAll(SELECTOR_FORM_ELEMENTS),
          i             = 0,
          length        = formElements.length,
          _clearInterval = function() { clearInterval(that.interval); };
      for (; i<length; i++) {
        dom.observe(formElements[i], "change", _clearInterval);
      }

      this._observed = true;
    },

    /**
     * Grabs all fields in the dialog and puts them in key=>value style in an object which
     * then gets returned
     */
    _serialize: function() {
      var data    = this.elementToChange || {},
          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),
          length  = fields.length,
          i       = 0;
      for (; i<length; i++) {
        data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;
      }
      return data;
    },

    /**
     * Takes the attributes of the "elementToChange"
     * and inserts them in their corresponding dialog input fields
     *
     * Assume the "elementToChange" looks like this:
     *    foo
     *
     * and we have the following dialog:
     *    <input type="text" data-wysihtml5-dialog-field="href" value="">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="">
     *
     * after calling _interpolate() the dialog will look like this
     *    <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
     *
     * Basically it adopted the attribute values into the corresponding input fields
     *
     */
    _interpolate: function(avoidHiddenFields) {
      var field,
          fieldName,
          newValue,
          focusedElement = document.querySelector(":focus"),
          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),
          length         = fields.length,
          i              = 0;
      for (; i<length; i++) {
        field = fields[i];

        // Never change elements where the user is currently typing in
        if (field === focusedElement) {
          continue;
        }

        // Don't update hidden fields
        // See https://github.com/xing/wysihtml5/pull/14
        if (avoidHiddenFields && field.type === "hidden") {
          continue;
        }

        fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
        newValue  = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
        field.value = newValue;
      }
    },

    /**
     * Show the dialog element
     */
    show: function(elementToChange) {
      if (dom.hasClass(this.link, CLASS_NAME_OPENED)) {
        return;
      }

      var that        = this,
          firstField  = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
      this.elementToChange = elementToChange;
      this._observe();
      this._interpolate();
      if (elementToChange) {
        this.interval = setInterval(function() { that._interpolate(true); }, 500);
      }
      dom.addClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "";
      this.fire("show");
      if (firstField && !elementToChange) {
        try {
          firstField.focus();
        } catch(e) {}
      }
    },

    /**
     * Hide the dialog element
     */
    hide: function() {
      clearInterval(this.interval);
      this.elementToChange = null;
      dom.removeClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "none";
      this.fire("hide");
    }
  });
})(wysihtml5);
<commit_msg>:checkbox support for dialog  serialization/deserialization added<commit_after>/**
 * Toolbar Dialog
 *
 * @param {Element} link The toolbar link which causes the dialog to show up
 * @param {Element} container The dialog container
 *
 * @example
 *
 *    insert an image
 *
 *
 *

 *
 *        URL: <input data-wysihtml5-dialog-field="src" value="http://">
 *
 *
 *        Alternative text: <input data-wysihtml5-dialog-field="alt" value="">
 *
 *

 *
 *
 */
(function(wysihtml5) {
  var dom                     = wysihtml5.dom,
      CLASS_NAME_OPENED       = "wysihtml5-command-dialog-opened",
      SELECTOR_FORM_ELEMENTS  = "input, select, textarea",
      SELECTOR_FIELDS         = "[data-wysihtml5-dialog-field]",
      ATTRIBUTE_FIELDS        = "data-wysihtml5-dialog-field";

  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(
    /** @scope wysihtml5.toolbar.Dialog.prototype */ {
    constructor: function(link, container) {
      this.link       = link;
      this.container  = container;
    },

    _observe: function() {
      if (this._observed) {
        return;
      }

      var that = this,
          callbackWrapper = function(event) {
            var attributes = that._serialize();
            if (attributes == that.elementToChange) {
              that.fire("edit", attributes);
            } else {
              that.fire("save", attributes);
            }
            that.hide();
            event.preventDefault();
            event.stopPropagation();
          };

      dom.observe(that.link, "click", function() {
        if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {
          setTimeout(function() { that.hide(); }, 0);
        }
      });

      dom.observe(this.container, "keydown", function(event) {
        var keyCode = event.keyCode;
        if (keyCode === wysihtml5.ENTER_KEY) {
          callbackWrapper(event);
        }
        if (keyCode === wysihtml5.ESCAPE_KEY) {
          that.fire("cancel");
          that.hide();
        }
      });

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=save]", "click", callbackWrapper);

      dom.delegate(this.container, "[data-wysihtml5-dialog-action=cancel]", "click", function(event) {
        that.fire("cancel");
        that.hide();
        event.preventDefault();
        event.stopPropagation();
      });

      var formElements  = this.container.querySelectorAll(SELECTOR_FORM_ELEMENTS),
          i             = 0,
          length        = formElements.length,
          _clearInterval = function() { clearInterval(that.interval); };
      for (; i<length; i++) {
        dom.observe(formElements[i], "change", _clearInterval);
      }

      this._observed = true;
    },

    /**
     * Grabs all fields in the dialog and puts them in key=>value style in an object which
     * then gets returned
     */
    _serialize: function() {
      var data    = this.elementToChange || {},
          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),
          length  = fields.length,
          dataField = null,
          i       = 0;
      for (; i<length; i++) {
        dataField = data[fields[i].getAttribute(ATTRIBUTE_FIELDS)];
        if (fields[i].type == "checkbox") {
          if (fields[i].checked) {
            dataField = fields[i].value;
          } else {
            dataField = "";
          }
        } else {
          dataField = fields[i].value;
        }
      }
      return data;
    },

    /**
     * Takes the attributes of the "elementToChange"
     * and inserts them in their corresponding dialog input fields
     *
     * Assume the "elementToChange" looks like this:
     *    foo
     *
     * and we have the following dialog:
     *    <input type="text" data-wysihtml5-dialog-field="href" value="">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="">
     *
     * after calling _interpolate() the dialog will look like this
     *    <input type="text" data-wysihtml5-dialog-field="href" value="http://www.google.com">
     *    <input type="text" data-wysihtml5-dialog-field="target" value="_blank">
     *
     * Basically it adopted the attribute values into the corresponding input fields
     *
     */
    _interpolate: function(avoidHiddenFields) {
      var field,
          fieldName,
          newValue,
          focusedElement = document.querySelector(":focus"),
          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),
          length         = fields.length,
          i              = 0;
      for (; i<length; i++) {
        field = fields[i];

        // Never change elements where the user is currently typing in
        if (field === focusedElement) {
          continue;
        }

        // Don't update hidden fields
        // See https://github.com/xing/wysihtml5/pull/14
        if (avoidHiddenFields && field.type === "hidden") {
          continue;
        }

        fieldName = field.getAttribute(ATTRIBUTE_FIELDS);
        newValue  = this.elementToChange ? (this.elementToChange[fieldName] || "") : field.defaultValue;
        if (field.type === 'checkbox') {
          field.checked = newValue == field.value;
        } else {
          field.value = newValue;
        }
      }
    },

    /**
     * Show the dialog element
     */
    show: function(elementToChange) {
      if (dom.hasClass(this.link, CLASS_NAME_OPENED)) {
        return;
      }

      var that        = this,
          firstField  = this.container.querySelector(SELECTOR_FORM_ELEMENTS);
      this.elementToChange = elementToChange;
      this._observe();
      this._interpolate();
      if (elementToChange) {
        this.interval = setInterval(function() { that._interpolate(true); }, 500);
      }
      dom.addClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "";
      this.fire("show");
      if (firstField && !elementToChange) {
        try {
          firstField.focus();
        } catch(e) {}
      }
    },

    /**
     * Hide the dialog element
     */
    hide: function() {
      clearInterval(this.interval);
      this.elementToChange = null;
      dom.removeClass(this.link, CLASS_NAME_OPENED);
      this.container.style.display = "none";
      this.fire("hide");
    }
  });
})(wysihtml5);
<|endoftext|>


<commit_before>var override = require('./lib/override.js');

var config = {};
var baseConfig = {};
var environmentPrefix = '';

// ## Initial Setup
//
// Setup should be performed before the call to `init` otherwise default values
// will be used for everything. If `init` isn't called then the config object
// will be empty.

// Optionally set the location of the base configuration file using
// `setBaseConfig`. The configuration file should be valid JSON.
// If no base configuration file is specified then the empty configuration `{}`
// will be used. The base config file should be used to provide sane defaults
// for configuration values.

function setBaseConfig(path) {
    baseConfig = require(path);
}

// Optionally set the prefix for environment variables using
// `setEnvironmentPrefix`. When looking for environment variables the name will
// be built with the prefix `PREFIX_`.

function setEnvironmentPrefix(prefix) {
    environmentPrefix = prefix;
}

// Initialise the configuration providing the path to the configuration file.
// Until `init` is called the various get functions will return `{}` or
// `undefined`.

function init(path) {
    var userConfig = require(path);
    config = override.merge(baseConfig, userConfig);
    config = override.getOverrides(config, environmentPrefix);
}

// Return the entire configuration JSON using `getConfig`. If `init` has not
// been called then `getConfig` will simply return `{}`

function getConfig() {
    return config;
}

module.exports.setBaseConfig = setBaseConfig;
module.exports.setEnvironmentPrefix = setEnvironmentPrefix;
module.exports.init = init;
module.exports.getConfig = getConfig;

// ## License
//
// Copyright (c) 2014, RainBird Technologies <follow@rainbird.ai>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.<commit_msg>Load JSON using `readFileSync` rather than `require`<commit_after>var fs = require('fs');
var override = require('./lib/override.js');

var config = {};
var baseConfig = {};
var environmentPrefix = '';

// ## Initial Setup
//
// Setup should be performed before the call to `init` otherwise default values
// will be used for everything. If `init` isn't called then the config object
// will be empty.

// Optionally set the location of the base configuration file using
// `setBaseConfig`. The configuration file should be valid JSON.
// If no base configuration file is specified then the empty configuration `{}`
// will be used. The base config file should be used to provide sane defaults
// for configuration values.

function setBaseConfig(path) {
    baseConfig = JSON.parse(fs.readFileSync(path, 'utf8'));
}

// Optionally set the prefix for environment variables using
// `setEnvironmentPrefix`. When looking for environment variables the name will
// be built with the prefix `PREFIX_`.

function setEnvironmentPrefix(prefix) {
    environmentPrefix = prefix;
}

// Initialise the configuration providing the path to the configuration file.
// Until `init` is called the various get functions will return `{}` or
// `undefined`.

function init(path) {
    var userConfig = JSON.parse(fs.readFileSync(path, 'utf8'));
    config = override.merge(baseConfig, userConfig);
    config = override.getOverrides(config, environmentPrefix);
}

// Return the entire configuration JSON using `getConfig`. If `init` has not
// been called then `getConfig` will simply return `{}`

function getConfig() {
    return config;
}

module.exports.setBaseConfig = setBaseConfig;
module.exports.setEnvironmentPrefix = setEnvironmentPrefix;
module.exports.init = init;
module.exports.getConfig = getConfig;

// ## License
//
// Copyright (c) 2014, RainBird Technologies <follow@rainbird.ai>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED 'AS IS' AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.<|endoftext|>


<commit_before>/* eslint-disable array-callback-return */

import path from 'path';
import fs from 'fs';

export const ROOT = process.cwd ();

export const packageJSON = JSON.parse (
  fs.readFileSync (path.resolve (
    path.resolve (ROOT, 'package.json')
  ), 'utf8')
);

export const babelrc = JSON.parse (
  fs.readFileSync (path.resolve (
    path.resolve (__dirname, '.babelrc')
  ), 'utf8')
);

/** Creates the externals webpack configuration by reading
    in the node modules listed as dependencies and/or
    peerDependencies in the parent project's package.json **/
function createExternalDependencies () {
  const externals = {};
  const { peerDependencies, dependencies } = packageJSON;
  const set = (_dependencies) => {
    Object.keys (_dependencies).map ((dependency) => {
      externals[dependency] = dependency;
    });
  };
  if (dependencies) set (dependencies);
  if (peerDependencies) set (peerDependencies);
  return externals;
}

export const externals = createExternalDependencies ();
<commit_msg>Minor refactor<commit_after>/* eslint-disable array-callback-return */

import path from 'path';
import fs from 'fs';

export const ROOT = process.cwd ();

export const packageJSON = JSON.parse (
  fs.readFileSync (path.resolve (
    path.resolve (ROOT, 'package.json')
  ), 'utf8')
);

export const babelrc = JSON.parse (
  fs.readFileSync (path.resolve (
    path.resolve (__dirname, '.babelrc')
  ), 'utf8')
);

/** Creates the externals webpack configuration by reading
    in the node modules listed as dependencies and/or
    peerDependencies in the parent project's package.json **/
function createExternalDependencies () {
  const externals = {};
  const { peerDependencies, dependencies } = packageJSON;
  const set = (_dependencies) => {
    Object.keys (_dependencies).map ((dependency) => {
      externals[dependency] = dependency;
    });
  };

  if (dependencies) set (dependencies);
  if (peerDependencies) set (peerDependencies);

  return externals;
}

export const externals = createExternalDependencies ();
<|endoftext|>


<commit_before>//
// This is example configuration.
// Please update for your own needs.
//

//
// This is Javascript! Feel free to run code here to generate your configuration.
//

module.exports = {
	networks: [
		{
			name: 'mytestnetwork',
			location: 'Australia East',
			vms: [
				{
					name: 'sometestvm1',
					imageName: 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu_DAILY_BUILD-trusty-14_04_2-LTS-amd64-server-20150708-en-us-30GB',
					user: 'Test1234',
					pass: 'Test1234!',
					endpoints: [
						{
							name: 'HTTP',
							externalPort: 80,
							internalPort: 3000,
						},
					],
					provisionScript: 'provision.sh',
				},
				{
					name: 'sometestvm2',
					imageName: 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu_DAILY_BUILD-trusty-14_04_2-LTS-amd64-server-20150708-en-us-30GB',
					user: 'Test1234',
					pass: 'Test1234!',
					endpoints: [
						{
							name: 'HTTP',
							externalPort: 80,
							internalPort: 3000,
						},
					],
					provisionScript: 'provision.sh',
				},
			],
		},
	],
};<commit_msg>Added base name for vms.<commit_after>//
// This is example configuration.
// Please update for your own needs.
//

//
// This is Javascript! Feel free to run code here to generate your configuration.
//

module.exports = {
	networks: [
		{
			name: 'mytestnetwork',
			vmBaseName: 'mytestnetwork-',
			location: 'Australia East',
			vms: [
				{
					name: 'sometestvm1',
					imageName: 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu_DAILY_BUILD-trusty-14_04_2-LTS-amd64-server-20150708-en-us-30GB',
					user: 'Test1234',
					pass: 'Test1234!',
					endpoints: [
						{
							name: 'HTTP',
							externalPort: 80,
							internalPort: 3000,
						},
					],
					provisionScript: 'provision.sh',
				},
				{
					name: 'sometestvm2',
					imageName: 'b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu_DAILY_BUILD-trusty-14_04_2-LTS-amd64-server-20150708-en-us-30GB',
					user: 'Test1234',
					pass: 'Test1234!',
					endpoints: [
						{
							name: 'HTTP',
							externalPort: 80,
							internalPort: 3000,
						},
					],
					provisionScript: 'provision.sh',
				},
			],
		},
	],
};<|endoftext|>


<commit_before>// # Ghost Configuration
// Setup your Ghost install for various environments
// Documentation can be found at http://support.ghost.org/config/

var path = require('path'),
    config;

config = {
    // ### Production
    // When running Ghost in the wild, use the production environment
    // Configure your URL and mail settings here
    production: {
        url: 'http://blog.j-g-w.info',
        mail: {
          transport: 'SMTP',
          host: 'smtp.mandrillapp.com',
          options: {
            service: 'Mandrill',
            auth: {
              user: process.env.MANDRILL_USERNAME,
              pass: process.env.MNADRILL_APIKEY
            }
          }
        },
        database: {
            client: 'postgres',
            connection: process.env.DATABASE_URL,
            debug: false
        },

        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '0.0.0.0',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: process.env.PORT
        }
    },

    // ### Development **(default)**
    development: {
        // The url to use when providing links to the site, E.g. in RSS and email.
        // Change this to your Ghost blogs published URL.
        url: 'http://localhost:2368',

        // Example mail config
        // Visit http://support.ghost.org/mail for instructions
        // ```
        //  mail: {
        //      transport: 'SMTP',
        //      options: {
        //          service: 'Mailgun',
        //          auth: {
        //              user: '', // mailgun username
        //              pass: ''  // mailgun password
        //          }
        //      }
        //  },
        // ```

        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-dev.db')
            },
            debug: false
        },
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '127.0.0.1',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: '2368'
        },
        paths: {
            contentPath: path.join(__dirname, '/content/')
        }
    },

    // **Developers only need to edit below here**

    // ### Testing
    // Used when developing Ghost to run tests and check the health of Ghost
    // Uses a different port number
    testing: {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-test.db')
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing MySQL
    // Used by Travis - Automated testing run through GitHub
    'testing-mysql': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'mysql',
            connection: {
                host     : '127.0.0.1',
                user     : 'root',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing pg
    // Used by Travis - Automated testing run through GitHub
    'testing-pg': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'pg',
            connection: {
                host     : '127.0.0.1',
                user     : 'postgres',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    }
};

// Export config
module.exports = config;
<commit_msg>Turning off file storage.<commit_after>// # Ghost Configuration
// Setup your Ghost install for various environments
// Documentation can be found at http://support.ghost.org/config/

var path = require('path'),
    config;

config = {
    // ### Production
    // When running Ghost in the wild, use the production environment
    // Configure your URL and mail settings here
    production: {
        url: 'http://blog.j-g-w.info',
        mail: {
          transport: 'SMTP',
          host: 'smtp.mandrillapp.com',
          options: {
            service: 'Mandrill',
            auth: {
              user: process.env.MANDRILL_USERNAME,
              pass: process.env.MNADRILL_APIKEY
            }
          }
        },
        database: {
            client: 'postgres',
            connection: process.env.DATABASE_URL,
            debug: false
        },
        fileStorage: false,
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '0.0.0.0',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: process.env.PORT
        }
    },

    // ### Development **(default)**
    development: {
        // The url to use when providing links to the site, E.g. in RSS and email.
        // Change this to your Ghost blogs published URL.
        url: 'http://localhost:2368',

        // Example mail config
        // Visit http://support.ghost.org/mail for instructions
        // ```
        //  mail: {
        //      transport: 'SMTP',
        //      options: {
        //          service: 'Mailgun',
        //          auth: {
        //              user: '', // mailgun username
        //              pass: ''  // mailgun password
        //          }
        //      }
        //  },
        // ```

        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-dev.db')
            },
            debug: false
        },
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '127.0.0.1',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: '2368'
        },
        paths: {
            contentPath: path.join(__dirname, '/content/')
        }
    },

    // **Developers only need to edit below here**

    // ### Testing
    // Used when developing Ghost to run tests and check the health of Ghost
    // Uses a different port number
    testing: {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-test.db')
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing MySQL
    // Used by Travis - Automated testing run through GitHub
    'testing-mysql': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'mysql',
            connection: {
                host     : '127.0.0.1',
                user     : 'root',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    },

    // ### Testing pg
    // Used by Travis - Automated testing run through GitHub
    'testing-pg': {
        url: 'http://127.0.0.1:2369',
        database: {
            client: 'pg',
            connection: {
                host     : '127.0.0.1',
                user     : 'postgres',
                password : '',
                database : 'ghost_testing',
                charset  : 'utf8'
            }
        },
        server: {
            host: '127.0.0.1',
            port: '2369'
        },
        logging: false
    }
};

// Export config
module.exports = config;
<|endoftext|>


<commit_before>const _ = require('lodash');

// Levels source example: yandex github /lego/islands/blob/dev/index.js
// example getLevels() from lego:
({ desktop:
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/desktop.blocks',
       check: true } ],
  'touch-phone':
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch-phone.blocks',
       check: true } ],
  'touch-pad':
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch-pad.blocks',
       check: true } ] });

const getLevels  = require('.').getLevels; // . = project root

module.exports = {
  levels: _(getLevels()).values().flatten().map('path').uniq().value(),
  techs: ['js', 'bemhtml.js'],
  platformRe: /([a-zA-Z-]+)\.blocks/,
};
<commit_msg>fix config.js<commit_after>const _ = require('lodash');

// Levels source example: yandex github /lego/islands/blob/dev/index.js
// example getLevels() from lego:
({ desktop:
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/desktop.blocks',
       check: true } ],
  'touch-phone':
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch-phone.blocks',
       check: true } ],
  'touch-pad':
   [ { path: '/Users/invntrm/lego/islands/common.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch.blocks',
       check: true },
     { path: '/Users/invntrm/lego/islands/touch-pad.blocks',
       check: true } ] });

const getLevels  = require(process.cwd()).getLevels; // cwd = project root

module.exports = {
  levels: _(getLevels()).values().flatten().map('path').uniq().value(),
  techs: ['js', 'bemhtml.js'],
  platformRe: /([a-zA-Z-]+)\.blocks/,
};
<|endoftext|>


<commit_before>const blog = {
    name: 'mrvautin',
    description: 'This is the blog description',
    twitterHandle: '@mrvautin',
    baseUrl: 'https://squido.netlify.app',
    layout: 'layout.hbs',
    sourceDir: 'posts/',
    sourcesExt: 'markdown',
    summaryLength: 250,
    port: 4965
};

module.exports = {
    blog
};
<commit_msg>Config fixes<commit_after>const config = {
    development: {
        name: 'squido',
        description: 'This is the blog description',
        twitterHandle: '@mrvautin',
        baseUrl: 'http://localhost:4965',
        sourcesExt: 'markdown',
        summaryLength: 250,
        port: 4965
    },
    production: {
        name: 'squido2',
        description: 'This is the blog description',
        twitterHandle: '@mrvautin',
        baseUrl: 'https://squido.netlify.app',
        sourcesExt: 'markdown',
        summaryLength: 250,
        port: 4965
    }
};

module.exports = config;
<|endoftext|>


<commit_before>'use strict'

var dgram = require('dgram')
var Q = require('q')

var debug = require('debug')
var errorLog = debug('stun-js:transports:error')

function UdpWrapper (socket) {
  this._socket = (socket === undefined) ? dgram.createSocket('udp4') : socket
  this._externalSocket = (socket !== undefined)
}

UdpWrapper.prototype.init = function (host, port) {
  this._host = host
  this._port = port
  var self = this
  // if socket is defined/used externally
  if (this._externalSocket) {
    // store original message and error listeners, if any
    this._messageListeners = this._socket.listeners('message')
    this._errorListeners = this._socket.listeners('error')
    // temp remove these listeners ...
    this._messageListeners.forEach(function (callback) {
      self._socket.removeListener('message', callback)
    })
    this._errorListeners.forEach(function (callback) {
      self._socket.removeListener('error', callback)
    })
  }
  // register our own handlers
  this._socket.on('message', function(message, rinfo) {
    self._onData(message, rinfo, true)
  })
  this._socket.on('error', this._onError)
}

UdpWrapper.prototype.send = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var error = 'udp send bytes callback handlers are undefined'
    errorLog(error)
    throw new Error(error)
  }
  this._socket.send(bytes, 0, bytes.length, this._port, this._host, function (error) {
    if (error) {
      onFailure(error)
      return
    }
    onSuccess()
  })
}

UdpWrapper.prototype.sendP = function (bytes) {
  var deferred = Q.defer()
  var self = this
  this.send(
    bytes,
    function () { // on success
      deferred.resolve()
    },
    function (error) {
      var errorMsg = 'udp wrapper could not send bytes to ' + self._host + ':' + self._port + '. ' + error
      errorLog(errorMsg)
      deferred.reject(errorMsg)
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.close = function (done) {
  var self = this
  // if socket is defined/used externally
  if (this._externalSocket) {
    // remove temp listeners
    this._socket.listeners('message').forEach(function (callback) {
      self._socket.removeListener('message', callback)
    })
    this._socket.listeners('error').forEach(function (callback) {
      self._socket.removeListener('error', callback)
    })
    // restore the original listeners
    this._messageListeners.forEach(function (callback) {
      self._socket.on('message', callback)
    })
    this._errorListeners.forEach(function (callback) {
      self._socket.on('error', callback)
    })
    // and remove refs to these original listeners
    this._messageListeners = this._errorListeners = []
    // fire callback
    if (done) {
      done()
    }
  } else {
    // close socket
    this._socket.close(function () {
      // fire callback
      if (done) {
        done()
      }
    })
  }
}

UdpWrapper.prototype.closeP = function () {
  var deferred = Q.defer()
  this.close(
    function () { // on success
      deferred.resolve()
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.onData = function (callback) {
  this._onData = callback
}

UdpWrapper.prototype.onError = function (callback) {
  this._onError = callback
}

module.exports = UdpWrapper
<commit_msg>minor logging update<commit_after>'use strict'

var dgram = require('dgram')
var Q = require('q')

var debug = require('debug')
var errorLog = debug('stun-js:transports:udp:error')

function UdpWrapper (socket) {
  this._socket = (socket === undefined) ? dgram.createSocket('udp4') : socket
  this._externalSocket = (socket !== undefined)
}

UdpWrapper.prototype.init = function (host, port) {
  this._host = host
  this._port = port
  var self = this
  // if socket is defined/used externally
  if (this._externalSocket) {
    // store original message and error listeners, if any
    this._messageListeners = this._socket.listeners('message')
    this._errorListeners = this._socket.listeners('error')
    // temp remove these listeners ...
    this._messageListeners.forEach(function (callback) {
      self._socket.removeListener('message', callback)
    })
    this._errorListeners.forEach(function (callback) {
      self._socket.removeListener('error', callback)
    })
  }
  // register our own handlers
  this._socket.on('message', function(message, rinfo) {
    self._onData(message, rinfo, true)
  })
  this._socket.on('error', this._onError)
}

UdpWrapper.prototype.send = function (bytes, onSuccess, onFailure) {
  if (onSuccess === undefined || onFailure === undefined) {
    var error = 'udp send bytes callback handlers are undefined'
    errorLog(error)
    throw new Error(error)
  }
  this._socket.send(bytes, 0, bytes.length, this._port, this._host, function (error) {
    if (error) {
      onFailure(error)
      return
    }
    onSuccess()
  })
}

UdpWrapper.prototype.sendP = function (bytes) {
  var deferred = Q.defer()
  var self = this
  this.send(
    bytes,
    function () { // on success
      deferred.resolve()
    },
    function (error) {
      var errorMsg = 'udp wrapper could not send bytes to ' + self._host + ':' + self._port + '. ' + error
      errorLog(errorMsg)
      deferred.reject(errorMsg)
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.close = function (done) {
  var self = this
  // if socket is defined/used externally
  if (this._externalSocket) {
    // remove temp listeners
    this._socket.listeners('message').forEach(function (callback) {
      self._socket.removeListener('message', callback)
    })
    this._socket.listeners('error').forEach(function (callback) {
      self._socket.removeListener('error', callback)
    })
    // restore the original listeners
    this._messageListeners.forEach(function (callback) {
      self._socket.on('message', callback)
    })
    this._errorListeners.forEach(function (callback) {
      self._socket.on('error', callback)
    })
    // and remove refs to these original listeners
    this._messageListeners = this._errorListeners = []
    // fire callback
    if (done) {
      done()
    }
  } else {
    // close socket
    this._socket.close(function () {
      // fire callback
      if (done) {
        done()
      }
    })
  }
}

UdpWrapper.prototype.closeP = function () {
  var deferred = Q.defer()
  this.close(
    function () { // on success
      deferred.resolve()
    }
  )
  return deferred.promise
}

UdpWrapper.prototype.onData = function (callback) {
  this._onData = callback
}

UdpWrapper.prototype.onError = function (callback) {
  this._onError = callback
}

module.exports = UdpWrapper
<|endoftext|>


<commit_before>(function() {
  'use strict';

  function sequoiaTreeDirective(Tree){

    return {
      restrict: 'AE',
      replace: true,
      templateUrl: 'angular-sequoia.html',
      scope: {
        'treeNodes': '=sequoiaTree',
        'model': '=ngModel',
        'template': '=nodeTemplate',
        'options': '='
      },
      link: function(scope) {
        scope.canEdit = scope.options.canEdit ? true : false;

        scope.model = _.isArray(scope.model) ? scope.model : [];
        scope.breadcrumbs = [];

        var tree = new Tree(scope.treeNodes, scope.template);

        scope.load = function(node) {
          scope.onlySelected = false;
          if(tree.isValidNode(node)) {
            tree.setCurrentNodes(node[tree.template.nodes]);
            scope.breadcrumbs = tree.breadcrumbs(node[tree.template.id]);
          } else {
            tree.setCurrentNodes();
            scope.breadcrumbs = [];
          }
        };

        scope.select = function(node) {
          if(node[tree.template.id]) {
            scope.model.push(node[tree.template.id]);
          }
        };

        scope.remove = function(node) {
          var index = node._id ? _.indexOf(scope.model,node[tree.template.id]) : -1;
          if(index !== -1) {
            scope.model.splice(index, 1);
          }
        };

        scope.isSelected = function(node) {
          return _.indexOf(scope.model, node[tree.template.id]) !== -1 ? true : false;
        };

        scope.toggleSelected = function() {
          if(scope.onlySelected) {
            scope.onlySelected = false;
            tree.setCurrentNodes(tree.getNodesInPath());
          } else {
            scope.onlySelected = true;
            var selected = tree.findSelected(scope.model);
            tree.setNodesInPath(tree.nodes);
            tree.setCurrentNodes(selected);
          }
        };

        scope.tree = tree;

        scope.load();
      }
    };

  }

  sequoiaTreeDirective.$inject = ['SequoiaTree'];

  angular.module('ngSequoia')
    .directive('sequoiaTree', sequoiaTreeDirective);

})();<commit_msg>Rename remove to deselect<commit_after>(function() {
  'use strict';

  function sequoiaTreeDirective(Tree){

    return {
      restrict: 'AE',
      replace: true,
      templateUrl: 'angular-sequoia.html',
      scope: {
        'treeNodes': '=sequoiaTree',
        'model': '=ngModel',
        'template': '=nodeTemplate',
        'options': '='
      },
      link: function(scope) {
        scope.canEdit = scope.options.canEdit ? true : false;

        scope.model = _.isArray(scope.model) ? scope.model : [];
        scope.breadcrumbs = [];

        var tree = new Tree(scope.treeNodes, scope.template);

        scope.load = function(node) {
          scope.onlySelected = false;
          if(tree.isValidNode(node)) {
            tree.setCurrentNodes(node[tree.template.nodes]);
            scope.breadcrumbs = tree.breadcrumbs(node[tree.template.id]);
          } else {
            tree.setCurrentNodes();
            scope.breadcrumbs = [];
          }
        };

        scope.select = function(node) {
          if(node[tree.template.id]) {
            scope.model.push(node[tree.template.id]);
          }
        };

        scope.deselect = function(node) {
          var index = node[tree.template.id] ? _.indexOf(scope.model,node[tree.template.id]) : -1;
          if(index !== -1) {
            scope.model.splice(index, 1);
          }
        };

        scope.isSelected = function(node) {
          return _.indexOf(scope.model, node[tree.template.id]) !== -1 ? true : false;
        };

        scope.toggleSelected = function() {
          if(scope.onlySelected) {
            scope.onlySelected = false;
            tree.setCurrentNodes(tree.getNodesInPath());
          } else {
            scope.onlySelected = true;
            var selected = tree.findSelected(scope.model);
            tree.setNodesInPath(tree.nodes);
            tree.setCurrentNodes(selected);
          }
        };

        scope.tree = tree;

        scope.load();
      }
    };

  }

  sequoiaTreeDirective.$inject = ['SequoiaTree'];

  angular.module('ngSequoia')
    .directive('sequoiaTree', sequoiaTreeDirective);

})();<|endoftext|>


<commit_before>// On Web, this will find .env.defaults and optional .env in web/
// On Desktop App, this will find .env.defaults and optional .env in root dir
require('dotenv-defaults').config({ silent: false });

const config = {
  MATOMO_URL: process.env.MATOMO_URL,
  MATOMO_ID: process.env.MATOMO_ID,
  WEBPACK_WEB_PORT: process.env.WEBPACK_WEB_PORT,
  WEBPACK_ELECTRON_PORT: process.env.WEBPACK_ELECTRON_PORT,
  WEB_SERVER_PORT: process.env.WEB_SERVER_PORT,
  LBRY_WEB_API: process.env.LBRY_WEB_API, //api.lbry.tv',
  LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
  LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
  LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
  WELCOME_VERSION: process.env.WELCOME_VERSION,
  DOMAIN: process.env.DOMAIN,
  SHARE_DOMAIN_URL: process.env.SHARE_DOMAIN_URL,
  URL: process.env.URL,
  THUMBNAIL_CDN_URL: process.env.THUMBNAIL_CDN_URL,
  SITE_TITLE: process.env.SITE_TITLE,
  SITE_NAME: process.env.SITE_NAME,
  SITE_DESCRIPTION: process.env.SITE_DESCRIPTION,
  LOGO_TITLE: process.env.LOGO_TITLE,
  OG_TITLE_SUFFIX: process.env.OG_TITLE_SUFFIX,
  OG_HOMEPAGE_TITLE: process.env.OG_HOMEPAGE_TITLE,
  OG_IMAGE_URL: process.env.OG_IMAGE_URL,
  YRBL_HAPPY_IMG_URL: process.env.YRBL_HAPPY_IMG_URL,
  YRBL_SAD_IMG_URL: process.env.YRBL_SAD_IMG_URL,
  SITE_CANONICAL_URL: process.env.SITE_CANONICAL_URL,
  DEFAULT_LANGUAGE: process.env.DEFAULT_LANGUAGE,
  AUTO_FOLLOW_CHANNELS: process.env.AUTO_FOLLOW_CHANNELS,
  UNSYNCED_SETTINGS: process.env.UNSYNCED_SETTINGS,
  ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
  ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true',
  ENABLE_CREATOR_REACTIONS: process.env.ENABLE_CREATOR_REACTIONS === 'true',
  SIMPLE_SITE: process.env.SIMPLE_SITE === 'true',
  SHOW_ADS: process.env.SHOW_ADS === 'true',
  PINNED_URI_1: process.env.PINNED_URI_1,
  PINNED_LABEL_1: process.env.PINNED_LABEL_1,
  PINNED_URI_2: process.env.PINNED_URI_2,
  PINNED_LABEL_2: process.env.PINNED_LABEL_2,
  KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS,
};

config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
config.URL_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;

module.exports = config;
<commit_msg>fix lbry.com links triggering lbry:// link file render<commit_after>// On Web, this will find .env.defaults and optional .env in web/
// On Desktop App, this will find .env.defaults and optional .env in root dir
require('dotenv-defaults').config({ silent: false });

const config = {
  MATOMO_URL: process.env.MATOMO_URL,
  MATOMO_ID: process.env.MATOMO_ID,
  WEBPACK_WEB_PORT: process.env.WEBPACK_WEB_PORT,
  WEBPACK_ELECTRON_PORT: process.env.WEBPACK_ELECTRON_PORT,
  WEB_SERVER_PORT: process.env.WEB_SERVER_PORT,
  LBRY_WEB_API: process.env.LBRY_WEB_API, //api.lbry.tv',
  LBRY_API_URL: process.env.LBRY_API_URL, //api.lbry.com',
  LBRY_WEB_STREAMING_API: process.env.LBRY_WEB_STREAMING_API, //cdn.lbryplayer.xyz',
  LBRY_WEB_BUFFER_API: process.env.LBRY_WEB_BUFFER_API,
  WELCOME_VERSION: process.env.WELCOME_VERSION,
  DOMAIN: process.env.DOMAIN,
  SHARE_DOMAIN_URL: process.env.SHARE_DOMAIN_URL,
  URL: process.env.URL,
  THUMBNAIL_CDN_URL: process.env.THUMBNAIL_CDN_URL,
  SITE_TITLE: process.env.SITE_TITLE,
  SITE_NAME: process.env.SITE_NAME,
  SITE_DESCRIPTION: process.env.SITE_DESCRIPTION,
  LOGO_TITLE: process.env.LOGO_TITLE,
  OG_TITLE_SUFFIX: process.env.OG_TITLE_SUFFIX,
  OG_HOMEPAGE_TITLE: process.env.OG_HOMEPAGE_TITLE,
  OG_IMAGE_URL: process.env.OG_IMAGE_URL,
  YRBL_HAPPY_IMG_URL: process.env.YRBL_HAPPY_IMG_URL,
  YRBL_SAD_IMG_URL: process.env.YRBL_SAD_IMG_URL,
  SITE_CANONICAL_URL: process.env.SITE_CANONICAL_URL,
  DEFAULT_LANGUAGE: process.env.DEFAULT_LANGUAGE,
  AUTO_FOLLOW_CHANNELS: process.env.AUTO_FOLLOW_CHANNELS,
  UNSYNCED_SETTINGS: process.env.UNSYNCED_SETTINGS,
  ENABLE_COMMENT_REACTIONS: process.env.ENABLE_COMMENT_REACTIONS === 'true',
  ENABLE_FILE_REACTIONS: process.env.ENABLE_FILE_REACTIONS === 'true',
  ENABLE_CREATOR_REACTIONS: process.env.ENABLE_CREATOR_REACTIONS === 'true',
  SIMPLE_SITE: process.env.SIMPLE_SITE === 'true',
  SHOW_ADS: process.env.SHOW_ADS === 'true',
  PINNED_URI_1: process.env.PINNED_URI_1,
  PINNED_LABEL_1: process.env.PINNED_LABEL_1,
  PINNED_URI_2: process.env.PINNED_URI_2,
  PINNED_LABEL_2: process.env.PINNED_LABEL_2,
  KNOWN_APP_DOMAINS: process.env.KNOWN_APP_DOMAINS ? process.env.KNOWN_APP_DOMAINS.split(',') : [],
};

config.URL_LOCAL = `http://localhost:${config.WEB_SERVER_PORT}`;
config.URL_DEV = `http://localhost:${config.WEBPACK_WEB_PORT}`;

module.exports = config;
<|endoftext|>


<commit_before>import DayGridPlugin from '@fullcalendar/daygrid'
import RRulePlugin from '@fullcalendar/rrule'
import { parseUtcDate, parseLocalDate } from '../lib/date-parsing'

describe('rrule plugin', function() {
  pushOptions({
    plugins: [ RRulePlugin, DayGridPlugin ],
    defaultView: 'dayGridMonth',
    now: '2018-09-07',
    timeZone: 'UTC'
  })

  it('expands events when given an rrule string', function() {
    initCalendar({
      events: [
        {
          rrule: 'DTSTART:20180904T130000\nRRULE:FREQ=WEEKLY'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
    expect(events[4].start).toEqualDate('2018-10-02T13:00:00Z')
  })

  it('respects allDay when an rrule string', function() {
    initCalendar({
      events: [
        {
          allDay: true,
          rrule: 'DTSTART:20180904T130000\nRRULE:FREQ=WEEKLY'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events[0].start).toEqualDate('2018-09-04') // should round down
    expect(events[0].allDay).toBe(true)
    expect(events[0].extendedProps).toEqual({}) // didnt accumulate allDay or rrule props
  })

  it('expands events when given an rrule object', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
    expect(events[4].start).toEqualDate('2018-10-02T13:00:00Z')
  })

  it('can expand monthly recurrence', function() {
    initCalendar({
      defaultView: 'dayGridMonth',
      now: '2018-12-25T12:00:00',
      events: [ {
        rrule: {
          dtstart: '2018-11-01',
          freq: 'monthly',
          count: 13,
          bymonthday: [ 13 ]
        }
      } ]
    })

    let events = currentCalendar.getEvents()
    expect(events.length).toBe(1)
    expect(events[0].start).toEqualDate('2018-12-13')
  })

  it('expands events until a date', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            until: '2018-10-01',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(4)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
  })

  // https://github.com/fullcalendar/fullcalendar/issues/4596
  it('expands a range that starts exactly at the current view\'s start', function() {
    initCalendar({
      defaultDate: '2019-04-02',
      defaultView: 'dayGridDay',
      events: [
        {
          title: 'event with everyday with range',
          allDay: true,
          rrule: {
            freq: 'daily',
            dtstart: '2019-04-02',
            until: '2019-04-09'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBeGreaterThanOrEqual(1)
    expect(events[0].start).toEqualDate('2019-04-02')
  })

  it('expands events with a duration', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            freq: 'weekly'
          },
          duration: '03:00'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toEqualDate('2018-09-04T16:00:00Z')
  })

  it('expands events with guessed allDay', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(true)
  })

  it('inherits allDayDefault from source', function() {
    initCalendar({
      allDayDefault: false,
      events: [
        {
          rrule: {
            dtstart: parseUtcDate('2018-09-04'), // no allDay info
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  it('inherits allDayDefault from source setting', function() {
    initCalendar({
      eventSources: [ {
        allDayDefault: false,
        events: [
          {
            rrule: {
              dtstart: parseUtcDate('2018-09-04'), // no allDay info
              freq: 'weekly'
            }
          }
        ]
      } ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  it('can generate local dates', function() {
    initCalendar({
      timeZone: 'local',
      events: [
        {
          rrule: {
            dtstart: parseLocalDate('2018-09-04T05:00:00').toISOString(),
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualLocalDate('2018-09-04T05:00:00')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  function getSortedEvents() {
    let events = currentCalendar.getEvents()

    events.sort(function(eventA, eventB) {
      return eventA._instance.range.start - eventB._instance.range.start // faster than .start
    })

    return events
  }

})
<commit_msg>Change description of one test and add another<commit_after>import DayGridPlugin from '@fullcalendar/daygrid'
import RRulePlugin from '@fullcalendar/rrule'
import { parseUtcDate, parseLocalDate } from '../lib/date-parsing'

describe('rrule plugin', function() {
  pushOptions({
    plugins: [ RRulePlugin, DayGridPlugin ],
    defaultView: 'dayGridMonth',
    now: '2018-09-07',
    timeZone: 'UTC'
  })

  it('expands events when given an rrule string', function() {
    initCalendar({
      events: [
        {
          rrule: 'DTSTART:20180904T130000\nRRULE:FREQ=WEEKLY'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
    expect(events[4].start).toEqualDate('2018-10-02T13:00:00Z')
  })

  it('respects allDay when an rrule string', function() {
    initCalendar({
      events: [
        {
          allDay: true,
          rrule: 'DTSTART:20180904T130000\nRRULE:FREQ=WEEKLY'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events[0].start).toEqualDate('2018-09-04') // should round down
    expect(events[0].allDay).toBe(true)
    expect(events[0].extendedProps).toEqual({}) // didnt accumulate allDay or rrule props
  })

  it('expands events when given an rrule object', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
    expect(events[4].start).toEqualDate('2018-10-02T13:00:00Z')
  })

  it('can expand monthly recurrence', function() {
    initCalendar({
      defaultView: 'dayGridMonth',
      now: '2018-12-25T12:00:00',
      events: [ {
        rrule: {
          dtstart: '2018-11-01',
          freq: 'monthly',
          count: 13,
          bymonthday: [ 13 ]
        }
      } ]
    })

    let events = currentCalendar.getEvents()
    expect(events.length).toBe(1)
    expect(events[0].start).toEqualDate('2018-12-13')
  })

  it('expands events until a date', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            until: '2018-10-01',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(4)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toBe(null)
    expect(events[1].start).toEqualDate('2018-09-11T13:00:00Z')
    expect(events[2].start).toEqualDate('2018-09-18T13:00:00Z')
    expect(events[3].start).toEqualDate('2018-09-25T13:00:00Z')
  })

  // https://github.com/fullcalendar/fullcalendar/issues/4596
  it('expands a range that starts exactly at the current view\'s start', function() {
    initCalendar({
      defaultDate: '2019-04-02',
      defaultView: 'dayGridDay',
      events: [
        {
          title: 'event with everyday with range',
          allDay: true,
          rrule: {
            freq: 'daily',
            dtstart: '2019-04-02',
            until: '2019-04-09'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBeGreaterThanOrEqual(1)
    expect(events[0].start).toEqualDate('2019-04-02')
  })

  it('expands events with a duration', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04T13:00:00',
            freq: 'weekly'
          },
          duration: '03:00'
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04T13:00:00Z')
    expect(events[0].end).toEqualDate('2018-09-04T16:00:00Z')
  })

  it('expands events with guessed allDay', function() {
    initCalendar({
      events: [
        {
          rrule: {
            dtstart: '2018-09-04',
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(true)
  })

  it('inherits allDayDefault from source', function() {
    initCalendar({
      allDayDefault: false,
      events: [
        {
          rrule: {
            dtstart: parseUtcDate('2018-09-04'), // no allDay info
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  it('inherits allDayDefault from source setting', function() {
    initCalendar({
      eventSources: [ {
        allDayDefault: false,
        events: [
          {
            rrule: {
              dtstart: parseUtcDate('2018-09-04'), // no allDay info
              freq: 'weekly'
            }
          }
        ]
      } ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualDate('2018-09-04')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  it('can generate local dates when rrule is defined in object form', function() {
    initCalendar({
      timeZone: 'local',
      events: [
        {
          rrule: {
            dtstart: parseLocalDate('2018-09-04T05:00:00').toISOString(),
            freq: 'weekly'
          }
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualLocalDate('2018-09-04T05:00:00')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  it('can generate local dates when rrule is defined as icalendar string', function() {
    const localDateToUTCIsoString = parseLocalDate('2018-09-04T05:00:00').toISOString()
    const modified = localDateToUTCIsoString.replace('.000', '').replace(/[\-\:]/g, '')
    initCalendar({
      timeZone: 'local',
      events: [
        {
          rrule: `DTSTART:${modified}\nRRULE:FREQ=WEEKLY`,
        }
      ]
    })
    let events = getSortedEvents()
    expect(events.length).toBe(5)
    expect(events[0].start).toEqualLocalDate('2018-09-04T05:00:00')
    expect(events[0].end).toBe(null)
    expect(events[0].allDay).toBe(false)
  })

  function getSortedEvents() {
    let events = currentCalendar.getEvents()

    events.sort(function(eventA, eventB) {
      return eventA._instance.range.start - eventB._instance.range.start // faster than .start
    })

    return events
  }

})
<|endoftext|>