<commit_before>/*
 * freepano - WebGL panorama viewer
 *
 * Copyright (c) 2014 FOXEL SA - http://foxel.ch
 * Please read <http://foxel.ch/license> for more information.
 *
 *
 * Author(s):
 *
 *      Kevin Velickovic <k.velickovic@foxel.ch>
 *
 *
 * Contributor(s):
 *
 *      Luc Deschenaux <l.deschenaux@foxel.ch>
 *      Alexandre Kraft
 *
 *
 * This file is part of the FOXEL project <http://foxel.ch>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Additional Terms:
 *
 *      You are required to preserve legal notices and author attributions in
 *      that material or in the Appropriate Legal Notices displayed by works
 *      containing it.
 *
 *      You are required to attribute the work as explained in the "Usage and
 *      Attribution" section of <http://foxel.ch/license>.
 */

// Plugin constructor
function Map(options)
{
    if (!(this instanceof Map)) {
      return new Map(options);
    }

    // merge specified options with default options and extend this instance
    $.extend(true,this,Map.prototype.defaults,options);

    // Initialize plugin
    this.init();
}

// Extend plugin prototype
$.extend(true, Map.prototype, {

    // default values
    defaults: {
        // active
        active: false,

        // leaflet defaults
        leaflet: {

            // see http://leafletjs.com/reference.html#tilelayer-options
            tileLayer: {

                url_template: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',

                options: {
                     attribution: '© OpenStreetMap contributors'
                }

            },

            origin: [51.505, -0.09], // default geographical coordinates

            zoom: {
                base: 4,
                min: 3,
                max: 25,
                native: 18,
                bounds: 18
            },

            // see http://leafletjs.com/reference.html#map-zoompanoptions
            zoompan_options: undefined,

            icon: {
                iconUrl: 'img/marker_icon.png', // marker icon url
                shadowUrl: 'img/marker_shadow.png', // marker shadow image url
                iconSize: [22.5, 36.25], // marker size
                shadowSize: [40.75, 36.25], // marker shadow size
                iconAnchor: [22.5/2, 36.25], // point corresponding to marker's location
                shadowAnchor: [22.5/2, 36.25],
                popupAnchor: [0, 0] // point from which menu should popup relative to the iconAnchor
            },

            icon_highlighted: {
                iconUrl:     'img/marker_icon_highlight.png',
                shadowUrl:   'img/marker_shadow.png'
            }
        }
    },

    show: function map_show() {

        var map=this;

        // dom
        var pano = map.panorama;
        var container = $(pano.container);

        // map container exists ?
        var div=$('.map',container);
        if (div.length) {
            // then show map if hidden and/or return
            if (!$(div).is(':visible')) {
                div.show();
            }
            return;
        }

        // Append map
        var mapContainer = $('
',{'class':'map'});
        container.append(mapContainer);

        // Create leaflet map object
        var leaflet = map.leaflet.instance = L.map(mapContainer[0], {
            keyboard: false,
            scrollWheelZoom: true,
            minZoom: map.leaflet.zoom.min,
            maxZoom: map.leaflet.zoom.max
        }).setView(map.leaflet.origin, map.leaflet.zoom.base, map.leaflet.zoompan_options);

        // add a tile layer
        L.tileLayer(map.leaflet.tileLayer.url_template, $.extend(true,{},map.leaflet.tileLayer.options,{
            minZoom: map.leaflet.zoom.min,
            maxZoom: map.leaflet.zoom.max,
            maxNativeZoom: map.leaflet.zoom.native
        })).addTo(leaflet);

        // Create marker icon
        var markerIcon = L.icon(map.leaflet.icon);

        // Create highlighted marker icon
        var markerIcon_Highlighted = L.icon($.extend(true,{},map.leaflet.icon,map.leaflet.icon_highlighted));

        var markers = [];

        // Iterate over panoramas and create markers
        $.each(pano.list.images, function( index, image ) {

            // No geo coordinates
            if (image.coords === undefined || image.coords === null)
                return;

            // Icon
            var icon = markerIcon;

            // Use initial image if set and currentImage is not defined
            if (pano.list.currentImage === undefined && pano.list.initialImage !== undefined)
                pano.list.currentImage = pano.list.initialImage;

            // Use first image if currentImage is not defined
            else if (pano.list.currentImage === undefined)
                pano.list.currentImage = Object.keys(pano.list.images)[0];

            // Determine if the marker is highlighted
            if ( pano.list.currentImage == index )
                icon = markerIcon_Highlighted;

            // Create marker
            var marker = L.marker([image.coords.lat, image.coords.lon], {icon: icon})
            .on('click', function(e) {

                // Reset all markers to default icon
                $.each(markers, function( index, marker ) {
                    if (marker!==e.target)
                      marker.setIcon(markerIcon);
                });

                // Set highlighted icon for marker
                e.target.setIcon(markerIcon_Highlighted);

                // Check if panorama has changed, then change it
                var changed = e.target.panorama.index != pano.list.currentImage;
                if(changed)
                    pano.list.show(e.target.panorama.index);

                // Spread event
                $(map).trigger('markerclick',{changed:changed,target:e.target.panorama.index});

            });

            // Extend marker with panorama object
            $.extend( marker, {
                panorama: {
                    index: index,
                    image: image
                }
            });

            // Add marker to array
            markers.push( marker )

            // Add marker to map
            marker.addTo(leaflet)

        });

        // No elligible markers
        if (markers.length == 0) {
            this.hide();
            return;
        }

        // Create makers featureGroup
        var markersGroup = new L.featureGroup(markers);

        // Fit map to markers
        leaflet.fitBounds(markersGroup.getBounds());

        // Unzoom from bounds
        if (leaflet.getZoom() > map.leaflet.zoom.bounds)
            leaflet.setZoom(map.leaflet.zoom.bounds);
        else
            leaflet.setZoom(leaflet.getZoom()-1);

    }, // map_show

    hide: function map_hide() {
        $('.map',this.panorama.container).hide();
    },

    remove: function map_remove() {
        $('.map',this.panorama.container).remove();
    },

    init: function map_init() {
        var map = this;

        // watch touch move properties
        watch(map,['active'], function() {
            if (map.active)
                map.show();
            else
                map.hide();
        });

        map.callback({target: map, type: 'ready'});

    }, // map_init

    callback: function map_callback(e) {
        var map=e.target;
        switch(e.type){
            case 'ready':
                // chain with old panorama.prototype.init on callback
                map.panorama_init.call(map.panorama);
                break;
        }
    } // map_callback

});

// register freepano.map plugin

$.extend(Map.prototype,{
    // save pointers to overrided Panorama.prototype methods
    panorama_init: Panorama.prototype.init,
    panorama_callback: Panorama.prototype.callback
});

$.extend(Panorama.prototype,{

  // hook Map.prototype.init to Panorama.prototype.init
  init: function map_panorama_init() {

    var panorama=this;

    // skip Map instantiation if map preferences undefined in panorama
    if (panorama.map!==undefined) {

      // or if map is already instantiated
      if (!(panorama.map instanceof Map)) {

        // instantiate map
        panorama.map=new Map($.extend(true,{

          // pass panorama instance pointer to map instance
          panorama: panorama,

        },panorama.map));

      }

    } else {

      // chain with old panorama.prototype.init
      Map.prototype.panorama_init.call(panorama);

    }
  }, // map_panorama_init

  // hook to Panorama.prototype.callback
  callback: function map_panorama_callback(panorama_event) {
    var panorama=this;
    var map=panorama.map;

    if (map!=undefined) {
      switch(panorama_event.type){

        // show map on pano ready
        case 'ready':
          if (map.active) {
            map.show();
          } else {
            map.hide();
          }
          break;

      } // switch panorama_event.type
    }

    // chain with previous panorama callback
    Map.prototype.panorama_callback.apply(panorama,[panorama_event]);

  } // map_panorama_callback

});

<commit_msg>updated jquery.freepano.map.js<commit_after>/*
 * freepano - WebGL panorama viewer
 *
 * Copyright (c) 2014 FOXEL SA - http://foxel.ch
 * Please read <http://foxel.ch/license> for more information.
 *
 *
 * Author(s):
 *
 *      Kevin Velickovic <k.velickovic@foxel.ch>
 *
 *
 * Contributor(s):
 *
 *      Luc Deschenaux <l.deschenaux@foxel.ch>
 *      Alexandre Kraft
 *
 *
 * This file is part of the FOXEL project <http://foxel.ch>.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *
 * Additional Terms:
 *
 *      You are required to preserve legal notices and author attributions in
 *      that material or in the Appropriate Legal Notices displayed by works
 *      containing it.
 *
 *      You are required to attribute the work as explained in the "Usage and
 *      Attribution" section of <http://foxel.ch/license>.
 */

// Plugin constructor
function Map(options)
{
    if (!(this instanceof Map)) {
      return new Map(options);
    }

    // merge specified options with default options and extend this instance
    $.extend(true,this,Map.prototype.defaults,options);

    // Initialize plugin
    this.init();
}

// Extend plugin prototype
$.extend(true, Map.prototype, {

    // default values
    defaults: {
        // active
        active: true,

        // leaflet defaults
        leaflet: {

            // see http://leafletjs.com/reference.html#tilelayer-options
            tileLayer: {

                url_template: 'http://{s}.tile.osm.org/{z}/{x}/{y}.png',

                options: {
                     attribution: '© OpenStreetMap contributors'
                }

            },

            origin: [51.505, -0.09], // default geographical coordinates

            zoom: {
                base: 4,
                min: 3,
                max: 25,
                native: 18,
                bounds: 18
            },

            // see http://leafletjs.com/reference.html#map-zoompanoptions
            zoompan_options: undefined,

            icon: {
                iconUrl: 'img/marker_icon.png', // marker icon url
                shadowUrl: 'img/marker_shadow.png', // marker shadow image url
                iconSize: [22.5, 36.25], // marker size
                shadowSize: [40.75, 36.25], // marker shadow size
                iconAnchor: [22.5/2, 36.25], // point corresponding to marker's location
                shadowAnchor: [22.5/2, 36.25],
                popupAnchor: [0, 0] // point from which menu should popup relative to the iconAnchor
            },

            icon_highlighted: {
                iconUrl:     'img/marker_icon_highlight.png',
                shadowUrl:   'img/marker_shadow.png'
            }
        }
    },

    show: function map_show() {

        var map=this;

        // dom
        var pano = map.panorama;
        var container = $(pano.container);

        // map container exists ?
        var div=$('.map',container);
        if (div.length) {
            // then show map if hidden and/or return
            if (!$(div).is(':visible')) {
                div.show();
            }
            return;
        }

        // Append map
        var mapContainer = $('
',{'class':'map'});
        container.append(mapContainer);

        // Create leaflet map object
        var leaflet = map.leaflet.instance = L.map(mapContainer[0], {
            keyboard: false,
            scrollWheelZoom: true,
            minZoom: map.leaflet.zoom.min,
            maxZoom: map.leaflet.zoom.max
        }).setView(map.leaflet.origin, map.leaflet.zoom.base, map.leaflet.zoompan_options);

        // add a tile layer
        L.tileLayer(map.leaflet.tileLayer.url_template, $.extend(true,{},map.leaflet.tileLayer.options,{
            minZoom: map.leaflet.zoom.min,
            maxZoom: map.leaflet.zoom.max,
            maxNativeZoom: map.leaflet.zoom.native
        })).addTo(leaflet);

        // Create marker icon
        var markerIcon = L.icon(map.leaflet.icon);

        // Create highlighted marker icon
        var markerIcon_Highlighted = L.icon($.extend(true,{},map.leaflet.icon,map.leaflet.icon_highlighted));

        var markers = [];

        // Iterate over panoramas and create markers
        $.each(pano.list.images, function( index, image ) {

            // No geo coordinates
            if (image.coords === undefined || image.coords === null)
                return;

            // Icon
            var icon = markerIcon;

            // Use initial image if set and currentImage is not defined
            if (pano.list.currentImage === undefined && pano.list.initialImage !== undefined)
                pano.list.currentImage = pano.list.initialImage;

            // Use first image if currentImage is not defined
            else if (pano.list.currentImage === undefined)
                pano.list.currentImage = Object.keys(pano.list.images)[0];

            // Determine if the marker is highlighted
            if ( pano.list.currentImage == index )
                icon = markerIcon_Highlighted;

            // Create marker
            var marker = L.marker([image.coords.lat, image.coords.lon], {icon: icon})
            .on('click', function(e) {

                // Reset all markers to default icon
                $.each(markers, function( index, marker ) {
                    if (marker!==e.target)
                      marker.setIcon(markerIcon);
                });

                // Set highlighted icon for marker
                e.target.setIcon(markerIcon_Highlighted);

                // Check if panorama has changed, then change it
                var changed = e.target.panorama.index != pano.list.currentImage;
                if(changed)
                    pano.list.show(e.target.panorama.index);

                // Spread event
                $(map).trigger('markerclick',{changed:changed,target:e.target.panorama.index});

            });

            // Extend marker with panorama object
            $.extend( marker, {
                panorama: {
                    index: index,
                    image: image
                }
            });

            // Add marker to array
            markers.push( marker )

            // Add marker to map
            marker.addTo(leaflet)

        });

        // No elligible markers
        if (markers.length == 0) {
            this.hide();
            return;
        }

        // Create makers featureGroup
        var markersGroup = new L.featureGroup(markers);

        // Fit map to markers
        leaflet.fitBounds(markersGroup.getBounds());

        // Unzoom from bounds
        if (leaflet.getZoom() > map.leaflet.zoom.bounds)
            leaflet.setZoom(map.leaflet.zoom.bounds);
        else
            leaflet.setZoom(leaflet.getZoom()-1);

    }, // map_show

    hide: function map_hide() {
        $('.map',this.panorama.container).hide();
    },

    remove: function map_remove() {
        $('.map',this.panorama.container).remove();
    },

    init: function map_init() {
        var map = this;

        if (map.active) map.show();

        // watch touch move properties
        watch(map,['active'], function() {
            if (map.active)
                map.show();
            else
                map.hide();
        });

        map.callback({target: map, type: 'ready'});

    }, // map_init

    callback: function map_callback(e) {
        var map=e.target;
        switch(e.type){
            case 'ready':
                // chain with old panorama.prototype.init on callback
                map.panorama_init.call(map.panorama);
                break;
        }
    } // map_callback

});

// register freepano.map plugin

$.extend(Map.prototype,{
    // save pointers to overrided Panorama.prototype methods
    panorama_init: Panorama.prototype.init,
    panorama_callback: Panorama.prototype.callback
});

$.extend(Panorama.prototype,{

  // hook Map.prototype.init to Panorama.prototype.init
  init: function map_panorama_init() {

    var panorama=this;

    // skip Map instantiation if map preferences undefined in panorama
    if (panorama.map!==undefined) {

      // or if map is already instantiated
      if (!(panorama.map instanceof Map)) {

        // instantiate map
        panorama.map=new Map($.extend(true,{

          // pass panorama instance pointer to map instance
          panorama: panorama,

        },panorama.map));

      }

    } else {

      // chain with old panorama.prototype.init
      Map.prototype.panorama_init.call(panorama);

    }
  }, // map_panorama_init

  // hook to Panorama.prototype.callback
  callback: function map_panorama_callback(panorama_event) {
    var panorama=this;
    var map=panorama.map;

    if (map!=undefined) {
      switch(panorama_event.type){

        // show map on pano ready
        case 'ready':
          if (map.active) {
            map.show();
          } else {
            map.hide();
          }
          break;

      } // switch panorama_event.type
    }

    // chain with previous panorama callback
    Map.prototype.panorama_callback.apply(panorama,[panorama_event]);

  } // map_panorama_callback

});

<|endoftext|>


<commit_before>'use strict';

var Boom = require('boom');
var _ = require('lodash');
var pluginName = 'pluginJsonapi';
var utilities = require('./utilities');

// some paths sinply don't want to be jsonapi'd
var ignorePaths = [
  '/', // Lout documentation and AWS healthcheck
  '/css/{path*}' // Lout documentation
];

// certain status codes shouldn't be jsonapi'd
var ignoreStatusCodes = [
  201, // Created (used on POST)
  204 // No Content (used on DELETE)
];

var pluginJsonApi = module.exports = {};

pluginJsonApi.errorHandler = function errorHandler( request, reply, error ) {
  request.log( ['error', __filename, pluginName], {
    error: error.toString(),
    data: request.data
  } );

  return reply(Boom.internal(error));
};

pluginJsonApi.makeItSo = function makeItSo( request, reply ) { // eslint-disable-line consistent-return

  try {
    // If there was no error and it's not one of our ignoredPaths or ignored status codes, jsonapi it
    if (request.response.isBoom || _.includes(ignorePaths, request.route.path) || _.includes(ignoreStatusCodes, request.response.statusCode)) {
      // return early
      return reply.continue();
    }

    // Make the response a bit more accessible
    var result = _.get(request, 'response.source');
    // check a bind configuration is present
    if ( !_.get(request, 'route.settings.bind')) {
      throw new Error('configuration bind.resourceName not found on handler');
    }

    // Get the current resource from the result
    var resources = result[request.route.settings.bind.resourceName];
    if (!resources) {
      // no resources, return early
      return reply.continue();
    }

    var stateObject = {
      request: request,
      resources: resources
    };

    /*
     * Flow
     * collectIncludes() - store the includes for later
     * getSubResources() - get the sub resources which will be linked
     * getResources() - get the resources
     * resolveLinkedData() - resolve the sub resources which we have collected previously
     */
    utilities.collectIncludes(stateObject)
    .then(utilities.getSubResources)
    .then(utilities.getResources)
    .then(utilities.resolveLinkedData)
    .then(function() {
      // all done
      return reply.continue();
    })
    .fail(function(error) {
      return pluginJsonApi.errorHandler(request, reply, error);
    })
    .done();

  } catch ( error ) {
    return pluginJsonApi.errorHandler(request, reply, error);
  }
};

/**
* Registers the plugin when the hapi server bootstraps - follows the convention for Hapi.js plugins
* @param {object} server - the hapi plugin object
* @param {object} options - any initial options needed to set up the plugin
* @param {function} next - the next plugin to be set up
* @returns {undefined} Nothing - calls the next plugin
*/
pluginJsonApi.register = function(server, options, next) {

  function makeItSo(request, reply) {
    return pluginJsonApi.alsoMakeItSo(request, reply);
  }

  // Extend the onPreResponse for EVERY request through the api
  server.ext('onPreResponse', makeItSo);

  // In order to test this functionality it needs to be exposed on the server.
  if (process.env.NODE_ENV === 'test') {
    server.expose('makeItSo', makeItSo);
  }

  next();
};

pluginJsonApi.register.attributes = {
  pkg: require('../package.json')
};
<commit_msg>wrong function<commit_after>'use strict';

var Boom = require('boom');
var _ = require('lodash');
var pluginName = 'pluginJsonapi';
var utilities = require('./utilities');

// some paths sinply don't want to be jsonapi'd
var ignorePaths = [
  '/', // Lout documentation and AWS healthcheck
  '/css/{path*}' // Lout documentation
];

// certain status codes shouldn't be jsonapi'd
var ignoreStatusCodes = [
  201, // Created (used on POST)
  204 // No Content (used on DELETE)
];

var pluginJsonApi = module.exports = {};

pluginJsonApi.errorHandler = function errorHandler(request, reply, error) {
  request.log( ['error', __filename, pluginName], {
    error: error.toString(),
    data: request.data
  } );

  return reply(Boom.internal(error));
};

pluginJsonApi.alsoMakeItSo = function alsoMakeItSo(request, reply) { // eslint-disable-line consistent-return

  try {
    // If there was no error and it's not one of our ignoredPaths or ignored status codes, jsonapi it
    if (request.response.isBoom || _.includes(ignorePaths, request.route.path) || _.includes(ignoreStatusCodes, request.response.statusCode)) {
      // return early
      return reply.continue();
    }

    // Make the response a bit more accessible
    var result = _.get(request, 'response.source');
    // check a bind configuration is present
    if ( !_.get(request, 'route.settings.bind')) {
      throw new Error('configuration bind.resourceName not found on handler');
    }

    // Get the current resource from the result
    var resources = result[request.route.settings.bind.resourceName];
    if (!resources) {
      // no resources, return early
      return reply.continue();
    }

    var stateObject = {
      request: request,
      resources: resources
    };

    /*
     * Flow
     * collectIncludes() - store the includes for later
     * getSubResources() - get the sub resources which will be linked
     * getResources() - get the resources
     * resolveLinkedData() - resolve the sub resources which we have collected previously
     */
    utilities.collectIncludes(stateObject)
    .then(utilities.getSubResources)
    .then(utilities.getResources)
    .then(utilities.resolveLinkedData)
    .then(function() {
      // all done
      return reply.continue();
    })
    .fail(function(error) {
      return pluginJsonApi.errorHandler(request, reply, error);
    })
    .done();

  } catch ( error ) {
    return pluginJsonApi.errorHandler(request, reply, error);
  }
};

/**
* Registers the plugin when the hapi server bootstraps - follows the convention for Hapi.js plugins
* @param {object} server - the hapi plugin object
* @param {object} options - any initial options needed to set up the plugin
* @param {function} next - the next plugin to be set up
* @returns {undefined} Nothing - calls the next plugin
*/
pluginJsonApi.register = function(server, options, next) {

  function makeItSo(request, reply) {
    return pluginJsonApi.alsoMakeItSo(request, reply);
  }

  // Extend the onPreResponse for EVERY request through the api
  server.ext('onPreResponse', makeItSo);

  // In order to test this functionality it needs to be exposed on the server.
  if (process.env.NODE_ENV === 'test') {
    server.expose('makeItSo', makeItSo);
  }

  next();
};

pluginJsonApi.register.attributes = {
  pkg: require('../package.json')
};
<|endoftext|>


<commit_before>module.exports.name = 'cssnano/postcss-svgo';
module.exports.tests = [{
    message: 'should optimise inline svg',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="#ff0"/></svg>\')}',
}, {
    message: 'should optimise inline svg with standard charset definition',
    fixture: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="#ff0"/></svg>\')}',
}, {
    message: 'should optimise inline svg without charset definition',
    fixture: 'h1{background:url(\'data:image/svg+xml,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="#ff0"/></svg>\')}',
}, {
    message: 'should optimise uri-encoded inline svg',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2240%22%20fill%3D%22yellow%22%20%2F%3E%3C!--test%20comment--%3E%3C%2Fsvg%3E\')}',
    expected: 'h1{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http://www.w3.org/2000/svg\'%3E%3Ccircle cx=\'50\' cy=\'50\' r=\'40\' fill=\'%23ff0\'/%3E%3C/svg%3E")}',
}, {
    message: 'should allow users to customise the output',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="#ff0"/><!--test comment--></svg>\')}',
    options: {svgo: {plugins: [{removeComments: false}]}},
}];
<commit_msg>Update tests for postcss-svgo@2.1.6.<commit_after>module.exports.name = 'cssnano/postcss-svgo';
module.exports.tests = [{
    message: 'should optimise inline svg',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="%23ff0"/></svg>\')}',
}, {
    message: 'should optimise inline svg with standard charset definition',
    fixture: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="%23ff0"/></svg>\')}',
}, {
    message: 'should optimise inline svg without charset definition',
    fixture: 'h1{background:url(\'data:image/svg+xml,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="%23ff0"/></svg>\')}',
}, {
    message: 'should optimise uri-encoded inline svg',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%3C!DOCTYPE%20svg%20PUBLIC%20%22-%2F%2FW3C%2F%2FDTD%20SVG%201.1%2F%2FEN%22%20%22http%3A%2F%2Fwww.w3.org%2FGraphics%2FSVG%2F1.1%2FDTD%2Fsvg11.dtd%22%3E%3Csvg%20version%3D%221.1%22%20id%3D%22Layer_1%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20xml%3Aspace%3D%22preserve%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2240%22%20fill%3D%22yellow%22%20%2F%3E%3C!--test%20comment--%3E%3C%2Fsvg%3E\')}',
    expected: 'h1{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=\'http://www.w3.org/2000/svg\'%3E%3Ccircle cx=\'50\' cy=\'50\' r=\'40\' fill=\'%23ff0\'/%3E%3C/svg%3E")}',
}, {
    message: 'should allow users to customise the output',
    fixture: 'h1{background:url(\'data:image/svg+xml;utf-8,<?xml version="1.0" encoding="utf-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"><circle cx="50" cy="50" r="40" fill="yellow" /><!--test comment--></svg>\')}',
    expected: 'h1{background:url(\'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg"><circle cx="50" cy="50" r="40" fill="%23ff0"/><!--test comment--></svg>\')}',
    options: {svgo: {plugins: [{removeComments: false}]}},
}];
<|endoftext|>


<commit_before>var lastFocusedWindowID = 1;

function init() {
	console.log("Tiles background page started");

	chrome.windows.get(chrome.windows.WINDOW_ID_CURRENT, { populate: true }, function(window) {
		if (window.type == 'normal') {
			lastFocusedWindowID = chrome.windows.WINDOW_ID_CURRENT;
		}

		updateWindow(window);
	});

	migrateStorage();

	// Set the version if not done already
	storageVersionExists(function(exists) {
		if (!exists) {
			setStorageVersion(getExtensionVersion());
		}
	});

	writeUserStylesheet();
}

chrome.tabs.onActivated.addListener(function(info) {
	chrome.tabs.get(info.tabId, function(tab) {
		updateTab(tab);
	});
});

chrome.tabs.onUpdated.addListener(function(tabID, changeInfo, tab) {
	if (tab.active) {
		updateTab(tab);
	}
});

chrome.windows.onFocusChanged.addListener(function(windowID) {
	if (windowID == -1) {
		return;
	}

	chrome.windows.get(windowID, { populate: true }, function(window) {
		if (window.type == 'normal') {
			lastFocusedWindowID = windowID;
		}

		updateWindow(window);
	});
});

chrome.contextMenus.removeAll(function() {
	chrome.contextMenus.create({
	    "title": "Tiles Options",
	    "documentUrlPatterns": [chrome.extension.getURL("/") + "*"],
	    "contexts": ["page", "link"],
	    "onclick" : function() {
	    	goToOptionsPage(true)
	    }
	});
});

function goToOptionsPage(newTab) {
	var optionsURL = chrome.extension.getURL("/TILES_VERSION_ID_/options/options.html");

	if (newTab) {
		chrome.tabs.create({
			url: optionsURL
		});
	} else {
		chrome.tabs.getCurrent(function(tab) {
			chrome.tabs.update(tab.id, { url : optionsURL })
		});
	}
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	console.log('Message received: ' + request.message);

	if (request.message == "getUrl") {
		getFocusedTab(function(tab) {
			if (tab) {
				sendResponse({ url: tab.url });

				console.log('Sent URL - ' + tab.url);
			}
		});
	} else if (request.message == "getAbbreviation") {
		getFocusedTab(function(tab) {
			if (tab) {
				getSiteAbbreviationForURL(tab.url, function(abbreviation) {
					sendResponse({ abbreviation: abbreviation });

					console.log('Sent abbreviation - ' + abbreviation);
				});
			}
		});
	} else if (request.message == "setAbbreviation") {
		getFocusedTab(function(tab) {
			if (tab) {
				getIDForURL(tab.url, function(id) {
					updateSiteAbbreviation(id, request.abbreviation, function(response) {
						sendResponse({ message: "success" });

						console.log('Setting abbreviation of ' + tab.url + ' to ' + request.abbreviation);

						updateAllWindows();
					});
				});
			}
		});
	} else if (request.message == "delete") {
		console.log('Deleting...');

		getFocusedTab(function(tab) {
			if (!tab) {
				return;
			}

			function deleteSiteCallback() {
				if (!request.url) {
					setPopup(true, false, tab.id);
					changeIcon(false, null, tab.id);
				}

				sendResponse({ message: "deleted" });

				console.log('Sent deleted');

				updateAllWindows();
			}

			if (request.url == undefined) {
				console.log("Deleting site " + tab.url);
				getIDForURL(tab.url, function(id) {
					removeSites([id], deleteSiteCallback);
				});
			} else {
				console.log("Deleting site " + request.url);
				getIDForURL(request.url, function(id) {
					removeSites([id], deleteSiteCallback);
				});
			}
		});
	} else if (request.message == "save") {
		console.log('Saving...');

		getFocusedTab(function(tab) {
			createSite(tab.url, request.abbreviation, null, function(site) {
				addSites([site], function() {
					updateAllWindows();

					sendResponse({ message: "saved" });

					console.log('Sent saved');
				});
			});
		});
	} else if (request.message == "openTab") {
		chrome.tabs.create({
			url: request.url
		});

		sendResponse({ message: "opened" });
	} else if (request.message == SITES_ADDED_MESSAGE
		|| request.message == SITES_REMOVED_MESSAGE
		|| request.message == SITE_UPDATED_MESSAGE
		|| request.message == BACKGROUND_COLOR_UPDATED_MESSAGE) {
		writeUserStylesheet();
	}

	return true;
});

function getFocusedTab(callback) {
	chrome.windows.get(lastFocusedWindowID, { populate: true }, function(window) {
		if (window && window.type != 'normal') {
			return callback(null);
		}

		var tabs = window.tabs;

		for (var j = 0; j < tabs.length; j++) {
			if (tabs[j].active) {
				return callback(tabs[j]);
			}
		}
	});
}

function setPopup(save, error, tabID) {
	var details = {};

	if (error) {
		details.popup = '/TILES_VERSION_ID_/browser_action/error.html';
	} else {
		if (save) {
			details.popup = '/TILES_VERSION_ID_/browser_action/save.html';
		} else {
			details.popup = '/TILES_VERSION_ID_/browser_action/delete.html';
		}
	}

	details.tabId = tabID;

	chrome.browserAction.setPopup(details);
}

/**
 * Updates all of the windows.
 */
function updateAllWindows() {
	sendMessageToExtensionTabs("refresh");

	chrome.windows.getAll({ populate: true }, function(windows) {
		console.log('Updating all windows...');

		for (var i = 0; i < windows.length; i++) {
			updateWindow(windows[i]);
		}
	});
}

/**
 * Updates all of the tabs in a window.
 * @param  {Window} window The window to update all of its tabs.
 */
function updateWindow(window) {
	if (window && window.type == 'normal') {
		var tabs = window.tabs;

		for (var i = 0; i < tabs.length; i++) {
			if (tabs[i].active) {
				updateTab(tabs[i]);

				break;
			}
		}
	}
}

/**
 * Sets the appropriate popup and icon for the tab.
 * @param  {Tab} tab The tab to update its popup and icon.
 */
function updateTab(tab) {
	if (isChromeURL(tab.url)) {
		setPopup(false, true, tab.id);

		changeIcon(false, null, tab.id);
	} else {
		siteExistsWithURL(tab.url, function(exists) {
			setPopup(!exists, false, tab.id);

			changeIcon(exists, null, tab.id);
		});
	}
}

/**
 * Sets the icon for the browser action in the chrome toolbar.
 * @param {boolean} color If {true}, icon will be set to color
 *     version, else icon will be set to grayscale version.
 * @param callback The callback to call after the icon has
 *     been set.
 * @param tabID The related tab ID.
 */
function changeIcon(color, callback, tabID) {
	var details = {};

	if (color) {
		details.path = '/TILES_VERSION_ID_/icons/icon-bitty.png';
	} else {
		details.path = '/TILES_VERSION_ID_/icons/icon-bitty-gray.png';
	}

	details.tabId = tabID;

	chrome.browserAction.setIcon(details, callback);
}

function writeUserStylesheet() {
	getFileSystem(function(fs) {
		getSitesCount(function(sitesCount) {
			if (sitesCount > 0) {
				getBackgroundColor(function(color) {
					if (!color) {
						writeToFile(fs, "user.css", "body { background: rgb(0, 0, 0) !important; }");
					} else {
						writeToFile(fs, "user.css", "body { background: rgb(" + color['red'] + ", " + color['green'] + ", " + color['blue'] + ") !important; }");
					}
				});
			} else {
				writeToFile(fs, "user.css", "body { background: rgb(0, 0, 0) !important; }");
			}
		});
	});
}

init();<commit_msg>Use getLastFocused to get the last focused window.<commit_after>function init() {
	console.log("Tiles background page started");

	chrome.windows.getLastFocused({ populate: true }, function(window) {
		updateWindow(window);
	});

	migrateStorage();

	// Set the version if not done already
	storageVersionExists(function(exists) {
		if (!exists) {
			setStorageVersion(getExtensionVersion());
		}
	});

	writeUserStylesheet();
}

chrome.tabs.onActivated.addListener(function(info) {
	chrome.tabs.get(info.tabId, function(tab) {
		updateTab(tab);
	});
});

chrome.tabs.onUpdated.addListener(function(tabID, changeInfo, tab) {
	if (tab.active) {
		updateTab(tab);
	}
});

chrome.windows.onFocusChanged.addListener(function(windowID) {
	if (windowID == -1) {
		return;
	}

	chrome.windows.get(windowID, { populate: true }, function(window) {
		updateWindow(window);
	});
});

chrome.contextMenus.removeAll(function() {
	chrome.contextMenus.create({
	    "title": "Tiles Options",
	    "documentUrlPatterns": [chrome.extension.getURL("/") + "*"],
	    "contexts": ["page", "link"],
	    "onclick" : function() {
	    	goToOptionsPage(true)
	    }
	});
});

function goToOptionsPage(newTab) {
	var optionsURL = chrome.extension.getURL("/TILES_VERSION_ID_/options/options.html");

	if (newTab) {
		chrome.tabs.create({
			url: optionsURL
		});
	} else {
		chrome.tabs.getCurrent(function(tab) {
			chrome.tabs.update(tab.id, { url : optionsURL })
		});
	}
}

chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
	console.log('Message received: ' + request.message);

	if (request.message == "getUrl") {
		getFocusedTab(function(tab) {
			if (tab) {
				sendResponse({ url: tab.url });

				console.log('Sent URL - ' + tab.url);
			}
		});
	} else if (request.message == "getAbbreviation") {
		getFocusedTab(function(tab) {
			if (tab) {
				getSiteAbbreviationForURL(tab.url, function(abbreviation) {
					sendResponse({ abbreviation: abbreviation });

					console.log('Sent abbreviation - ' + abbreviation);
				});
			}
		});
	} else if (request.message == "setAbbreviation") {
		getFocusedTab(function(tab) {
			if (tab) {
				getIDForURL(tab.url, function(id) {
					updateSiteAbbreviation(id, request.abbreviation, function(response) {
						sendResponse({ message: "success" });

						console.log('Setting abbreviation of ' + tab.url + ' to ' + request.abbreviation);

						updateAllWindows();
					});
				});
			}
		});
	} else if (request.message == "delete") {
		console.log('Deleting...');

		getFocusedTab(function(tab) {
			if (!tab) {
				return;
			}

			function deleteSiteCallback() {
				if (!request.url) {
					setPopup(true, false, tab.id);
					changeIcon(false, null, tab.id);
				}

				sendResponse({ message: "deleted" });

				console.log('Sent deleted');

				updateAllWindows();
			}

			if (request.url == undefined) {
				console.log("Deleting site " + tab.url);
				getIDForURL(tab.url, function(id) {
					removeSites([id], deleteSiteCallback);
				});
			} else {
				console.log("Deleting site " + request.url);
				getIDForURL(request.url, function(id) {
					removeSites([id], deleteSiteCallback);
				});
			}
		});
	} else if (request.message == "save") {
		console.log('Saving...');

		getFocusedTab(function(tab) {
			createSite(tab.url, request.abbreviation, null, function(site) {
				addSites([site], function() {
					updateAllWindows();

					sendResponse({ message: "saved" });

					console.log('Sent saved');
				});
			});
		});
	} else if (request.message == "openTab") {
		chrome.tabs.create({
			url: request.url
		});

		sendResponse({ message: "opened" });
	} else if (request.message == SITES_ADDED_MESSAGE
		|| request.message == SITES_REMOVED_MESSAGE
		|| request.message == SITE_UPDATED_MESSAGE
		|| request.message == BACKGROUND_COLOR_UPDATED_MESSAGE) {
		writeUserStylesheet();
	}

	return true;
});

function getFocusedTab(callback) {
	chrome.windows.getLastFocused({ populate: true }, function(window) {
		if (window && window.type != 'normal') {
			return callback(null);
		}

		var tabs = window.tabs;

		for (var j = 0; j < tabs.length; j++) {
			if (tabs[j].active) {
				return callback(tabs[j]);
			}
		}
	});
}

function setPopup(save, error, tabID) {
	var details = {};

	if (error) {
		details.popup = '/TILES_VERSION_ID_/browser_action/error.html';
	} else {
		if (save) {
			details.popup = '/TILES_VERSION_ID_/browser_action/save.html';
		} else {
			details.popup = '/TILES_VERSION_ID_/browser_action/delete.html';
		}
	}

	details.tabId = tabID;

	chrome.browserAction.setPopup(details);
}

/**
 * Updates all of the windows.
 */
function updateAllWindows() {
	sendMessageToExtensionTabs("refresh");

	chrome.windows.getAll({ populate: true }, function(windows) {
		console.log('Updating all windows...');

		for (var i = 0; i < windows.length; i++) {
			updateWindow(windows[i]);
		}
	});
}

/**
 * Updates all of the tabs in a window.
 * @param  {Window} window The window to update all of its tabs.
 */
function updateWindow(window) {
	if (window && window.type == 'normal') {
		var tabs = window.tabs;

		for (var i = 0; i < tabs.length; i++) {
			if (tabs[i].active) {
				updateTab(tabs[i]);

				break;
			}
		}
	}
}

/**
 * Sets the appropriate popup and icon for the tab.
 * @param  {Tab} tab The tab to update its popup and icon.
 */
function updateTab(tab) {
	if (isChromeURL(tab.url)) {
		setPopup(false, true, tab.id);

		changeIcon(false, null, tab.id);
	} else {
		siteExistsWithURL(tab.url, function(exists) {
			setPopup(!exists, false, tab.id);

			changeIcon(exists, null, tab.id);
		});
	}
}

/**
 * Sets the icon for the browser action in the chrome toolbar.
 * @param {boolean} color If {true}, icon will be set to color
 *     version, else icon will be set to grayscale version.
 * @param callback The callback to call after the icon has
 *     been set.
 * @param tabID The related tab ID.
 */
function changeIcon(color, callback, tabID) {
	var details = {};

	if (color) {
		details.path = '/TILES_VERSION_ID_/icons/icon-bitty.png';
	} else {
		details.path = '/TILES_VERSION_ID_/icons/icon-bitty-gray.png';
	}

	details.tabId = tabID;

	chrome.browserAction.setIcon(details, callback);
}

function writeUserStylesheet() {
	getFileSystem(function(fs) {
		getSitesCount(function(sitesCount) {
			if (sitesCount > 0) {
				getBackgroundColor(function(color) {
					if (!color) {
						writeToFile(fs, "user.css", "body { background: rgb(0, 0, 0) !important; }");
					} else {
						writeToFile(fs, "user.css", "body { background: rgb(" + color['red'] + ", " + color['green'] + ", " + color['blue'] + ") !important; }");
					}
				});
			} else {
				writeToFile(fs, "user.css", "body { background: rgb(0, 0, 0) !important; }");
			}
		});
	});
}

init();<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var hasClassSupport = require( '@stdlib/utils/detect-class-support' );
var isPlainObject = require( '@stdlib/utils/is-plain-object' );
var err2json = require( './../lib' );

// FIXTURES //

var createClass1 = require( './fixtures/customerror.proto.js' );
var createClass2 = require( './fixtures/customerror.subclass.js' );

// VARIABLES //

var opts = {
	'skip': !hasClassSupport
};

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof err2json, 'function', 'main export is a function' );
	t.end();
});

tape( 'if provided anything other than an error instance, the function will throw an error', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true,
		[],
		{},
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), Error, 'throws when provided a ' + (typeof values[i]) );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			err2json( value );
		};
	}
});

tape( 'the function returns a JSON object', function test( t ) {
	var err = new Error( 'beep' );
	var json = err2json( err );
	t.equal( isPlainObject( json ), true, 'returns an object' );
	t.end();
});

tape( 'the JSON object includes an error type', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'Error',
		'EvalError',
		'TypeError',
		'ReferenceError',
		'SyntaxError',
		'URIError',
		'RangeError'
	];

	for ( i = 0; i < values.length; i++ ) {
		json = err2json( values[ i ] );
		t.equal( json.type, expected[ i ], 'type equal to ' + expected[ i ] );
	}
	t.end();
});

tape( 'the JSON object includes an error message', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error( 'a' ),
		new EvalError( 'b' ),
		new TypeError( 'c' ),
		new ReferenceError( 'd' ),
		new SyntaxError( 'e' ),
		new URIError( 'f' ),
		new RangeError( 'g' )
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		json = err2json( values[ i ] );
		t.equal( json.message, expected[ i ], 'message equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `stack` property is present, the JSON object includes a stack trace', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].stack = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.stack, expected[ i ], 'stack equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `stack` property is not present, the JSON object will not include a `stack` property', function test( t ) {
	var json;
	var err;

	err = new Error();

	// Fake not having a `stack` by intercepting access and returning `undefined`, similar to non-existent property behavior...
	Object.defineProperty( err, 'stack', {
		'value': void 0,
		'enumerable': false,
		'configuable': true,
		'writable': true
	});

	json = err2json( err );
	t.equal( json.stack, void 0, 'no stack property' );
	t.end();
});

tape( 'if a `name` property is present, the JSON object includes an error name', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].name = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.name, expected[ i ], 'name equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `name` property is not present, the JSON object will not include a `name` property', function test(t ) {
	var json;
	var err;

	err = new Error();

	// Fake not having a `name` by intercepting access and returning `void 0`, similar to non-existent property behavior...
	Object.defineProperty( err, 'name', {
		'value': void 0,
		'enumerable': false,
		'configuable': true,
		'writable': true
	});

	json = err2json( err );
	t.equal( json.name, void 0, 'no name property' );

	t.end();
});

tape( 'if a `code` property is present, the JSON object includes an error code', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		1,
		2,
		3,
		4,
		5,
		6,
		7
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].code = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.code, expected[ i ], 'code equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if an `errno` property is present, the JSON object includes an error code string', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].errno = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.errno, expected[ i ], 'errno equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `syscall` property is present, the JSON object includes a failed system call string', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].syscall = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.syscall, expected[ i ], 'syscall equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a provided error has additional enumerable properties, the function will include these properties and their values in the output JSON', function test( t ) {
	var json;
	var err;

	// Data descriptor...
	err = new Error( 'errrr' );
	err.beep = 'boop';
	err.boop = 'beep';

	json = err2json( err );
	t.equal( json.beep, err.beep, 'data descriptor' );
	t.equal( json.boop, err.boop, 'data descriptor' );

	// Accessor descriptor...
	err = new Error( 'errrr' );
	Object.defineProperty( err, 'beep', {
		'enumerable': true,
		'configurable': true,
		'get': function get() {
			return 'boop';
		}
	});
	Object.defineProperty( err, 'boop', {
		'enumerable': true,
		'configurable': false,
		'get': function get() {
			return 'beep';
		}
	});

	json = err2json( err );
	t.equal( json.beep, err.beep, 'accessor descriptor' );
	t.equal( json.boop, err.boop, 'accessor descriptor' );

	t.end();
});

tape( 'the function deep copies enumerable properties', function test( t ) {
	var json;
	var err;

	// Deep equal...
	err = new Error( 'errrr' );
	err.arr = [ 1, 2, [ 3, 4, 5 ] ];

	json = err2json( err );
	t.notEqual( json.arr, err.arr, 'new instances' );
	t.deepEqual( json.arr, err.arr, 'deep equal' );

	t.end();
});

tape( 'custom errors (proto)', function test( t ) {
	var CustomError;
	var types;
	var ctors;
	var json;
	var err;
	var i;

	ctors = [
		Error,
		TypeError,
		SyntaxError,
		ReferenceError,
		URIError,
		EvalError,
		RangeError
	];

	types = [
		'Error',
		'TypeError',
		'SyntaxError',
		'ReferenceError',
		'URIError',
		'EvalError',
		'RangeError'
	];

	for ( i = 0; i < ctors.length; i++ ) {
		CustomError = createClass1( ctors[ i ] );
		err = new CustomError( 'custom error' );
		json = err2json( err );

		t.equal( json.type, types[ i ], 'type equal to ' + types[ i ] );
		t.equal( json.message, err.message, 'equal messages' );
		t.equal( json.name, err.name, 'equal names' );
		t.equal( json.stack, err.stack, 'equal stack trace' );
	}
	t.end();
});

tape( 'custom errors (subclass; ES2015)', opts, function test( t ) {
	var CustomError;
	var ctors;
	var json;
	var err;
	var i;

	ctors = [
		'Error',
		'TypeError',
		'SyntaxError',
		'ReferenceError',
		'URIError',
		'EvalError',
		'RangeError'
	];

	for ( i = 0; i < ctors.length; i++ ) {
		CustomError = createClass2( ctors[ i ] );
		err = new CustomError( 'custom error' );
		json = err2json( err );

		t.equal( json.type, ctors[ i ], 'type equal to ' + ctors[ i ] );
		t.equal( json.message, err.message, 'equal messages' );
		t.equal( json.name, err.name, 'equal names' );
		t.equal( json.stack, err.stack, 'equal stack trace' );
	}
	t.end();
});
<commit_msg>Fix test bug<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var hasClassSupport = require( '@stdlib/utils/detect-class-support' );
var isPlainObject = require( '@stdlib/utils/is-plain-object' );
var err2json = require( './../lib' );

// FIXTURES //

var createClass1 = require( './fixtures/customerror.proto.js' );
var createClass2 = require( './fixtures/customerror.subclass.js' );

// VARIABLES //

var opts = {
	'skip': !hasClassSupport()
};

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.equal( typeof err2json, 'function', 'main export is a function' );
	t.end();
});

tape( 'if provided anything other than an error instance, the function will throw an error', function test( t ) {
	var values;
	var i;

	values = [
		'5',
		5,
		NaN,
		null,
		undefined,
		true,
		[],
		{},
		function(){}
	];

	for ( i = 0; i < values.length; i++ ) {
		t.throws( badValue( values[i] ), Error, 'throws when provided a ' + (typeof values[i]) );
	}
	t.end();

	function badValue( value ) {
		return function badValue() {
			err2json( value );
		};
	}
});

tape( 'the function returns a JSON object', function test( t ) {
	var err = new Error( 'beep' );
	var json = err2json( err );
	t.equal( isPlainObject( json ), true, 'returns an object' );
	t.end();
});

tape( 'the JSON object includes an error type', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'Error',
		'EvalError',
		'TypeError',
		'ReferenceError',
		'SyntaxError',
		'URIError',
		'RangeError'
	];

	for ( i = 0; i < values.length; i++ ) {
		json = err2json( values[ i ] );
		t.equal( json.type, expected[ i ], 'type equal to ' + expected[ i ] );
	}
	t.end();
});

tape( 'the JSON object includes an error message', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error( 'a' ),
		new EvalError( 'b' ),
		new TypeError( 'c' ),
		new ReferenceError( 'd' ),
		new SyntaxError( 'e' ),
		new URIError( 'f' ),
		new RangeError( 'g' )
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		json = err2json( values[ i ] );
		t.equal( json.message, expected[ i ], 'message equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `stack` property is present, the JSON object includes a stack trace', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].stack = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.stack, expected[ i ], 'stack equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `stack` property is not present, the JSON object will not include a `stack` property', function test( t ) {
	var json;
	var err;

	err = new Error();

	// Fake not having a `stack` by intercepting access and returning `undefined`, similar to non-existent property behavior...
	Object.defineProperty( err, 'stack', {
		'value': void 0,
		'enumerable': false,
		'configuable': true,
		'writable': true
	});

	json = err2json( err );
	t.equal( json.stack, void 0, 'no stack property' );
	t.end();
});

tape( 'if a `name` property is present, the JSON object includes an error name', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].name = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.name, expected[ i ], 'name equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `name` property is not present, the JSON object will not include a `name` property', function test(t ) {
	var json;
	var err;

	err = new Error();

	// Fake not having a `name` by intercepting access and returning `void 0`, similar to non-existent property behavior...
	Object.defineProperty( err, 'name', {
		'value': void 0,
		'enumerable': false,
		'configuable': true,
		'writable': true
	});

	json = err2json( err );
	t.equal( json.name, void 0, 'no name property' );

	t.end();
});

tape( 'if a `code` property is present, the JSON object includes an error code', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		1,
		2,
		3,
		4,
		5,
		6,
		7
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].code = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.code, expected[ i ], 'code equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if an `errno` property is present, the JSON object includes an error code string', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].errno = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.errno, expected[ i ], 'errno equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a `syscall` property is present, the JSON object includes a failed system call string', function test( t ) {
	var expected;
	var values;
	var json;
	var i;

	values = [
		new Error(),
		new EvalError(),
		new TypeError(),
		new ReferenceError(),
		new SyntaxError(),
		new URIError(),
		new RangeError()
	];

	expected = [
		'a',
		'b',
		'c',
		'd',
		'e',
		'f',
		'g'
	];

	for ( i = 0; i < values.length; i++ ) {
		values[ i ].syscall = expected[ i ];
		json = err2json( values[ i ] );
		t.equal( json.syscall, expected[ i ], 'syscall equal to \'' + expected[ i ] + '\'' );
	}
	t.end();
});

tape( 'if a provided error has additional enumerable properties, the function will include these properties and their values in the output JSON', function test( t ) {
	var json;
	var err;

	// Data descriptor...
	err = new Error( 'errrr' );
	err.beep = 'boop';
	err.boop = 'beep';

	json = err2json( err );
	t.equal( json.beep, err.beep, 'data descriptor' );
	t.equal( json.boop, err.boop, 'data descriptor' );

	// Accessor descriptor...
	err = new Error( 'errrr' );
	Object.defineProperty( err, 'beep', {
		'enumerable': true,
		'configurable': true,
		'get': function get() {
			return 'boop';
		}
	});
	Object.defineProperty( err, 'boop', {
		'enumerable': true,
		'configurable': false,
		'get': function get() {
			return 'beep';
		}
	});

	json = err2json( err );
	t.equal( json.beep, err.beep, 'accessor descriptor' );
	t.equal( json.boop, err.boop, 'accessor descriptor' );

	t.end();
});

tape( 'the function deep copies enumerable properties', function test( t ) {
	var json;
	var err;

	// Deep equal...
	err = new Error( 'errrr' );
	err.arr = [ 1, 2, [ 3, 4, 5 ] ];

	json = err2json( err );
	t.notEqual( json.arr, err.arr, 'new instances' );
	t.deepEqual( json.arr, err.arr, 'deep equal' );

	t.end();
});

tape( 'custom errors (proto)', function test( t ) {
	var CustomError;
	var types;
	var ctors;
	var json;
	var err;
	var i;

	ctors = [
		Error,
		TypeError,
		SyntaxError,
		ReferenceError,
		URIError,
		EvalError,
		RangeError
	];

	types = [
		'Error',
		'TypeError',
		'SyntaxError',
		'ReferenceError',
		'URIError',
		'EvalError',
		'RangeError'
	];

	for ( i = 0; i < ctors.length; i++ ) {
		CustomError = createClass1( ctors[ i ] );
		err = new CustomError( 'custom error' );
		json = err2json( err );

		t.equal( json.type, types[ i ], 'type equal to ' + types[ i ] );
		t.equal( json.message, err.message, 'equal messages' );
		t.equal( json.name, err.name, 'equal names' );
		t.equal( json.stack, err.stack, 'equal stack trace' );
	}
	t.end();
});

tape( 'custom errors (subclass; ES2015)', opts, function test( t ) {
	var CustomError;
	var ctors;
	var json;
	var err;
	var i;

	ctors = [
		'Error',
		'TypeError',
		'SyntaxError',
		'ReferenceError',
		'URIError',
		'EvalError',
		'RangeError'
	];

	for ( i = 0; i < ctors.length; i++ ) {
		CustomError = createClass2( ctors[ i ] );
		err = new CustomError( 'custom error' );
		json = err2json( err );

		t.equal( json.type, ctors[ i ], 'type equal to ' + ctors[ i ] );
		t.equal( json.message, err.message, 'equal messages' );
		t.equal( json.name, err.name, 'equal names' );
		t.equal( json.stack, err.stack, 'equal stack trace' );
	}
	t.end();
});
<|endoftext|>


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

(function() {
    'use strict';

    var argv        = process.argv,
        Util        = require('util-io'),
        vm          = require('vm'),

        Clients     = [],
        Num         = 0,

        argvLast    = argv.slice().pop();

    switch (argvLast) {
    case '-v':
        version();
        break;

    case '--v':
        version();
        break;

    default:
        start();
    }

    function start() {
        var DIR         = __dirname + '/../',

        webconsole  = require('../'),
        http        = require('http'),

        express     = require('express'),
        minify      = require('minify'),

        app         = express(),
        server      = http.createServer(app),

        port        =   process.env.PORT            ||  /* c9           */
                        process.env.app_port        ||  /* nodester     */
                        process.env.VCAP_APP_PORT   ||  /* cloudfoundry */
                        1337,

        ip          =   process.env.IP              ||  /* c9           */
                        '0.0.0.0';

        app .use(webconsole({
                server: server,
                online: false
            }))
            .use(minify({
                dir: DIR
            }))
            .use(express.static(DIR));

        server.listen(port, ip);

        console.log('url: http://' + ip + ':' + port);
    }

    function version() {
        var pack = require('../package.json');

        console.log('v' + pack.version);
    }
})();
<commit_msg>feature(console) rm vm, Clients, Num<commit_after>#!/usr/bin/env node

(function() {
    'use strict';

    var argv        = process.argv,
        Util        = require('util-io'),
        argvLast    = argv.slice().pop();

    switch (argvLast) {
    case '-v':
        version();
        break;

    case '--v':
        version();
        break;

    default:
        start();
    }

    function start() {
        var DIR         = __dirname + '/../',

        webconsole  = require('../'),
        http        = require('http'),

        express     = require('express'),
        minify      = require('minify'),

        app         = express(),
        server      = http.createServer(app),

        port        =   process.env.PORT            ||  /* c9           */
                        process.env.app_port        ||  /* nodester     */
                        process.env.VCAP_APP_PORT   ||  /* cloudfoundry */
                        1337,

        ip          =   process.env.IP              ||  /* c9           */
                        '0.0.0.0';

        app .use(webconsole({
                server: server,
                online: false
            }))
            .use(minify({
                dir: DIR
            }))
            .use(express.static(DIR));

        server.listen(port, ip);

        console.log('url: http://' + ip + ':' + port);
    }

    function version() {
        var pack = require('../package.json');

        console.log('v' + pack.version);
    }
})();
<|endoftext|>


<commit_before>import Em from 'ember';
import missingPlugin from '../utils/missing-plugin';
/* global NetworkActivity */

/**
  Mixin for your ember-data adapter that toggles the NetworkActivity indicator.

  Use by importing and applying the mixin to your adapter

  ```javascript
  // app/adapters/application.js
  import DS from 'ember-data';
  import NetworkActivityAdapterMixin from 'ember-cli-cordova-shims/mixins/network-activity-adapter';

  export default DS.RESTAdapter.extend(NetworkActivityAdapterMixin, {
    ...
  });
  ```

  @class NetworkActivityAdapterMixin
  @namespace CordovaShims.Mixins
  @module ember-cli-cordova-shims/mixins/network-activity-adapter
  @extends Ember.Mixin
  @since {wip}
 */
export default Em.Mixin.create({
  _pendingAjaxCalls: 0,

  ajax: function(){
    this.incrementProperty('_pendingAjaxCalls');

    return new Em.RSVP.Promise((resolve, reject) => {
      this._super.apply(this, arguments)
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.decrementProperty('_pendingAjaxCalls');
        });
    });
  },

  /**
    @method _toggleNetworkActivity
    @private
  */
  _toggleNetworkActivity: Em.observer('_pendingAjaxCalls', function(){
    if (!window.NetworkActivity) {
      Em.run.scheduleOnce('afterRender', this, this._missingPlugin);
      return;
    }

    if (this.get('_pendingAjaxCalls') > 0) {
      NetworkActivity.activityStart();
    } else {
      NetworkActivity.activityStop();
    }
  }),

  /**
    @method _missingPlugin
    @private
  */
  _missingPlugin: function(){
    missingPlugin('NetworkActivity', 'com.wearecocoon.cordova.plugin.networkactivity');
  }
});
<commit_msg>Mark NetworkActivityAdapterMixin since 0.3.0<commit_after>import Em from 'ember';
import missingPlugin from '../utils/missing-plugin';
/* global NetworkActivity */

/**
  Mixin for your ember-data adapter that toggles the NetworkActivity indicator.

  Use by importing and applying the mixin to your adapter

  ```javascript
  // app/adapters/application.js
  import DS from 'ember-data';
  import NetworkActivityAdapterMixin from 'ember-cli-cordova-shims/mixins/network-activity-adapter';

  export default DS.RESTAdapter.extend(NetworkActivityAdapterMixin, {
    ...
  });
  ```

  @class NetworkActivityAdapterMixin
  @namespace CordovaShims.Mixins
  @module ember-cli-cordova-shims/mixins/network-activity-adapter
  @extends Ember.Mixin
  @since 0.3.0
 */
export default Em.Mixin.create({
  _pendingAjaxCalls: 0,

  ajax: function(){
    this.incrementProperty('_pendingAjaxCalls');

    return new Em.RSVP.Promise((resolve, reject) => {
      this._super.apply(this, arguments)
        .then(resolve)
        .catch(reject)
        .finally(() => {
          this.decrementProperty('_pendingAjaxCalls');
        });
    });
  },

  /**
    @method _toggleNetworkActivity
    @private
  */
  _toggleNetworkActivity: Em.observer('_pendingAjaxCalls', function(){
    if (!window.NetworkActivity) {
      Em.run.scheduleOnce('afterRender', this, this._missingPlugin);
      return;
    }

    if (this.get('_pendingAjaxCalls') > 0) {
      NetworkActivity.activityStart();
    } else {
      NetworkActivity.activityStop();
    }
  }),

  /**
    @method _missingPlugin
    @private
  */
  _missingPlugin: function(){
    missingPlugin('NetworkActivity', 'com.wearecocoon.cordova.plugin.networkactivity');
  }
});
<|endoftext|>


<commit_before>var tileRadius = 20;
var boardSize = 10;

var tileData = [
  ['A', 0, 7],
  ['B', 2, 3],
  ['C', 2, 3],
  ['D', 1, 3],
  ['E', 0, 10],
  ['F', 2, 3],
  ['G', 2, 4],
  ['H', 3, 2],
  ['I', 0, 7],
  ['J', 4, 1],
  ['K', 3, 2],
  ['L', 0, 4],
  ['M', 2, 3],
  ['N', 1, 4],
  ['O', 0, 7],
  ['P', 2, 3],
  ['Q', 4, 1],
  ['R', 1, 5],
  ['S', 1, 5],
  ['T', 1, 5],
  ['U', 1, 4],
  ['V', 4, 1],
  ['W', 3, 3],
  ['X', 4, 1],
  ['Y', 3, 2],
  ['Z', 4, 1],
  [' ', 0, 2]
];

function TileSpec(letter, value, freq) {
  this.letter = letter;
  this.value = value;
  this.freq = freq;
}

function makeTileSpecs(tileData) {
  return $.map(tileData, function (args) {
    var spec = new TileSpec();
    TileSpec.apply(spec, args);
    return spec;
  });
}

TileSpec.prototype.makeTile = function (parent) {
  var tile = $('
').appendTo(parent);

  tile.spec = this;

  var canvas = $('<canvas />').appendTo(tile);
  canvas.attr('width', tileRadius*3);
  canvas.attr('height', tileRadius*3);
  drawCircle(canvas, tileRadius*1.5, tileRadius*1.5, tileRadius);

  var text = $('
' + this.letter + '
').appendTo(tile);
  if (this.value) {
    text.append($('' + this.value + ''));
  }
  text.position({ my: 'center', at: 'center', of: canvas });

  tile.draggable();
  return tile;
}

TileSpec.prototype.makeTiles = function (parent) {
  var tiles = [];
  for (var i = 0; i < this.freq; i++) {
    tiles.push(this.makeTile(parent));
  }
  return tiles;
}

function drawCircle(element, x, y, r) {
  element.drawEllipse({
    strokeStyle: 'black', x: x, y: y, width: r*2, height: r*2
  });
}

function drawSpace(board, r, c) {
  drawCircle(board, tileRadius*(c*3+1.5), tileRadius*(r*3+1.5), tileRadius);
}

function makeBoard(parent) {
  var board = $('<canvas />').appendTo(parent);
  board.attr('width', tileRadius*boardSize*3);
  board.attr('height', tileRadius*boardSize*3);
  for (var r = 0; r < boardSize; r++) {
    for (var c = 0; c < boardSize; c++) {
      drawSpace(board, r, c);
    }
  }
  return board;
}

function placeTile(board, tile, r, c) {
  tile.position({ my: 'left top', at: 'left top', of: board,
                  collision: 'none',
                  offset: c*tileRadius*3 + ' ' + r*tileRadius*3 });
}

function main() {
  var root = $('#wordsearch');
  var board = makeBoard(root);
  var tiles = [];
  $.each(makeTileSpecs(tileData), function (i, spec) {
    tiles.push.apply(tiles, spec.makeTiles(root));
  });
  $.shuffle(tiles);
  for (var r = 0; r < boardSize; r++) {
    for (var c = 0; c < boardSize; c++) {
      if (r < boardSize/2 - 1 || r > boardSize/2 ||
          c < boardSize/2 - 1 || c > boardSize/2) {
        placeTile(board, tiles.pop(), r, c);
      }
    }
  }
}

$(main);
<commit_msg>Make tiles tan, and revert if not dropped on a droppable.<commit_after>var tileRadius = 20;
var boardSize = 10;

var tileData = [
  ['A', 0, 7],
  ['B', 2, 3],
  ['C', 2, 3],
  ['D', 1, 3],
  ['E', 0, 10],
  ['F', 2, 3],
  ['G', 2, 4],
  ['H', 3, 2],
  ['I', 0, 7],
  ['J', 4, 1],
  ['K', 3, 2],
  ['L', 0, 4],
  ['M', 2, 3],
  ['N', 1, 4],
  ['O', 0, 7],
  ['P', 2, 3],
  ['Q', 4, 1],
  ['R', 1, 5],
  ['S', 1, 5],
  ['T', 1, 5],
  ['U', 1, 4],
  ['V', 4, 1],
  ['W', 3, 3],
  ['X', 4, 1],
  ['Y', 3, 2],
  ['Z', 4, 1],
  [' ', 0, 2]
];

function TileSpec(letter, value, freq) {
  this.letter = letter;
  this.value = value;
  this.freq = freq;
}

function makeTileSpecs(tileData) {
  return $.map(tileData, function (args) {
    var spec = new TileSpec();
    TileSpec.apply(spec, args);
    return spec;
  });
}

TileSpec.prototype.makeTile = function (parent) {
  var tile = $('
').appendTo(parent);

  tile.spec = this;

  var canvas = $('<canvas />').appendTo(tile);
  canvas.attr('width', tileRadius*3);
  canvas.attr('height', tileRadius*3);
  drawCircle(canvas, tileRadius*1.5, tileRadius*1.5, tileRadius, 'tan');

  var text = $('
' + this.letter + '
').appendTo(tile);
  if (this.value) {
    text.append($('' + this.value + ''));
  }
  text.position({ my: 'center', at: 'center', of: canvas });

  tile.draggable({ stack: '.tile', revert: 'invalid', revertDuration: 200 });
  return tile;
}

TileSpec.prototype.makeTiles = function (parent) {
  var tiles = [];
  for (var i = 0; i < this.freq; i++) {
    tiles.push(this.makeTile(parent));
  }
  return tiles;
}

function drawCircle(element, x, y, r, fillStyle) {
  element.drawEllipse({
    fillStyle: fillStyle || 'transparent',
    strokeStyle: 'black', x: x, y: y, width: r*2, height: r*2
  });
}

function drawSpace(board, r, c) {
  drawCircle(board, tileRadius*(c*3+1.5), tileRadius*(r*3+1.5), tileRadius);
}

function makeBoard(parent) {
  var board = $('<canvas />').appendTo(parent);
  board.attr('width', tileRadius*boardSize*3);
  board.attr('height', tileRadius*boardSize*3);
  for (var r = 0; r < boardSize; r++) {
    for (var c = 0; c < boardSize; c++) {
      drawSpace(board, r, c);
    }
  }
  return board;
}

function placeTile(board, tile, r, c) {
  tile.position({ my: 'left top', at: 'left top', of: board,
                  collision: 'none',
                  offset: c*tileRadius*3 + ' ' + r*tileRadius*3 });
}

function main() {
  var root = $('#wordsearch');
  var board = makeBoard(root);
  var tiles = [];
  $.each(makeTileSpecs(tileData), function (i, spec) {
    tiles.push.apply(tiles, spec.makeTiles(root));
  });
  $.shuffle(tiles);
  for (var r = 0; r < boardSize; r++) {
    for (var c = 0; c < boardSize; c++) {
      if (r < boardSize/2 - 1 || r > boardSize/2 ||
          c < boardSize/2 - 1 || c > boardSize/2) {
        placeTile(board, tiles.pop(), r, c);
      }
    }
  }
}

$(main);
<|endoftext|>


<commit_before>/* jQuery scrollslider plugin | */
(function($) {
    var defaults = {
        height : 500,
        debug : false
    };
    var options;

    $.fn.scrollSlider = function( params ) {
        options = $.extend({}, defaults, options, params );

        var log = function( message ) {
            options['debug'] && console.log( message );
        }

        /*
        Slider elements
        */
        var $slider = $(this);
        var $viewport = $slider.find('.viewport');
        var $overview = $slider.find('.overview');
        var $scrollbar = $slider.find('.scrollbar');
        var $track = $scrollbar.find('.track');

        $track.css('position', 'relative');
        $track.css('left', 0);

        /*
        Set default height
        */
        $viewport.height( options.height );

        //slider.find('.overview img:last').on('load',

        $(window).load( function() {

            var $controlButtons = {};
            $controlButtons['left'] = $("a[data-sslider-control=left]");
            $controlButtons['right'] = $("a[data-sslider-control=right]");

            var contentWidth = 0;
            var imagesMargin = [];

            $overview.find('img').each( function( i, e ) {
                imagesMargin.push( contentWidth );
                contentWidth += $(e).outerWidth( true );
            });

            //Fix last imagesMargin
            var lastImageMargin = imagesMargin.pop();

            lastImageMargin -= ($viewport.width() - $overview.find('img:last').outerWidth());
            imagesMargin.push( lastImageMargin );

            if ( $viewport.width() > contentWidth ) {
                $scrollbar.hide();
                $controlButtons['left'].hide();
                $controlButtons['right'].hide();
                return;
            }

            /**
            Offseting variables
            **/
            var maxOffset = contentWidth - $slider.width(); //max offset for slider
            var minOffset = 0; //min offset is default by 0

            var k = ($scrollbar.width()-$track.width())/maxOffset;//multiplier for scrollbar positioning

            /**
            Events
            **/

            /**
            Mousewheel element
            **/

            $slider.on("mousewheel DOMMouseScroll", function( e ) {
                //Scroll delta
                var delta = (e.type === 'DOMMouseScroll' ?
                             e.originalEvent.detail * -40 :
                             e.originalEvent.wheelDelta);

                var overviewOffset = parseInt( $overview.css('margin-left') );
                var offset = overviewOffset + delta;

                if ( offset < minOffset && offset > -maxOffset ) {
                    //Standart situation, slides work, event return false
                    $overview.css('margin-left', offset);
                    $track.offset({
                        left: -offset*k + $scrollbar.offset().left
                    });

                    return false;
                } else if ( offset >= minOffset ) {
                    //Positioning on min offset, event return true
                    $overview.css('margin-left', minOffset);
                    $track.offset({
                        left: -minOffset*k + $scrollbar.offset().left
                    });
                    return true;
                } else if ( offset <= -maxOffset ) {
                    //Positioning on max offset, event return true
                    $overview.css('margin-left', -maxOffset);
                    $track.offset({
                        left: maxOffset*k + $scrollbar.offset().left
                    });
                    return true;
                }

                return true;
            });

            /**
            Scrollbar event
            **/

            var $dragging = null;
            var minPageX = $scrollbar.offset().left;
            var maxPageX = minPageX + $scrollbar.width() - $track.width();

            $(document).on("mousemove", function(e) {
                if ($dragging) {
                    var trackOffset = e.pageX - $track.width()/2

                    if ( trackOffset > minPageX && trackOffset < maxPageX ) {
                        $dragging.offset({
                            left: trackOffset
                        });

                        var offset = $dragging.offset().left - minPageX;
                        $overview.css('margin-left', -offset/k );
                    }
                }
            });

            $(document).on("mousedown", '.track', function (e) {
                $dragging = $(e.target);
            });

            $(document).on("mouseup", function (e) {
                $dragging = null;
            });

            /**
            Buttons event
            **/

            $controlButtons['left'].on('click', function() {
                var ml = parseInt( $overview.css('margin-left') );

                for ( var i = imagesMargin.length-1; i >=0; --i ) {
                    if ( -imagesMargin[i] > ml ) {
                        $overview.animate({'margin-left' : -imagesMargin[i]}, 'fast');
                        $track.animate({
                            'left': imagesMargin[i]*k
                        }, 'fast');
                        break;
                    }
                }

                return false;
            });

            $controlButtons['right'].on('click', function() {
                var ml = parseInt( $overview.css('margin-left') );

                for( var m in imagesMargin ) {
                    if ( -imagesMargin[m] < ml ) {
                        $overview.animate({'margin-left' : -imagesMargin[m]}, 'fast');
                        log( k );
                        log( imagesMargin[m]*k );
                        $track.animate({
                            'left': Math.round( imagesMargin[m]*k )
                        }, 'fast');
                        break;
                    }
                }

                return false;
            });
        });

        return this;
    };

})(jQuery);<commit_msg>Add different content types in options.content attr<commit_after>/* jQuery scrollslider plugin | */
(function($) {
    var defaults = {
        height : 500,
        debug : false,
        content : 'img'
    };
    var options;

    $.fn.scrollSlider = function( params ) {
        options = $.extend({}, defaults, options, params );

        var log = function( message ) {
            options['debug'] && console.log( message );
        }

        /*
        Slider elements
        */
        var $slider = $(this);
        var $viewport = $slider.find('.viewport');
        var $overview = $slider.find('.overview');
        var $scrollbar = $slider.find('.scrollbar');
        var $track = $scrollbar.find('.track');

        $track.css('position', 'relative');
        $track.css('left', 0);

        /*
        Set default height
        */
        $viewport.height( options.height );

        //slider.find('.overview img:last').on('load',

        $(window).load( function() {

            var $controlButtons = {};
            $controlButtons['left'] = $("a[data-sslider-control=left]");
            $controlButtons['right'] = $("a[data-sslider-control=right]");

            var contentWidth = 0;
            var imagesMargin = [];

            $overview.find( options.content ).each( function( i, e ) {
                imagesMargin.push( contentWidth );
                contentWidth += $(e).outerWidth( true );
            });

            //Fix last imagesMargin
            var lastImageMargin = imagesMargin.pop();

            lastImageMargin -= ($viewport.width() - $overview.find( options.content + ':last').outerWidth());
            imagesMargin.push( lastImageMargin );

            if ( $viewport.width() > contentWidth ) {
                $scrollbar.hide();
                $controlButtons['left'].hide();
                $controlButtons['right'].hide();
                return;
            }

            /**
            Offseting variables
            **/
            var maxOffset = contentWidth - $slider.width(); //max offset for slider
            var minOffset = 0; //min offset is default by 0

            var k = ($scrollbar.width()-$track.width())/maxOffset;//multiplier for scrollbar positioning

            /**
            Events
            **/

            /**
            Mousewheel element
            **/

            $slider.on("mousewheel DOMMouseScroll", function( e ) {
                //Scroll delta
                var delta = (e.type === 'DOMMouseScroll' ?
                             e.originalEvent.detail * -40 :
                             e.originalEvent.wheelDelta);

                var overviewOffset = parseInt( $overview.css('margin-left') );
                var offset = overviewOffset + delta;

                if ( offset < minOffset && offset > -maxOffset ) {
                    //Standart situation, slides work, event return false
                    $overview.css('margin-left', offset);
                    $track.offset({
                        left: -offset*k + $scrollbar.offset().left
                    });

                    return false;
                } else if ( offset >= minOffset ) {
                    //Positioning on min offset, event return true
                    $overview.css('margin-left', minOffset);
                    $track.offset({
                        left: -minOffset*k + $scrollbar.offset().left
                    });
                    return true;
                } else if ( offset <= -maxOffset ) {
                    //Positioning on max offset, event return true
                    $overview.css('margin-left', -maxOffset);
                    $track.offset({
                        left: maxOffset*k + $scrollbar.offset().left
                    });
                    return true;
                }

                return true;
            });

            /**
            Scrollbar event
            **/

            var $dragging = null;
            var minPageX = $scrollbar.offset().left;
            var maxPageX = minPageX + $scrollbar.width() - $track.width();

            $(document).on("mousemove", function(e) {
                if ($dragging) {
                    var trackOffset = e.pageX - $track.width()/2

                    if ( trackOffset > minPageX && trackOffset < maxPageX ) {
                        $dragging.offset({
                            left: trackOffset
                        });

                        var offset = $dragging.offset().left - minPageX;
                        $overview.css('margin-left', -offset/k );
                    }
                }
            });

            $(document).on("mousedown", '.track', function (e) {
                $dragging = $(e.target);
            });

            $(document).on("mouseup", function (e) {
                $dragging = null;
            });

            /**
            Buttons event
            **/

            $controlButtons['left'].on('click', function() {
                var ml = parseInt( $overview.css('margin-left') );

                for ( var i = imagesMargin.length-1; i >=0; --i ) {
                    if ( -imagesMargin[i] > ml ) {
                        $overview.animate({'margin-left' : -imagesMargin[i]}, 'fast');
                        $track.animate({
                            'left': imagesMargin[i]*k
                        }, 'fast');
                        break;
                    }
                }

                return false;
            });

            $controlButtons['right'].on('click', function() {
                var ml = parseInt( $overview.css('margin-left') );

                for( var m in imagesMargin ) {
                    if ( -imagesMargin[m] < ml ) {
                        $overview.animate({'margin-left' : -imagesMargin[m]}, 'fast');
                        log( k );
                        log( imagesMargin[m]*k );
                        $track.animate({
                            'left': Math.round( imagesMargin[m]*k )
                        }, 'fast');
                        break;
                    }
                }

                return false;
            });
        });

        return this;
    };

})(jQuery);<|endoftext|>