<commit_before>//= require "keyboard"
//= require "mouse"
//= require "user"

/**
 * @namespace Misc. UI methods that do not related to user-submitted data
 */
var Interface = {
	/**
	 * Prompts the user to select a bbox, then downloads that bbox
	 */
	download_bbox: function() {
		Glop.paused = true

		alert('Please select a bounding box to download')

		var canvas = $('canvas')

		canvas.observe('mousemove', Interface.bbox_select_mousemove)
		canvas.observe('mousedown', Interface.bbox_select_mousedown)
		canvas.observe('mouseup', Interface.bbox_select_mouseup)
		canvas.stopObserving('mousemove', Events.mousemove)
		canvas.stopObserving('mousedown', Events.mousedown)
		canvas.stopObserving('mouseup', Events.mouseup)

		Interface.bbox_select_active = true
		Interface.bbox_select_dragging = false
	},
	bbox_select_mousemove: function(e) {
		if (Interface.bbox_select_active && Interface.bbox_select_dragging) {
			var pointer_x = Map.x+(((Glop.width/-2)+Event.pointerX(e))/Cartagen.zoom_level)
			var pointer_y = Map.y+(((Glop.height/-2)+Event.pointerY(e))/Cartagen.zoom_level)

			Interface.bbox_select_end = [pointer_x, pointer_y]

			Glop.draw(false, true)

			var width = Interface.bbox_select_end[0] - Interface.bbox_select_start[0]
			var height = Interface.bbox_select_end[1] - Interface.bbox_select_start[1]

			$C.save()
			$C.fill_style('#000')
			$C.opacity(0.2)
			$C.rect(Interface.bbox_select_start[0], Interface.bbox_select_start[1], width, height)
			$C.opacity(1)
			$C.stroke_style('#000')
			$C.stroke_rect(Interface.bbox_select_start[0], Interface.bbox_select_start[1], width, height)
			$C.restore()
		}
	}.bindAsEventListener(Interface),
	bbox_select_mousedown: function(e) {
		if (Interface.bbox_select_active && !Interface.bbox_select_dragging) {
			var pointer_x = Map.x+(((Glop.width/-2)+Event.pointerX(e))/Cartagen.zoom_level)
			var pointer_y = Map.y+(((Glop.height/-2)+Event.pointerY(e))/Cartagen.zoom_level)

			Interface.bbox_select_dragging = true
			Interface.bbox_select_start = [pointer_x, pointer_y]
			Interface.bbox_select_end = Interface.bbox_select_start
		}
	}.bindAsEventListener(Interface),
	bbox_select_mouseup: function() {
		if (Interface.bbox_select_active && Interface.bbox_select_dragging) {
			Glop.paused = false
			$l(Interface.bbox_select_start[0])
			$l(Interface.bbox_select_end[0])

			var min_lon = Math.min(Projection.x_to_lon(Interface.bbox_select_start[0]), Projection.x_to_lon(Interface.bbox_select_end[0]))
			var min_lat = Math.min(Projection.y_to_lat(Interface.bbox_select_start[1]), Projection.y_to_lat(Interface.bbox_select_end[1]))
			var max_lon = Math.max(Projection.x_to_lon(Interface.bbox_select_start[0]), Projection.x_to_lon(Interface.bbox_select_end[0]))
			var max_lat = Math.max(Projection.y_to_lat(Interface.bbox_select_start[1]), Projection.y_to_lat(Interface.bbox_select_end[1]))

			var query = min_lon + ',' + min_lat + ',' + max_lon + ',' + max_lat

			window.open('/api/0.6/map.json?bbox=' + query, 'Cartagen data')

			alert('Copy these values into your Cartagen.setup call: \n\nlat1: ' + min_lat + ', \nlat2: ' + max_lat + ', \nlng1: ' + min_lon + ', \nlng2: ' + max_lon)

			var canvas = $('canvas')
			canvas.stopObserving('mousemove', Interface.bbox_select_mousemove)
			canvas.stopObserving('mousedown', Interface.bbox_select_mousedown)
			canvas.stopObserving('mouseup', Interface.bbox_select_mouseup)
			canvas.observe('mousemove', Events.mousemove)
			canvas.observe('mousedown', Events.mousedown)
			canvas.observe('mouseup', Events.mouseup)

			Interface.bbox_select_active = true
			Interface.bbox_select_dragging = false
		}
	}.bindAsEventListener(Interface)
}
<commit_msg>Change notification when you download data - the old stuff didn't work when copy/pasted into Cartagen.setup<commit_after>//= require "keyboard"
//= require "mouse"
//= require "user"

/**
 * @namespace Misc. UI methods that do not related to user-submitted data
 */
var Interface = {
	/**
	 * Prompts the user to select a bbox, then downloads that bbox
	 */
	download_bbox: function() {
		Glop.paused = true

		alert('Please select a bounding box to download')

		var canvas = $('canvas')

		canvas.observe('mousemove', Interface.bbox_select_mousemove)
		canvas.observe('mousedown', Interface.bbox_select_mousedown)
		canvas.observe('mouseup', Interface.bbox_select_mouseup)
		canvas.stopObserving('mousemove', Events.mousemove)
		canvas.stopObserving('mousedown', Events.mousedown)
		canvas.stopObserving('mouseup', Events.mouseup)

		Interface.bbox_select_active = true
		Interface.bbox_select_dragging = false
	},
	bbox_select_mousemove: function(e) {
		if (Interface.bbox_select_active && Interface.bbox_select_dragging) {
			var pointer_x = Map.x+(((Glop.width/-2)+Event.pointerX(e))/Cartagen.zoom_level)
			var pointer_y = Map.y+(((Glop.height/-2)+Event.pointerY(e))/Cartagen.zoom_level)

			Interface.bbox_select_end = [pointer_x, pointer_y]

			Glop.draw(false, true)

			var width = Interface.bbox_select_end[0] - Interface.bbox_select_start[0]
			var height = Interface.bbox_select_end[1] - Interface.bbox_select_start[1]

			$C.save()
			$C.fill_style('#000')
			$C.opacity(0.2)
			$C.rect(Interface.bbox_select_start[0], Interface.bbox_select_start[1], width, height)
			$C.opacity(1)
			$C.stroke_style('#000')
			$C.stroke_rect(Interface.bbox_select_start[0], Interface.bbox_select_start[1], width, height)
			$C.restore()
		}
	}.bindAsEventListener(Interface),
	bbox_select_mousedown: function(e) {
		if (Interface.bbox_select_active && !Interface.bbox_select_dragging) {
			var pointer_x = Map.x+(((Glop.width/-2)+Event.pointerX(e))/Cartagen.zoom_level)
			var pointer_y = Map.y+(((Glop.height/-2)+Event.pointerY(e))/Cartagen.zoom_level)

			Interface.bbox_select_dragging = true
			Interface.bbox_select_start = [pointer_x, pointer_y]
			Interface.bbox_select_end = Interface.bbox_select_start
		}
	}.bindAsEventListener(Interface),
	bbox_select_mouseup: function() {
		if (Interface.bbox_select_active && Interface.bbox_select_dragging) {
			Glop.paused = false
			$l(Interface.bbox_select_start[0])
			$l(Interface.bbox_select_end[0])

			var min_lon = Math.min(Projection.x_to_lon(Interface.bbox_select_start[0]), Projection.x_to_lon(Interface.bbox_select_end[0]))
			var min_lat = Math.min(Projection.y_to_lat(Interface.bbox_select_start[1]), Projection.y_to_lat(Interface.bbox_select_end[1]))
			var max_lon = Math.max(Projection.x_to_lon(Interface.bbox_select_start[0]), Projection.x_to_lon(Interface.bbox_select_end[0]))
			var max_lat = Math.max(Projection.y_to_lat(Interface.bbox_select_start[1]), Projection.y_to_lat(Interface.bbox_select_end[1]))

			var query = min_lon + ',' + min_lat + ',' + max_lon + ',' + max_lat

			window.open('/api/0.6/map.json?bbox=' + query, 'Cartagen data')

			var lon1 = Map.bbox[0]
			var lat2 = Map.bbox[1]
			var lon2 = Map.bbox[2]
			var lat1 = Map.bbox[3]

			alert('Copy these values into your Cartagen.setup call: \n\nlat1: ' + lat1 + ', \nlat2: ' + lat2 + ', \nlng1: ' + lon1 + ', \nlng2: ' + lon2 + ',\nzoom_level: ' + Cartagen.zoom_level)

			var canvas = $('canvas')
			canvas.stopObserving('mousemove', Interface.bbox_select_mousemove)
			canvas.stopObserving('mousedown', Interface.bbox_select_mousedown)
			canvas.stopObserving('mouseup', Interface.bbox_select_mouseup)
			canvas.observe('mousemove', Events.mousemove)
			canvas.observe('mousedown', Events.mousedown)
			canvas.observe('mouseup', Events.mouseup)

			Interface.bbox_select_active = true
			Interface.bbox_select_dragging = false
		}
	}.bindAsEventListener(Interface)
}
<|endoftext|>


<commit_before>var fs = require('fs')
  , path = require('path')
  , request = require('request')
  , dbox = require('dbox')
  , qs = require('querystring')
  , url = require('url')
  , _ = require('lodash')

var dropbox_config_file = path.resolve(__dirname, 'dropbox-config.json')
  , dropbox_config = {}
  , isUsingDefaultConfig = true
// ^^^helps with the home page view; should we show the dropbox dropdown?

if(fs.existsSync(dropbox_config_file)) {
  dropbox_config = JSON.parse( fs.readFileSync( dropbox_config_file, 'utf-8' ) )
  isUsingDefaultConfig = false
} else {
  dropbox_config = {
    "app_key": "YOUR_KEY"
  , "app_secret": "YOUR_SECRET"
  , "callback_url": "YOUR_CALLBACK_URL"
  , "auth_url": "https://www.dropbox.com/1/oauth/authorize"
  , "request_token_url": "https://api.dropbox.com/1/oauth/request_token"
  , "access_token_url": "https://api.dropbox.com/1/oauth/access_token"
  , "collections_url": "https://api-content.dropbox.com/1"
  }
  console.warn('Dropbox config not found at ' + dropbox_config_file + '. Using defaults instead.')
}

exports.Dropbox = (function() {

  var dboxapp = dbox.app({
  	"app_key": dropbox_config.app_key,
  	"app_secret": dropbox_config.app_secret,
  	"root": "dropbox" })

  // Grab collection from db
  function _getCollection(collectionId, cb){

	  var dbUrl = url.resolve(dropbox_config.collections_url, '/collection?')

	  var params = {'id': collectionId}

	  dbUrl += qs.stringify(params)

	  console.log(dbUrl + " is the dbUrl")

	  // Umm auth'd with dropbox? Need to add this...
	  request.get(dbUrl, function requestCb(err,resp,body){
	  	if(err) return cb(err)
	  	cb && cb(null,body)
	  })

  } // end _getCollection

  // Grab collection's actual content from db
  function _getCollectionItemContents(collectionId, item_id, cb){

	  var dbUrl = url.resolve(dropbox_config.collections_url, '/collection_item_contents?')

	  var params = {'id': collectionId, 'item_id': item_id}

	  dbUrl += qs.stringify(params)

	  console.log(dbUrl + " is the dbUrl")

	  // Umm auth'd with dropbox? Need to add this...
	  request.get(dbUrl, function requestCb(err,resp,body){
	  	if(err) return cb(err)
	  	if(!resp.headers['X-Dropbox-Item-Metadata']) return cb(new Error('No X-Dropbox-Item-Metadata header found.'))
	  	cb && cb(null,body)
	  })

  } // end getCollectionItemContents

  return {
    isUsingDefault: isUsingDefaultConfig,
    config: dropbox_config,
    getNewRequestToken: function(req, res, cb) {

      dboxapp.requesttoken(function(status, request_token){

        console.log(request_token)
        return cb(status, request_token)

      })
      // Create your auth_url for the view

    },
    getRemoteAccessToken: function(request_token, request_token_secret, cb) {

      var req_token = {oauth_token : request_token, oauth_token_secret : request_token_secret};
      dboxapp.accesstoken(req_token, function(status, access_token) {

          console.log(access_token)
          return cb(status, access_token)

      });

    }, // end getRemoteAccessToken()
    getAccountInfo: function(dropbox_obj, cb) {
      var access_token = {oauth_token : dropbox_obj.oauth.access_token, oauth_token_secret : dropbox_obj.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      dboxclient.account(function(status, reply){
        return cb(status, reply)
      })

    }, // end getAccountInfo()
    fetchDropboxFile: function(req, res) {

      if(!req.session.isDropboxSynced){
        res.type('text/plain')
        return res.status(403).send("You are not authenticated with Dropbox.")
      }

      var access_token = {
      	oauth_token : req.session.dropbox.oauth.access_token,
      	oauth_token_secret : req.session.dropbox.oauth.access_token_secret
     	}

      var dboxclient = dboxapp.client(access_token)

      var pathToMdFile = req.body.mdFile

      dboxclient.get(pathToMdFile, function(status, reply, metadata) {

        return res.json({data: reply.toString()})

      })

    },
    searchForMdFiles: function(dropbox_obj, cb) {

      // *sigh* http://forums.dropbox.com/topic.php?id=50266&replies=1

      var access_token = {oauth_token : dropbox_obj.oauth.access_token, oauth_token_secret : dropbox_obj.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      var options = {
        file_limit         : 500,
        include_deleted    : false
      }

      dboxclient.search("/", ".md", options, function(status, reply) {
        var regex = /.*\.md$/i;
        var files = []
        reply.forEach(function(item){
          if(regex.test(item.path)) {
            files.push(item)
          }
        })
        dboxclient.search("/", ".mdown", options, function(status, reply) {
          files = files.concat(reply)
          dboxclient.search("/", ".markdown", options, function(status, reply) {
            files = files.concat(reply)
            return cb(status, files)
          })
        })
      })

    },
    saveToDropbox: function(req, res){

      if(!req.session.isDropboxSynced){
        res.type('text/plain')
        return res.status(403).send("You are not authenticated with Dropbox.")
      }

      var access_token = {oauth_token : req.session.dropbox.oauth.access_token, oauth_token_secret : req.session.dropbox.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      // TODO: EXPOSE THE CORE MODULE SO WE CAN GENERATE RANDOM NAMES

      var pathToMdFile = req.body.pathToMdFile || '/Dillinger/' + md.generateRandomMdFilename('md')
      var contents = req.body.fileContents || 'Test Data from Dillinger.'

      dboxclient.put(pathToMdFile, contents, function(status, reply){
        return res.json({data: reply})
      })

    }, // end saveToDropbox
    handleIncomingFlowRequest: function(req, res, cb){

    	// TODO: Are they auth'd?  How do handle this?

    	var editFlowJson = JSON.parse( req.params['edit_flow_blob'] )
    		,	item_id = editFlowJson['items_ids'][0] // the actual item_id of the md file

    	// first, we have to get the collection
			// "edit_flow" is hardcoded for Flow prototyping
    	_getCollection('edit_flow', function getCollectionCb(err,data){

    		if(err){
    			console.error(err)
    			return res.send(500)
    		}
    		// Now get the contents...
    		_getCollectionItemContents('edit_flow', item_id, function _getCollectionItemContentsCb(err,data){

	    		if(err){
	    			console.error(err)
	    			return res.send(500)
	    		}

	    		// if no errors, we should have the actual raw data...

	    		console.log(data)

    		}) // end _getCollectionItemContents

    	}) // end _getCollection

    } // end handleIncomingFlowRequest

  }

})()

<commit_msg>Added edit-flow logic<commit_after>var fs = require('fs')
  , path = require('path')
  , request = require('request')
  , dbox = require('dbox')
  , qs = require('querystring')
  , url = require('url')
  , _ = require('lodash')

var dropbox_config_file = path.resolve(__dirname, 'dropbox-config.json')
  , dropbox_config = {}
  , isUsingDefaultConfig = true
// ^^^helps with the home page view; should we show the dropbox dropdown?

if(fs.existsSync(dropbox_config_file)) {
  dropbox_config = JSON.parse( fs.readFileSync( dropbox_config_file, 'utf-8' ) )
  isUsingDefaultConfig = false
} else {
  dropbox_config = {
    "app_key": "YOUR_KEY"
  , "app_secret": "YOUR_SECRET"
  , "callback_url": "YOUR_CALLBACK_URL"
  , "auth_url": "https://www.dropbox.com/1/oauth/authorize"
  , "request_token_url": "https://api.dropbox.com/1/oauth/request_token"
  , "access_token_url": "https://api.dropbox.com/1/oauth/access_token"
  , "collections_url": "https://api-content.dropbox.com/1"
  }
  console.warn('Dropbox config not found at ' + dropbox_config_file + '. Using defaults instead.')
}

exports.Dropbox = (function() {

  var dboxapp = dbox.app({
  	"app_key": dropbox_config.app_key,
  	"app_secret": dropbox_config.app_secret,
  	"root": "dropbox" })

  return {
    isUsingDefault: isUsingDefaultConfig,
    config: dropbox_config,
    getNewRequestToken: function(req, res, cb) {

      // Create your auth_url for the view
      dboxapp.requesttoken(function(status, request_token){

        return cb(status, request_token)

      })

    },
    getRemoteAccessToken: function(request_token, request_token_secret, cb) {

      var req_token = {oauth_token : request_token, oauth_token_secret : request_token_secret}

      dboxapp.accesstoken(req_token, function(status, access_token){
	      return cb(status, access_token)
      })

    }, // end getRemoteAccessToken()
    getAccountInfo: function(dropbox_obj, cb) {
      var access_token = {oauth_token : dropbox_obj.oauth.access_token, oauth_token_secret : dropbox_obj.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      dboxclient.account(function(status, reply){
        return cb(status, reply)
      })

    }, // end getAccountInfo()
    fetchDropboxFile: function(req, res) {

      if(!req.session.isDropboxSynced){
        res.type('text/plain')
        return res.status(403).send("You are not authenticated with Dropbox.")
      }

      var access_token = {
      	oauth_token : req.session.dropbox.oauth.access_token,
      	oauth_token_secret : req.session.dropbox.oauth.access_token_secret
     	}

      var dboxclient = dboxapp.client(access_token)

      var pathToMdFile = req.body.mdFile

      dboxclient.get(pathToMdFile, function(status, reply, metadata) {

        return res.json({data: reply.toString()})

      })

    },
    searchForMdFiles: function(dropbox_obj, cb) {

      // *sigh* http://forums.dropbox.com/topic.php?id=50266&replies=1

      var access_token = {oauth_token : dropbox_obj.oauth.access_token, oauth_token_secret : dropbox_obj.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      var options = {
        file_limit         : 500,
        include_deleted    : false
      }

      dboxclient.search("/", ".md", options, function(status, reply) {
        var regex = /.*\.md$/i
        	,	files = []
        	;

        if(status > 399 || !reply){
        	return cb(new Error('Bad response.'))
        }

        reply.forEach(function(item){
          if(regex.test(item.path)) {
            files.push(item)
          }
        })

        dboxclient.search("/", ".mdown", options, function(status, reply) {
          files = files.concat(reply)

          dboxclient.search("/", ".markdown", options, function(status, reply) {
            files = files.concat(reply)
            return cb(status, files)
          })

        })

      })

    },
    saveToDropbox: function(req, res){

      if(!req.session.isDropboxSynced){
        res.type('text/plain')
        return res.status(403).send("You are not authenticated with Dropbox.")
      }

      var access_token = {oauth_token : req.session.dropbox.oauth.access_token, oauth_token_secret : req.session.dropbox.oauth.access_token_secret};

      var dboxclient = dboxapp.client(access_token)

      // TODO: EXPOSE THE CORE MODULE SO WE CAN GENERATE RANDOM NAMES

      var pathToMdFile = req.body.pathToMdFile || '/Dillinger/' + md.generateRandomMdFilename('md')
      var contents = req.body.fileContents || 'Test Data from Dillinger.'

      dboxclient.put(pathToMdFile, contents, function(status, reply){
        return res.json({data: reply})
      })

    }, // end saveToDropbox
    handleIncomingFlowRequest: function(req, res, cb){

    	var	filePath = req.query['path']
    		,	access_token = {oauth_token : req.session.dropbox.oauth.access_token, oauth_token_secret : req.session.dropbox.oauth.access_token_secret}
    		,	dboxclient = dboxapp.client(access_token)

    	if(!access_token){
	    	return res.redirect('/redirect/dropbox')
    	}

      dboxclient.get(filePath, function(status, reply, metadata){
	      return res.json({data: reply.toString(), filename: path.basename(filePath)})
      })

    } // end handleIncomingFlowRequest

  }

})()

<|endoftext|>


<commit_before>'use strict';

var config = require('../../config');

/*
 * Code samples from:
 * http://docs.basho.com/riak/latest/dev/using/data-types/
 */

var async = require('async');
var clone = require('clone');
var logger = require('winston');
var Riak = require('basho-riak-client');

function DevUsingDataTypes() {
    var client = config.createClient();

    counter_examples();

    set_examples();

    map_examples();

    function set_examples() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        client.fetchSet(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            if (rslt.notFound) {
                logger.info("[DevUsingDataTypes] set 'cities' is not found!");
            }
            add_to_cities_set();
        });
    }

    function add_to_cities_set() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        var cmd = new Riak.Commands.CRDT.UpdateSet.Builder()
            .withBucketType(options.bucketType)
            .withBucket(options.bucket)
            .withKey(options.key)
            .withAdditions(['Toronto', 'Montreal'])
            .withCallback(
                function (err, rslt) {
                    if (err) {
                        throw new Error(err);
                    }

                    change_cities_set();
                }
            )
            .build();
        client.execute(cmd);
    }

    function change_cities_set() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        client.fetchSet(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            var update_opts = clone(options);
            update_opts.context = rslt.context;
            update_opts.additions = ['Hamilton', 'Ottawa'];
            update_opts.removals = ['Montreal', 'Ottawa'];

            client.updateSet(update_opts, function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }

                client.fetchSet(options, function(err, rslt) {
                    if (err) {
                        throw new Error(err);
                    }

                    logger.info("[DevUsingDataTypes] cities set values: '%s'",
                        rslt.values.join(', '));
                });
            });
        });
    }

    function counter_examples() {
        var options = {
            bucketType: 'counters',
            bucket: 'counter',
            key: 'traffic_tickets'
        };
        create_or_update_counter(options, 1, function(opt1) {
            display_counter(opt1, function(opt2) {
                create_or_update_counter(opt2, -1, function(opt3) {
                    display_counter(opt3);
                });
            });
        });
    }

    function create_or_update_counter(options, amount, next_func) {
        var my_opts = clone(options);
        my_opts.increment = amount;
        client.updateCounter(my_opts,
            function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }
                if (next_func) {
                    next_func(options);
                }
            }
        );
    }

    function display_counter(options, next_func) {
        client.fetchCounter(options,
            function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }

                if (rslt.notFound) {
                    logger.error("[DevUsingDataTypes] bt: %s, b: %s, k: %s, counter: NOT FOUND",
                        options.bucketType, options.bucket, options.key);
                } else {
                    logger.info("[DevUsingDataTypes] bt: %s, b: %s, k: %s, counter: %d",
                        options.bucketType, options.bucket, options.key, rslt.counterValue);
                }

                if (next_func) {
                    next_func(options);
                }
            }
        );
    }

    function map_examples() {

        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.setRegister('first_name', new Buffer('Ahmed'));
        mapOp.setRegister('phone_number', new Buffer('5551234567'));

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            flags_within_maps();
        });
    }

    function print_map(next_func) {
        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info'
        };

        client.fetchMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            logger.info("[DevUsingDataTypes] fetched map: %s", JSON.stringify(rslt));

            if (next_func) {
                next_func();
            }
        });
    }

    function flags_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.setFlag('enterprise_customer', false);

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            print_map(counters_within_maps);
        });
    }

    function counters_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.incrementCounter('page_visits', 1);

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            print_map(sets_within_maps);
        });
    }

    function sets_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.addToSet('interests', 'robots');
        mapOp.addToSet('interests', 'opera');
        mapOp.addToSet('interests', 'motorcycles');

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            print_map();
        });
    }
}

module.exports = DevUsingDataTypes;

<commit_msg>more examples from dev/using/data-types<commit_after>'use strict';

var config = require('../../config');

/*
 * Code samples from:
 * http://docs.basho.com/riak/latest/dev/using/data-types/
 */

var assert = require('assert');
var async = require('async');
var clone = require('clone');
var logger = require('winston');
var Riak = require('basho-riak-client');

function DevUsingDataTypes() {
    var client = config.createClient();

    counter_examples();

    set_examples();

    map_examples();

    function set_examples() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        client.fetchSet(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            if (rslt.notFound) {
                logger.info("[DevUsingDataTypes] set 'cities' is not found!");
            }
            add_to_cities_set();
        });
    }

    function add_to_cities_set() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        var cmd = new Riak.Commands.CRDT.UpdateSet.Builder()
            .withBucketType(options.bucketType)
            .withBucket(options.bucket)
            .withKey(options.key)
            .withAdditions(['Toronto', 'Montreal'])
            .withCallback(
                function (err, rslt) {
                    if (err) {
                        throw new Error(err);
                    }

                    change_cities_set();
                }
            )
            .build();
        client.execute(cmd);
    }

    function change_cities_set() {
        var options = {
            bucketType: 'sets',
            bucket: 'travel',
            key: 'cities'
        };
        client.fetchSet(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            var update_opts = clone(options);
            update_opts.context = rslt.context;
            update_opts.additions = ['Hamilton', 'Ottawa'];
            update_opts.removals = ['Montreal', 'Ottawa'];

            client.updateSet(update_opts, function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }

                client.fetchSet(options, function(err, rslt) {
                    if (err) {
                        throw new Error(err);
                    }

                    logger.info("[DevUsingDataTypes] cities set values: '%s'",
                        rslt.values.join(', '));
                });
            });
        });
    }

    function counter_examples() {
        var options = {
            bucketType: 'counters',
            bucket: 'counter',
            key: 'traffic_tickets'
        };
        create_or_update_counter(options, 1, function(opt1) {
            display_counter(opt1, function(opt2) {
                create_or_update_counter(opt2, -1, function(opt3) {
                    display_counter(opt3);
                });
            });
        });
    }

    function create_or_update_counter(options, amount, next_func) {
        var my_opts = clone(options);
        my_opts.increment = amount;
        client.updateCounter(my_opts,
            function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }
                if (next_func) {
                    next_func(options);
                }
            }
        );
    }

    function display_counter(options, next_func) {
        client.fetchCounter(options,
            function (err, rslt) {
                if (err) {
                    throw new Error(err);
                }

                if (rslt.notFound) {
                    logger.error("[DevUsingDataTypes] bt: %s, b: %s, k: %s, counter: NOT FOUND",
                        options.bucketType, options.bucket, options.key);
                } else {
                    logger.info("[DevUsingDataTypes] bt: %s, b: %s, k: %s, counter: %d",
                        options.bucketType, options.bucket, options.key, rslt.counterValue);
                }

                if (next_func) {
                    next_func(options);
                }
            }
        );
    }

    function map_examples() {

        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.setRegister('first_name', new Buffer('Ahmed'));
        mapOp.setRegister('phone_number', new Buffer('5551234567'));

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            flags_within_maps();
        });
    }

    function print_map(next_func) {
        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info'
        };

        client.fetchMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            logger.info("[DevUsingDataTypes] fetched map: %s", JSON.stringify(rslt));

            if (next_func) {
                next_func();
            }
        });
    }

    function flags_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.setFlag('enterprise_customer', false);

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            print_map(counters_within_maps);
        });
    }

    function counters_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.incrementCounter('page_visits', 1);

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            print_map(sets_within_maps);
        });
    }

    function sets_within_maps() {
        var mapOp = new Riak.Commands.CRDT.UpdateMap.MapOperation();
        mapOp.addToSet('interests', 'robots');
        mapOp.addToSet('interests', 'opera');
        mapOp.addToSet('interests', 'motorcycles');

        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info',
            op: mapOp
        };

        client.updateMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            verify_interests_set();
        });
    }

    function verify_interests_set() {
        var options = {
            bucketType: 'maps',
            bucket: 'customers',
            key: 'ahmed_info'
        };

        client.fetchMap(options, function (err, rslt) {
            if (err) {
                throw new Error(err);
            }

            assert(rslt.map.sets['interests'].indexOf('robots') !== -1);
        });
    }
}

module.exports = DevUsingDataTypes;

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2020 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas 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, version 3 of the License.
 *
 * Canvas 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/>.
 */
import {arrayOf, func, string} from 'prop-types'
import {useScope as useI18nScope} from '@canvas/i18n'
import React, {useEffect, useState} from 'react'

import {Flex} from '@instructure/ui-flex'
import {IconButton} from '@instructure/ui-buttons'
import {
  IconAlertsSolid,
  IconCalendarDaySolid,
  IconCalendarMonthSolid,
  IconMutedLine,
  IconNoLine
} from '@instructure/ui-icons'
import {Menu} from '@instructure/ui-menu'
import {Text} from '@instructure/ui-text'
import {Tooltip} from '@instructure/ui-tooltip'

const I18n = useI18nScope('notification_preferences')

const preferenceConfigs = {
  immediately: {
    icon: IconAlertsSolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Notify immediately')
  },
  daily: {
    icon: IconCalendarDaySolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Daily summary')
  },
  weekly: {
    icon: IconCalendarMonthSolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Weekly summary')
  },
  never: {
    icon: IconMutedLine,
    getScreenReaderLabel: () => I18n.t('Notifications off')
  },
  disabled: {
    icon: IconNoLine,
    getScreenReaderLabel: () => I18n.t('Notifications unsupported')
  }
}

const renderPreferenceButton = preferenceConfig => (
  <Tooltip renderTip={preferenceConfig.getScreenReaderLabel()} placement="bottom">
    <IconButton
      withBackground={false}
      withBorder={false}
      renderIcon={preferenceConfig.icon}
      color={preferenceConfig.color}
      screenReaderLabel={preferenceConfig.getScreenReaderLabel()}
    />
  </Tooltip>
)

const renderPreferenceMenuItem = preferenceConfig => (
  <Flex>
    <Flex.Item margin="0 x-small 0 0" padding="0 0 xxx-small 0">
      <preferenceConfig.icon />
    </Flex.Item>
    <Flex.Item>
      <Text>{preferenceConfig.getScreenReaderLabel()}</Text>
    </Flex.Item>
  </Flex>
)

const NotificationPreferencesSetting = ({
  selectedPreference,
  preferenceOptions,
  updatePreference
}) => {
  const [selection, setSelection] = useState(selectedPreference)

  useEffect(() => {
    setSelection(selectedPreference)
  }, [selectedPreference])

  const handleUpdate = value => {
    setSelection(value)
    updatePreference(value)
  }

  const preferenceConfig = preferenceConfigs[selection]
  return (
    <Menu
      trigger={renderPreferenceButton(preferenceConfig)}
      disabled={selection === 'disabled'}
      onSelect={(e, value) => handleUpdate(value)}
    >
      {preferenceOptions.map(option => (
        <Menu.Item key={option} value={option} selected={option === selection}>
          {renderPreferenceMenuItem(preferenceConfigs[option])}
        </Menu.Item>
      ))}
    </Menu>
  )
}

NotificationPreferencesSetting.propTypes = {
  selectedPreference: string,
  preferenceOptions: arrayOf(string),
  updatePreference: func
}

export default NotificationPreferencesSetting
<commit_msg>Fix change notification screenreader to identify it as a menu<commit_after>/*
 * Copyright (C) 2020 - present Instructure, Inc.
 *
 * This file is part of Canvas.
 *
 * Canvas 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, version 3 of the License.
 *
 * Canvas 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/>.
 */
import {arrayOf, func, string} from 'prop-types'
import {useScope as useI18nScope} from '@canvas/i18n'
import React, {useEffect, useState} from 'react'

import {Flex} from '@instructure/ui-flex'
import {IconButton} from '@instructure/ui-buttons'
import {
  IconAlertsSolid,
  IconCalendarDaySolid,
  IconCalendarMonthSolid,
  IconMutedLine,
  IconNoLine
} from '@instructure/ui-icons'
import {Menu} from '@instructure/ui-menu'
import {Text} from '@instructure/ui-text'
import {Tooltip} from '@instructure/ui-tooltip'

const I18n = useI18nScope('notification_preferences')

const preferenceConfigs = {
  immediately: {
    icon: IconAlertsSolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Notify immediately')
  },
  daily: {
    icon: IconCalendarDaySolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Daily summary')
  },
  weekly: {
    icon: IconCalendarMonthSolid,
    color: 'success',
    getScreenReaderLabel: () => I18n.t('Weekly summary')
  },
  never: {
    icon: IconMutedLine,
    getScreenReaderLabel: () => I18n.t('Notifications off')
  },
  disabled: {
    icon: IconNoLine,
    getScreenReaderLabel: () => I18n.t('Notifications unsupported')
  }
}

const renderPreferenceButton = preferenceConfig => (
  <Tooltip renderTip={preferenceConfig.getScreenReaderLabel()} placement="bottom">
    <IconButton
      withBackground={false}
      withBorder={false}
      renderIcon={preferenceConfig.icon}
      color={preferenceConfig.color}
      screenReaderLabel={preferenceConfig.getScreenReaderLabel()}
      aria-haspopup="true"
    />
  </Tooltip>
)

const renderPreferenceMenuItem = preferenceConfig => (
  <Flex>
    <Flex.Item margin="0 x-small 0 0" padding="0 0 xxx-small 0">
      <preferenceConfig.icon />
    </Flex.Item>
    <Flex.Item>
      <Text>{preferenceConfig.getScreenReaderLabel()}</Text>
    </Flex.Item>
  </Flex>
)

const NotificationPreferencesSetting = ({
  selectedPreference,
  preferenceOptions,
  updatePreference
}) => {
  const [selection, setSelection] = useState(selectedPreference)

  useEffect(() => {
    setSelection(selectedPreference)
  }, [selectedPreference])

  const handleUpdate = value => {
    setSelection(value)
    updatePreference(value)
  }

  const preferenceConfig = preferenceConfigs[selection]
  return (
    <Menu
      trigger={renderPreferenceButton(preferenceConfig)}
      disabled={selection === 'disabled'}
      onSelect={(e, value) => handleUpdate(value)}
    >
      {preferenceOptions.map(option => (
        <Menu.Item key={option} value={option} selected={option === selection}>
          {renderPreferenceMenuItem(preferenceConfigs[option])}
        </Menu.Item>
      ))}
    </Menu>
  )
}

NotificationPreferencesSetting.propTypes = {
  selectedPreference: string,
  preferenceOptions: arrayOf(string),
  updatePreference: func
}

export default NotificationPreferencesSetting
<|endoftext|>


<commit_before>

var fs = require('fs');
var Parser = require('./parse.js').StreamParser;

var argv = process.argv.slice(2);
for(var i=0; i<argv.length; i++){
	var arg = argv[i];
	if(arg.slice(0,1)=='-') switch(arg){
		case '-v': case '--version':
			console.log();
			break;
	}
}

var dirpath = 'test/syntax-suite/test_parsing';
var syntaxTestFiles = fs.readdirSync(dirpath).filter(function(n){
	return n[0]=='y' || n[0]=='n';
});

var validationTestFiles = [
	'tests/draft4/additionalItems.json',
	//'tests/draft4/additionalProperties.json',
	//'tests/draft4/allOf.json',
	//'tests/draft4/anyOf.json',
	'tests/draft4/default.json',
	//'tests/draft4/definitions.json',
	//'tests/draft4/dependencies.json',
	//'tests/draft4/enum.json',
	'tests/draft4/items.json',
	'tests/draft4/maximum.json',
	'tests/draft4/maxItems.json',
	//'tests/draft4/maxLength.json',
	'tests/draft4/maxProperties.json',
	'tests/draft4/minimum.json',
	'tests/draft4/minItems.json',
	//'tests/draft4/minLength.json',
	'tests/draft4/minProperties.json',
	'tests/draft4/multipleOf.json',
	//'tests/draft4/not.json',
	//'tests/draft4/oneOf.json',
	//'tests/draft4/pattern.json',
	//'tests/draft4/patternProperties.json',
	'tests/draft4/properties.json',
	//'tests/draft4/ref.json',
	//'tests/draft4/refRemote.json',
	'tests/draft4/required.json',
	'tests/draft4/type.json',
	//'tests/draft4/uniqueItems.json',
];

function runSyntaxTest(filename, done){
	var res = {
		pass: 0,
		fail: 0,
		messages: [],
		total: 0,
	};
	var filepath = dirpath + '/' + filename;
	var valid = null;
	if(filename[0]=='y') valid = true;
	else if(filename[0]=='n') valid=false;
	else return void done(new Error('Unknown test type'));
	var testError = null;
	var t = fs.createReadStream(filepath);
	var p = new Parser({}, {});
	t.pipe(p);
	p.on('error', function(err){
		if(!err) return;
		testError = err;
		result(err);
	});
	t.on('end', function(){
		if(testError) return;
		result();
	});
	function result(err){
		res.total++;
		if((valid==false && err) || (valid==true && !err)){
			res.pass++;
		}else{
			res.fail++;
			var er = {description:err.stack, valid:valid, error:err, value:p.value};
			res.messages.push(er);
		}
		return void done(null, res);
	}
}

function runValidationTest(filepath, done){
	var res = {
		pass: 0,
		fail: 0,
		messages: [],
		total: 0,
	};
	var schemas = require('./test/schema-suite/'+filepath);
	//console.log(filepath + ' ...');
	schemas.forEach(function(s){
		var schema = s.schema;
		var tests = s.tests;
		tests.forEach(function(t, i){
			var tjson = JSON.stringify(t.data, null, "\t");
			var p = new Parser(schema, {});
			p._transform(tjson);
			p.eof();
			res.total++;
			if(t.valid!=!!p.errors.length){
				res.pass++;
			}else{
				res.fail++;
				var er = {description:t.description, i:i, valid:t.valid, errors:p.errors, schema:schema, value:t.data};
				res.messages.push(er);
				//console.error('  Error: ('+er.description+') expected '+(er.valid?'valid':'invalid')+' but got '+er.errors.length+' errors');
				//console.log(er.schema, er.value);
				//console.error(er.errors);
			}
		});
	});
	return void done(null, res);
}

function runTests(){
	var totalFail = 0;
	var pass = 0;
	var fail = 0;
	var total = 0;
	var messages = [];
	nextSyntaxTest(0);
	function nextSyntaxTest(i){
		if(i==0) console.log('Running syntax tests...');
		var n = syntaxTestFiles[i];
		if(!n) return void finishSyntaxTests();
		runSyntaxTest(n, function(err, res){
			if(err) throw err;
			res.messages.forEach(function(v){
				console.log('Error: syntaxTest('+n+') '+v.description);
			});
			pass += res.pass;
			fail += res.fail;
			totalFail += res.fail;
			total += res.total;
			nextSyntaxTest(i+1);
		});
	}
	function finishSyntaxTests(){
		if(fail) console.log('Running syntax tests: ' + fail + ' failed');
		console.log('Running syntax tests: ' + pass + '/' + total + ' passed');
		console.log('Running validation tests...');
		pass = 0;
		fail = 0;
		total = 0;
		nextValidationTest(0);
	}
	function nextValidationTest(i){
		var n = validationTestFiles[i];
		if(!n) return void finishValidationTests(0);
		runValidationTest(n, function(err, res){
			if(err) throw err;
			res.messages.forEach(function(v){
				console.log('Error: validationTest('+n+') '+v.description, v);
			});
			pass += res.pass;
			fail += res.fail;
			totalFail += res.fail;
			total += res.total;
			nextValidationTest(i+1);
		});
	}
	function finishValidationTests(){
		if(fail) console.log('Validation tests: ' + fail + ' failed');
		console.log('Validation tests: ' + pass + '/' + total + ' passed');
		//if(totalFail) process.exit(1);
	}
}

runTests();

<commit_msg>Has support for "allOf"<commit_after>

var fs = require('fs');
var Parser = require('./parse.js').StreamParser;

var argv = process.argv.slice(2);
for(var i=0; i<argv.length; i++){
	var arg = argv[i];
	if(arg.slice(0,1)=='-') switch(arg){
		case '-v': case '--version':
			console.log();
			break;
	}
}

var dirpath = 'test/syntax-suite/test_parsing';
var syntaxTestFiles = fs.readdirSync(dirpath).filter(function(n){
	return n[0]=='y' || n[0]=='n';
});

var validationTestFiles = [
	'tests/draft4/additionalItems.json',
	//'tests/draft4/additionalProperties.json',
	'tests/draft4/allOf.json',
	//'tests/draft4/anyOf.json',
	'tests/draft4/default.json',
	//'tests/draft4/definitions.json',
	//'tests/draft4/dependencies.json',
	//'tests/draft4/enum.json',
	'tests/draft4/items.json',
	'tests/draft4/maximum.json',
	'tests/draft4/maxItems.json',
	//'tests/draft4/maxLength.json',
	'tests/draft4/maxProperties.json',
	'tests/draft4/minimum.json',
	'tests/draft4/minItems.json',
	//'tests/draft4/minLength.json',
	'tests/draft4/minProperties.json',
	'tests/draft4/multipleOf.json',
	//'tests/draft4/not.json',
	//'tests/draft4/oneOf.json',
	//'tests/draft4/pattern.json',
	//'tests/draft4/patternProperties.json',
	'tests/draft4/properties.json',
	//'tests/draft4/ref.json',
	//'tests/draft4/refRemote.json',
	'tests/draft4/required.json',
	'tests/draft4/type.json',
	//'tests/draft4/uniqueItems.json',
];

function runSyntaxTest(filename, done){
	var res = {
		pass: 0,
		fail: 0,
		messages: [],
		total: 0,
	};
	var filepath = dirpath + '/' + filename;
	var valid = null;
	if(filename[0]=='y') valid = true;
	else if(filename[0]=='n') valid=false;
	else return void done(new Error('Unknown test type'));
	var testError = null;
	var t = fs.createReadStream(filepath);
	var p = new Parser({}, {});
	t.pipe(p);
	p.on('error', function(err){
		if(!err) return;
		testError = err;
		result(err);
	});
	t.on('end', function(){
		if(testError) return;
		result();
	});
	function result(err){
		res.total++;
		if((valid==false && err) || (valid==true && !err)){
			res.pass++;
		}else{
			res.fail++;
			var er = {description:err.stack, valid:valid, error:err, value:p.value};
			res.messages.push(er);
		}
		return void done(null, res);
	}
}

function runValidationTest(filepath, done){
	var res = {
		pass: 0,
		fail: 0,
		messages: [],
		total: 0,
	};
	var schemas = require('./test/schema-suite/'+filepath);
	//console.log(filepath + ' ...');
	schemas.forEach(function(s){
		var schema = s.schema;
		var tests = s.tests;
		tests.forEach(function(t, i){
			var tjson = JSON.stringify(t.data, null, "\t");
			var p = new Parser(schema, {});
			p._transform(tjson);
			p.eof();
			res.total++;
			if(t.valid!=!!p.errors.length){
				res.pass++;
			}else{
				res.fail++;
				var er = {description:t.description, i:i, valid:t.valid, errors:p.errors, schema:schema, value:t.data};
				res.messages.push(er);
				//console.error('  Error: ('+er.description+') expected '+(er.valid?'valid':'invalid')+' but got '+er.errors.length+' errors');
				//console.log(er.schema, er.value);
				//console.error(er.errors);
			}
		});
	});
	return void done(null, res);
}

function runTests(){
	var totalFail = 0;
	var pass = 0;
	var fail = 0;
	var total = 0;
	var messages = [];
	nextSyntaxTest(0);
	function nextSyntaxTest(i){
		if(i==0) console.log('Running syntax tests...');
		var n = syntaxTestFiles[i];
		if(!n) return void finishSyntaxTests();
		runSyntaxTest(n, function(err, res){
			if(err) throw err;
			res.messages.forEach(function(v){
				console.log('Error: syntaxTest('+n+') '+v.description);
			});
			pass += res.pass;
			fail += res.fail;
			totalFail += res.fail;
			total += res.total;
			nextSyntaxTest(i+1);
		});
	}
	function finishSyntaxTests(){
		if(fail) console.log('Running syntax tests: ' + fail + ' failed');
		console.log('Running syntax tests: ' + pass + '/' + total + ' passed');
		console.log('Running validation tests...');
		pass = 0;
		fail = 0;
		total = 0;
		nextValidationTest(0);
	}
	function nextValidationTest(i){
		var n = validationTestFiles[i];
		if(!n) return void finishValidationTests(0);
		runValidationTest(n, function(err, res){
			if(err) throw err;
			res.messages.forEach(function(v){
				console.log('Error: validationTest('+n+') '+v.description, v);
			});
			pass += res.pass;
			fail += res.fail;
			totalFail += res.fail;
			total += res.total;
			nextValidationTest(i+1);
		});
	}
	function finishValidationTests(){
		if(fail) console.log('Validation tests: ' + fail + ' failed');
		console.log('Validation tests: ' + pass + '/' + total + ' passed');
		//if(totalFail) process.exit(1);
	}
}

runTests();

<|endoftext|>


<commit_before>define([],function meltreporter(){

  var isHeadless = false;

  if(window.navigator.userAgent.match(/PhantomJS/)) {
    isHeadless = true;
  }

  var styles = {
    //styles
    'bold'      : ['\033[1m',  '\033[22m'],
    'italic'    : ['\033[3m',  '\033[23m'],
    'underline' : ['\033[4m',  '\033[24m'],
    'inverse'   : ['\033[7m',  '\033[27m'],
    //grayscale
    'white'     : ['\033[37m', '\033[39m'],
    'grey'      : ['\033[90m', '\033[39m'],
    'black'     : ['\033[30m', '\033[39m'],
    //colors
    'blue'      : ['\033[34m', '\033[39m'],
    'cyan'      : ['\033[36m', '\033[39m'],
    'green'     : ['\033[32m', '\033[39m'],
    'magenta'   : ['\033[35m', '\033[39m'],
    'red'       : ['\033[31m', '\033[39m'],
    'yellow'    : ['\033[33m', '\033[39m']
  };

  function color(str, c) {
    if(isHeadless) {

      if(typeof c === 'string') {
        return styles[c][0] + str + styles[c][1];
      }

      var output = str;
      for(var ci=0;ci<c.length;ci++) {
        output = color(output, c[ci]);
      }
      return output;
    }

    return str;
  }

  function getColorStyle(percentage) {
    var colorStyle = 'yellow';

    if(percentage > 80) {
      colorStyle = 'green';
    } else if (percentage < 70) {
      colorStyle = 'red';
    }

    return colorStyle;
  }

  var totals = {
    totalCovered: 0,
    totalLines: 0
  };

  var summary = [];

  var writeLog = function ( filename,data) {

    var lineTotal = 0;
    var lineCovered = 0;

    var linesMissed = [];

    for(var i=0;i<data.length;i++) {
      if(data[i] !== undefined) {
        if(data[i] > 0) {
          lineCovered++;
        } else {
          linesMissed.push(i);
        }

        lineTotal++;
      }
    }

    var percentage = ((lineCovered/lineTotal)*100).toFixed(2);

    console.log( '\r\n' +
      color(filename + ': ', 'blue') +
      color(lineTotal + ' lines, ', 'blue') +
      color(percentage + '% coverage', getColorStyle(percentage))
    );

    totals.totalCovered += lineCovered;
    totals.totalLines += lineTotal;

    //console.log(data.join('\r\n'));

    var buffer = 5;
    for(var j=0;j<linesMissed.length;j++) {
      var line = linesMissed[j];
      console.log(color('showing lines '+ (line-buffer) + ' to '+ (line+buffer), 'bold'));
      console.log(color('--------------------------------------------------', 'bold'));

      for(var x=(line-buffer-1);x<(line+buffer);x++) {
        if(x === line-1) {
          console.warn(color('>> '+x+': '+data.source[x], ['red', 'inverse']));
        } else {
          console.log('   '+x+': '+data.source[x]);
        }
      }

    }

    summary.push(color(filename + ': ' + lineTotal + ' lines, ' + percentage + '% coverage', getColorStyle(percentage)));

  };

  var writeStats = function (stats) {
    for (var key in stats) {
      console.log(key+': '+stats[key]);
    }
  };

  return function(coverageData){

    console.log('\r\n\r\n'+color('QUnit Code Coverage', 'yellow'));

    writeStats(coverageData.stats);

    for (var filename in coverageData.files) {
      var data = coverageData.files[filename];
      writeLog(filename,data);
    }

    var percentage = ((totals.totalCovered/totals.totalLines)*100).toFixed(2);

    console.log('\r\n');

    for(var i=0;i<summary.length;i++) {
      console.log(summary[i]);
    }

    console.log(color('Total coverage: ', 'bold') + color(percentage +'%', getColorStyle(percentage)) + '\r\n');
  };
});<commit_msg>Added comment for where styles object came from<commit_after>define([],function meltreporter(){

  var isHeadless = false;

  if(window.navigator.userAgent.match(/PhantomJS/)) {
    isHeadless = true;
  }

  // Borrowed from colors.js by marak: https://github.com/Marak/colors.js/blob/master/colors.js#L61
  var styles = {
    //styles
    'bold'      : ['\033[1m',  '\033[22m'],
    'italic'    : ['\033[3m',  '\033[23m'],
    'underline' : ['\033[4m',  '\033[24m'],
    'inverse'   : ['\033[7m',  '\033[27m'],
    //grayscale
    'white'     : ['\033[37m', '\033[39m'],
    'grey'      : ['\033[90m', '\033[39m'],
    'black'     : ['\033[30m', '\033[39m'],
    //colors
    'blue'      : ['\033[34m', '\033[39m'],
    'cyan'      : ['\033[36m', '\033[39m'],
    'green'     : ['\033[32m', '\033[39m'],
    'magenta'   : ['\033[35m', '\033[39m'],
    'red'       : ['\033[31m', '\033[39m'],
    'yellow'    : ['\033[33m', '\033[39m']
  };

  function color(str, c) {
    if(isHeadless) {

      if(typeof c === 'string') {
        return styles[c][0] + str + styles[c][1];
      }

      var output = str;
      for(var ci=0;ci<c.length;ci++) {
        output = color(output, c[ci]);
      }
      return output;
    }

    return str;
  }

  function getColorStyle(percentage) {
    var colorStyle = 'yellow';

    if(percentage > 80) {
      colorStyle = 'green';
    } else if (percentage < 70) {
      colorStyle = 'red';
    }

    return colorStyle;
  }

  var totals = {
    totalCovered: 0,
    totalLines: 0
  };

  var summary = [];

  var writeLog = function ( filename,data) {

    var lineTotal = 0;
    var lineCovered = 0;

    var linesMissed = [];

    for(var i=0;i<data.length;i++) {
      if(data[i] !== undefined) {
        if(data[i] > 0) {
          lineCovered++;
        } else {
          linesMissed.push(i);
        }

        lineTotal++;
      }
    }

    var percentage = ((lineCovered/lineTotal)*100).toFixed(2);

    console.log( '\r\n' +
      color(filename + ': ', 'blue') +
      color(lineTotal + ' lines, ', 'blue') +
      color(percentage + '% coverage', getColorStyle(percentage))
    );

    totals.totalCovered += lineCovered;
    totals.totalLines += lineTotal;

    //console.log(data.join('\r\n'));

    var buffer = 5;
    for(var j=0;j<linesMissed.length;j++) {
      var line = linesMissed[j];
      console.log(color('showing lines '+ (line-buffer) + ' to '+ (line+buffer), 'bold'));
      console.log(color('--------------------------------------------------', 'bold'));

      for(var x=(line-buffer-1);x<(line+buffer);x++) {
        if(x === line-1) {
          console.warn(color('>> '+x+': '+data.source[x], ['red', 'inverse']));
        } else {
          console.log('   '+x+': '+data.source[x]);
        }
      }

    }

    summary.push(color(filename + ': ' + lineTotal + ' lines, ' + percentage + '% coverage', getColorStyle(percentage)));

  };

  var writeStats = function (stats) {
    for (var key in stats) {
      console.log(key+': '+stats[key]);
    }
  };

  return function(coverageData){

    console.log('\r\n\r\n'+color('QUnit Code Coverage', 'yellow'));

    writeStats(coverageData.stats);

    for (var filename in coverageData.files) {
      var data = coverageData.files[filename];
      writeLog(filename,data);
    }

    var percentage = ((totals.totalCovered/totals.totalLines)*100).toFixed(2);

    console.log('\r\n');

    for(var i=0;i<summary.length;i++) {
      console.log(summary[i]);
    }

    console.log(color('Total coverage: ', 'bold') + color(percentage +'%', getColorStyle(percentage)) + '\r\n');
  };
});
<|endoftext|>


<commit_before>"use strict";

var path = require("path"),

    sepRegex = /\\/g;

// Get a relative version of an absolute path w/ cross-platform/URL-friendly
// directory separators
module.exports = function(files) {
    var cwd = process.cwd();

    return files.map((file) =>
        path.relative(cwd, file).replace(sepRegex, "/")
    );
};
<commit_msg>refactor: modern JSisms<commit_after>"use strict";

const path = require("path");

const sepRegex = /\\/g;

// Get a relative version of an absolute path w/ cross-platform/URL-friendly
// directory separators
module.exports = function(files) {
    var cwd = process.cwd();

    return files.map((file) =>
        path.relative(cwd, file).replace(sepRegex, "/")
    );
};
<|endoftext|>


<commit_before>dojo.provide("dijit.util.PopupManager");

dojo.require("dijit.util.BackgroundIframe");
dojo.require("dijit.util.FocusManager");
dojo.require("dijit.util.place");
dojo.require("dijit.util.window");

dijit.util.PopupManager = new function(){
	// summary:
	//		This class is used to show/hide popups.
	//
	//		The widget must implement a close() callback, which is called when someone
	//		clicks somewhere random on the screen.  It will hide the [chain of] context menus

	var stack = [];
	var beginZIndex=1000;

	this.open = function(/*Event*/ e, /*Widget*/widget, /*Object*/ padding){
		// summary:
		//		Open the widget at mouse position
		//		TODO: if widget has href, attach to onLoaded() and reposition

		var x = e.pageX, y = e.pageY;
		var win = dijit.util.window.getDocumentWindow(e.target.ownerDocument);
		var iframe = win._frameElement || win.frameElement;
		if(iframe){
			var cood = dojo.coords(iframe, true);
			x += cood.x - dojo.withGlobal(win, dijit.util.getScroll).left;
			y += cood.y - dojo.withGlobal(win, dijit.util.getScroll).top;
		}
		dijit.util.placeOnScreen(widget.domNode, x, y, padding, true);

		_open(widget);
	}

	this.openAround = function(/*Widget*/parent, /*Widget*/widget, /*String?*/orient, /*Array?*/padding){
		// summary:
		//		Open the widget relative to parent widget (typically as a drop down to that widget)
		//		TODO: if widget has href attach to onLoaded and reposition

		dijit.util.placeOnScreenAroundElement(widget.domNode, parent, padding, orient);

		_open(widget);
	};

	function _open(widget){
		// summary:
		//		Utility function to help opening

		// display temporarily, and move into position, then hide again
		with(widget.domNode.style){
			zIndex = beginZIndex + stack.length;
			position = "absolute";
		}

		if(stack.length == 0){
			beforeTopOpen(null, widget);
		}

		stack.push(widget);

		// TODO: use effects
		dojo.style(widget.domNode, "display", "");

		if(dojo.isIE && dojo.isIE < 7){
			if(!widget.bgIframe){
				widget.bgIframe = new dijit.util.BackgroundIframe();
				widget.bgIframe.setZIndex(widget.domNode);
			}
			widget.bgIframe.size(widget.domNode);
			widget.bgIframe.show();
		}

	};

	this.close = function(){
		// summary:
		//		Close top level popup

		var widget = stack.pop();

		dojo.style(widget.domNode, "display", "none");
		if(dojo.isIE && dojo.isIE < 7){
			widget.bgIframe.hide();
		}

		if(stack.length == 0){
			afterTopClose(widget);
		}
	};

	///////////////////////////////////////////////////////////////////////
	// Utility functions for making mouse click close popup chain
	var currentTrigger;

	function beforeTopOpen(/*Widget*/ button, /*Widget*/menu){
		// summary:
		//	Called when a popup is opened, typically a button opening a menu.
		//	Registers handlers so that clicking somewhere else on the screen will close the popup

		// TODO: should do this at every level of popup?
		dijit.util.FocusManager.save(menu);

		currentTrigger=button;

		// setup handlers to catch screen clicks and close current menu
		setWindowEvents("connect");
	};

	function afterTopClose(/*Widget*/menu){
		// summary:
		//	called when the top level popup is closed, but before it performs it's actions
		//	removes handlers for mouse movement detection

		// remove handlers to catch screen clicks and close current menu
		// TODO: this doesn't seem to have any effect; try it after scott's new event code.
		setWindowEvents("disconnect");

		currentTrigger = null;

		dijit.util.FocusManager.restore(menu);
	};

	function onKeyPress(/*Event*/e){
		// summary
		//	Handles keystrokes, passing them up the chain of menus
		if(!e.keyCode){ return; }
		if(stack.length==0){ return; }

		// loop from child menu up ancestor chain, ending at button that spawned the menu
		var m = stack[stack.length-1];
		while(m){
			if(m.processKey(e)){
				e.preventDefault();
				e.stopPropagation();
				break;
			}
			m = m.parentPopup || m.parentMenu;
		}
	};

	function onMouse(/*Event*/e){
		// summary
		// Monitor clicks in the screen.  If popup has requested it than
		// clicking anywhere on the screen will close the current menu hierarchy

		if(stack.length==0){ return; }

		//PORT from dojo.dom.isDescendantOf
		var isDescendantOf = function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				node = node.parentNode;
			}
			return false; // boolean
		}

		// if they clicked on the trigger node (often a button), ignore the click
		if(currentTrigger && isDescendantOf(e.target, currentTrigger)){
			return;
		}

		// if they clicked on the popup itself then ignore it
		if(dojo.some(stack, function(widget){
			return isDescendantOf(e.target, widget.domNode);
		}))
		{
			return;
		}

		// the click didn't fall within the open menu tree so close it
		stack[0].close(true);
	};

	function setWindowEvents(/*String*/ command, /*Window*/targetWindow){
		// summary:
		//		This function connects or disconnects listeners on all the iframes
		//		and the top window, so that whereever the user clicks in the page,
		//		the popup menu will be closed

		if(!targetWindow){ //see comment below
			targetWindow = dijit.util.window.getDocumentWindow(window.top && window.top.document || window.document);
		}

		if(command == 'connect'){
			targetWindow._onmousedownhandler = dojo.connect(targetWindow.document, "onmousedown", null, onMouse);
			targetWindow._onscrollhandler = dojo.connect(targetWindow, "onscroll", null, onMouse);
			targetWindow._onkeyhandler = dojo.connect(targetWindow.document, "onkeypress", null, onKeyPress);
		}else{
			dojo.disconnect(targetWindow._onmousedownhandler);
			targetWindow._onmousedownhandler = null;
			dojo.disconnect(targetWindow._onscrollhandler);
			targetWindow._onscrollhandler = null;
			dojo.disconnect(targetWindow._onkeyhandler);
			targetWindow._onkeyhandler = null;
		}

		for(var i = 0; i < targetWindow.frames.length; i++){
			try{
				//do not remove dijit.util.window.getDocumentWindow, see comment in it
				var win = dijit.util.window.getDocumentWindow(targetWindow.frames[i].document);
				if(win){
					setWindowEvents(command, win);
				}
			}catch(e){ /* squelch error for cross domain iframes */ }
		}
	};
	dojo.addOnUnload(function(){ setWindowEvents("disconnect"); });
}();<commit_msg>Generally ensure Shift-F10 triggers context menu "open" on IE/FF (and Opera) under various circumstances. Refs #2695.<commit_after>dojo.provide("dijit.util.PopupManager");

dojo.require("dijit.util.BackgroundIframe");
dojo.require("dijit.util.FocusManager");
dojo.require("dijit.util.place");
dojo.require("dijit.util.window");

dijit.util.PopupManager = new function(){
	// summary:
	//		This class is used to show/hide popups.
	//
	//		The widget must implement a close() callback, which is called when someone
	//		clicks somewhere random on the screen.  It will hide the [chain of] context menus

	var stack = [];
	var beginZIndex=1000;

	this.open = function(/*Event*/ e, /*Widget*/widget, /*Object*/ padding){
		// summary:
		//		Open the widget at mouse position
		//		TODO: if widget has href, attach to onLoaded() and reposition

		var x = e.pageX, y = e.pageY;
		// FIXME: consider skipping everything up to _open
		// if x == y == 0, allowing the popup to appear
		// wherever it was last time.
		var win = dijit.util.window.getDocumentWindow(e.target.ownerDocument);
		var iframe = win._frameElement || win.frameElement;
		if(iframe){
			var cood = dojo.coords(iframe, true);
			x += cood.x - dojo.withGlobal(win, dijit.util.getScroll).left;
			y += cood.y - dojo.withGlobal(win, dijit.util.getScroll).top;
		}
		dijit.util.placeOnScreen(widget.domNode, x, y, padding, true);

		_open(widget);
	}

	this.openAround = function(/*Widget*/parent, /*Widget*/widget, /*String?*/orient, /*Array?*/padding){
		// summary:
		//		Open the widget relative to parent widget (typically as a drop down to that widget)
		//		TODO: if widget has href attach to onLoaded and reposition

		dijit.util.placeOnScreenAroundElement(widget.domNode, parent, padding, orient);

		_open(widget);
	};

	function _open(widget){
		// summary:
		//		Utility function to help opening

		// display temporarily, and move into position, then hide again
		with(widget.domNode.style){
			zIndex = beginZIndex + stack.length;
			position = "absolute";
		}

		if(stack.length == 0){
			beforeTopOpen(null, widget);
		}

		stack.push(widget);

		// TODO: use effects
		dojo.style(widget.domNode, "display", "");

		if(dojo.isIE && dojo.isIE < 7){
			if(!widget.bgIframe){
				widget.bgIframe = new dijit.util.BackgroundIframe();
				widget.bgIframe.setZIndex(widget.domNode);
			}
			widget.bgIframe.size(widget.domNode);
			widget.bgIframe.show();
		}

	};

	this.close = function(){
		// summary:
		//		Close top level popup

		var widget = stack.pop();

		dojo.style(widget.domNode, "display", "none");
		if(dojo.isIE && dojo.isIE < 7){
			widget.bgIframe.hide();
		}

		if(stack.length == 0){
			afterTopClose(widget);
		}
	};

	///////////////////////////////////////////////////////////////////////
	// Utility functions for making mouse click close popup chain
	var currentTrigger;

	function beforeTopOpen(/*Widget*/ button, /*Widget*/menu){
		// summary:
		//	Called when a popup is opened, typically a button opening a menu.
		//	Registers handlers so that clicking somewhere else on the screen will close the popup

		// TODO: should do this at every level of popup?
		dijit.util.FocusManager.save(menu);

		currentTrigger=button;

		// setup handlers to catch screen clicks and close current menu
		setWindowEvents("connect");
	};

	function afterTopClose(/*Widget*/menu){
		// summary:
		//	called when the top level popup is closed, but before it performs it's actions
		//	removes handlers for mouse movement detection

		// remove handlers to catch screen clicks and close current menu
		// TODO: this doesn't seem to have any effect; try it after scott's new event code.
		setWindowEvents("disconnect");

		currentTrigger = null;

		dijit.util.FocusManager.restore(menu);
	};

	function onKeyPress(/*Event*/e){
		// summary
		//	Handles keystrokes, passing them up the chain of menus
		if(!e.keyCode){ return; }
		if(stack.length==0){ return; }

		// loop from child menu up ancestor chain, ending at button that spawned the menu
		var m = stack[stack.length-1];
		while(m){
			if(m.processKey(e)){
				e.preventDefault();
				e.stopPropagation();
				break;
			}
			m = m.parentPopup || m.parentMenu;
		}
	};

	function onMouse(/*Event*/e){
		// summary
		// Monitor clicks in the screen.  If popup has requested it than
		// clicking anywhere on the screen will close the current menu hierarchy

		if(stack.length==0){ return; }

		//PORT from dojo.dom.isDescendantOf
		var isDescendantOf = function(/*Node*/node, /*Node*/ancestor){
			//	summary
			//	Returns boolean if node is a descendant of ancestor
			// guaranteeDescendant allows us to be a "true" isDescendantOf function

			while(node){
				if(node === ancestor){
					return true; // boolean
				}
				node = node.parentNode;
			}
			return false; // boolean
		}

		// if they clicked on the trigger node (often a button), ignore the click
		if(currentTrigger && isDescendantOf(e.target, currentTrigger)){
			return;
		}

		// if they clicked on the popup itself then ignore it
		if(dojo.some(stack, function(widget){
			return isDescendantOf(e.target, widget.domNode);
		}))
		{
			return;
		}

		// the click didn't fall within the open menu tree so close it
		stack[0].close(true);
	};

	function setWindowEvents(/*String*/ command, /*Window*/targetWindow){
		// summary:
		//		This function connects or disconnects listeners on all the iframes
		//		and the top window, so that whereever the user clicks in the page,
		//		the popup menu will be closed

		if(!targetWindow){ //see comment below
			targetWindow = dijit.util.window.getDocumentWindow(window.top && window.top.document || window.document);
		}

		if(command == 'connect'){
			targetWindow._onmousedownhandler = dojo.connect(targetWindow.document, "onmousedown", null, onMouse);
			targetWindow._onscrollhandler = dojo.connect(targetWindow, "onscroll", null, onMouse);
			targetWindow._onkeyhandler = dojo.connect(targetWindow.document, "onkeypress", null, onKeyPress);
		}else{
			dojo.disconnect(targetWindow._onmousedownhandler);
			targetWindow._onmousedownhandler = null;
			dojo.disconnect(targetWindow._onscrollhandler);
			targetWindow._onscrollhandler = null;
			dojo.disconnect(targetWindow._onkeyhandler);
			targetWindow._onkeyhandler = null;
		}

		for(var i = 0; i < targetWindow.frames.length; i++){
			try{
				//do not remove dijit.util.window.getDocumentWindow, see comment in it
				var win = dijit.util.window.getDocumentWindow(targetWindow.frames[i].document);
				if(win){
					setWindowEvents(command, win);
				}
			}catch(e){ /* squelch error for cross domain iframes */ }
		}
	};
	dojo.addOnUnload(function(){ setWindowEvents("disconnect"); });
}();<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const gulp = require('gulp');
const sass = require('gulp-sass');
const buffer = require('vinyl-buffer');
const spritesmith = require('gulp-spritesmith');
const imagemin = require('gulp-imagemin');
const pngquant = require('imagemin-pngquant');

const spritesPath = path.join(__dirname, 'src/assets/sprites');

let spritesArr = [];

(function collectSpritesTask(dir) {
    let filesList = [];

    fs.readdirSync(dir).forEach((name) => {
        const spritesFile = path.join(spritesPath, `${name}`);
        const stats = fs.lstatSync(spritesFile);
        if (stats.isFile() && /png^/.test(name)) {
            filesList.push(spritesFile);
        } else if (stats.isDirectory() && fs.readdirSync(spritesFile).length) {
            const gulpTask = `sprites:${name}`;
            spritesArr.push(gulpTask);
            gulp.task(gulpTask, () => {
                let spritesData =
                    gulp.src(path.join(spritesFile, '*.png'))
                        .pipe(spritesmith({
                            imgName: `${name}_icon.png`,
                            imgPath: `/img/${name}_icon.png`,
                            cssName: `_${name}_icon.scss`,
                        }));
                spritesData.css
                    .pipe(gulp.dest(path.join(__dirname, 'src/assets/css/')));

                spritesData.img
                    .pipe(buffer())
                    .pipe(imagemin({
                        optimizationLevel: 7, // 类型: Number, 默认: 3, 优化等级为: 0 ~ 7
                        use: [pngquant()], // 这里使用 pngquant 深度压缩 png 图片的 imagemin 插件
                    }))
                    .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
            });
        }
    });

    if (filesList.length) {
        gulp.task('sprites:app', () => {
            let spritesData =
                gulp.src(path.join(spritesPath, '*.png'))
                    .pipe(spritesmith({
                        imgName: 'app_icon.png',
                        imgPath: '/img/app_icon.png',
                        cssName: '_app_icon.scss',
                    }));

            spritesData.css
                .pipe(gulp.dest(path.join(__dirname, 'src/assets/css/')));

            spritesData.img
                .pipe(buffer())
                .pipe(imagemin({
                    optimizationLevel: 7, // 类型: Number, 默认: 3, 优化等级为: 0 ~ 7
                    use: [pngquant()], // 这里使用 pngquant 深度压缩 png 图片的 imagemin 插件
                }))
                .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
        });
    }
}(spritesPath));

/**
 * scss:single 不依赖图片的合并
 */
gulp.task('scss:single', () => {
    gulp.src(path.resolve(spritesPath, '../css/*.scss'))
        .pipe(sass({
            outputStyle: 'compressed',
        }).on('error', sass.logError))
        .pipe(gulp.dest(path.join(__dirname, 'static/css/')));
});

gulp.task('watch:scss', () => {
    gulp.watch(path.resolve(__dirname, 'src/assets/css/*.scss', ['scss:single']));
});

gulp.task('scss', ['sprites'], () => {
    gulp.src(path.resolve(spritesPath, '../css/*.scss'))
        .pipe(scss({
            outputStyle: 'compressed',
        }).on('error', sass.logError))
        .pipe(gulp.dest(path.join(__dirname, 'static/css/')));
});

gulp.task('img', () => {
    gulp.src(path.join(__dirname, 'src/assets/img/*.png'))
        .pipe(buffer())
        .pipe(imagemin({
            optimizationLevel: 7,
            use: [pngquant()],
        }))
        .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
});

gulp.task('default', ['sprites', 'scss', 'img']);
<commit_msg>修正gulpfile错误<commit_after>const fs = require('fs');
const path = require('path');
const gulp = require('gulp');
const sass = require('gulp-sass');
const buffer = require('vinyl-buffer');
const spritesmith = require('gulp.spritesmith');
const imagemin = require('gulp-imagemin');
const pngquant = require('imagemin-pngquant');

const spritesPath = path.join(__dirname, 'src/assets/sprites');

let spritesArr = [];

(function collectSpritesTask(dir) {
    let filesList = [];

    fs.readdirSync(dir).forEach((name) => {
        const spritesFile = path.join(spritesPath, `${name}`);
        const stats = fs.lstatSync(spritesFile);
        if (stats.isFile() && /png^/.test(name)) {
            filesList.push(spritesFile);
        } else if (stats.isDirectory() && fs.readdirSync(spritesFile).length) {
            const gulpTask = `sprites:${name}`;
            spritesArr.push(gulpTask);
            gulp.task(gulpTask, () => {
                let spritesData =
                    gulp.src(path.join(spritesFile, '*.png'))
                        .pipe(spritesmith({
                            imgName: `${name}_icon.png`,
                            imgPath: `/img/${name}_icon.png`,
                            cssName: `_${name}_icon.scss`,
                        }));
                spritesData.css
                    .pipe(gulp.dest(path.join(__dirname, 'src/assets/css/')));

                spritesData.img
                    .pipe(buffer())
                    .pipe(imagemin({
                        optimizationLevel: 7, // 类型: Number, 默认: 3, 优化等级为: 0 ~ 7
                        use: [pngquant()], // 这里使用 pngquant 深度压缩 png 图片的 imagemin 插件
                    }))
                    .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
            });
        }
    });

    if (filesList.length) {
        gulp.task('sprites:app', () => {
            let spritesData =
                gulp.src(path.join(spritesPath, '*.png'))
                    .pipe(spritesmith({
                        imgName: 'app_icon.png',
                        imgPath: '/img/app_icon.png',
                        cssName: '_app_icon.scss',
                    }));

            spritesData.css
                .pipe(gulp.dest(path.join(__dirname, 'src/assets/css/')));

            spritesData.img
                .pipe(buffer())
                .pipe(imagemin({
                    optimizationLevel: 7, // 类型: Number, 默认: 3, 优化等级为: 0 ~ 7
                    use: [pngquant()], // 这里使用 pngquant 深度压缩 png 图片的 imagemin 插件
                }))
                .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
        });
    }
}(spritesPath));

/**
 * scss:single 不依赖图片的合并
 */
gulp.task('scss:single', () => {
    gulp.src(path.resolve(spritesPath, '../css/*.scss'))
        .pipe(sass({
            outputStyle: 'compressed',
        }).on('error', sass.logError))
        .pipe(gulp.dest(path.join(__dirname, 'static/css/')));
});

gulp.task('watch:scss', () => {
    gulp.watch(path.resolve(__dirname, 'src/assets/css/*.scss', ['scss:single']));
});

gulp.task('scss', ['sprites'], () => {
    gulp.src(path.resolve(spritesPath, '../css/*.scss'))
        .pipe(sass({
            outputStyle: 'compressed',
        }).on('error', sass.logError))
        .pipe(gulp.dest(path.join(__dirname, 'static/css/')));
});

gulp.task('img', () => {
    gulp.src(path.join(__dirname, 'src/assets/img/*.png'))
        .pipe(buffer())
        .pipe(imagemin({
            optimizationLevel: 7,
            use: [pngquant()],
        }))
        .pipe(gulp.dest(path.join(__dirname, 'static/img/')));
});

gulp.task('default', ['sprites', 'scss', 'img']);
<|endoftext|>


<commit_before>/*
 * PhantomJS Runner QUnit Plugin 1.1.0
 *
 * PhantomJS binaries: http://phantomjs.org/download.html
 * Requires PhantomJS 1.6+ (1.7+ recommended)
 *
 * Run with:
 *   phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * e.g.
 *   phantomjs runner.js http://localhost/qunit/test/index.html
 */

/*global phantom:false, require:false, console:false, window:false, QUnit:false */

(function() {
	'use strict';

	var url, page, timeout,
		args = require('system').args;

	// arg[0]: scriptName, args[1...]: arguments
	if (args.length < 2 || args.length > 3) {
		console.error('Usage:\n  phantomjs runner.js [url-of-your-qunit-testsuite] [timeout-in-seconds]');
		phantom.exit(1);
	}

	url = args[1];
	page = require('webpage').create();
	if (args[2] !== undefined) {
		timeout = parseInt(args[2], 10);
	}

	// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
	page.onConsoleMessage = function(msg) {
		console.log(msg);
	};

	page.onInitialized = function() {
		page.evaluate(addLogging);
	};

	page.onCallback = function(message) {
		var result,
			failed;

		if (message) {
			if (message.name === 'QUnit.done') {
				result = message.data;
				failed = !result || !result.total || result.failed;

				if (!result.total) {
					console.error('No tests were executed. Are you loading tests asynchronously?');
				}

				phantom.exit(failed ? 1 : 0);
			}
		}
	};

	page.open(url, function(status) {
		if (status !== 'success') {
			console.error('Unable to access network: ' + status);
			phantom.exit(1);
		} else {
			// Cannot do this verification with the 'DOMContentLoaded' handler because it
			// will be too late to attach it if a page does not have any script tags.
			var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); });
			if (qunitMissing) {
				console.error('The `QUnit` object is not present on this page.');
				phantom.exit(1);
			}

			// Set a timeout on the test running, otherwise tests with async problems will hang forever
			if (typeof timeout === 'number') {
				setTimeout(function() {
					console.error('The specified timeout of ' + timeout + ' seconds has expired. Aborting...');
					phantom.exit(1);
				}, timeout * 1000);
			}

			// Do nothing... the callback mechanism will handle everything!
		}
	});

	function addLogging() {
		window.document.addEventListener('DOMContentLoaded', function() {
			var currentTestAssertions = [];

			QUnit.log(function(details) {
				var response;

				// Ignore passing assertions
				if (details.result) {
					return;
				}

				response = details.message || '';

				if (typeof details.expected !== 'undefined') {
					if (response) {
						response += ', ';
					}

					response += 'expected: ' + details.expected + ', but was: ' + details.actual;
				}

				if (details.source) {
					response += "\n" + details.source;
				}

				currentTestAssertions.push('Failed assertion: ' + response);
			});

			QUnit.testDone(function(result) {
				var i,
					len,
					name = '';

				if (result.module) {
					name += result.module + ': ';
				}
				name += result.name;

				if (result.failed) {
					console.log('\n' + 'Test failed: ' + name);

					for (i = 0, len = currentTestAssertions.length; i < len; i++) {
						console.log('    ' + currentTestAssertions[i]);
					}
				}

				currentTestAssertions.length = 0;
			});

			QUnit.done(function(result) {
				console.log('\n' + 'Took ' + result.runtime +  'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');

				if (typeof window.callPhantom === 'function') {
					window.callPhantom({
						'name': 'QUnit.done',
						'data': result
					});
				}
			});
		}, false);
	}
})();<commit_msg>Apply formatting changes.<commit_after>/*
 * PhantomJS Runner QUnit Plugin 1.1.0
 *
 * PhantomJS binaries: http://phantomjs.org/download.html
 * Requires PhantomJS 1.6+ (1.7+ recommended)
 *
 * Run with:
 *   phantomjs runner.js [url-of-your-qunit-testsuite]
 *
 * e.g.
 *   phantomjs runner.js http://localhost/qunit/test/index.html
 */

/*global phantom:false, require:false, console:false, window:false, QUnit:false */

(function () {
    'use strict';

    var url, page, timeout,
        args = require('system').args;

    // arg[0]: scriptName, args[1...]: arguments
    if (args.length < 2 || args.length > 3) {
        console.error('Usage:\n  phantomjs runner.js [url-of-your-qunit-testsuite] [timeout-in-seconds]');
        phantom.exit(1);
    }

    url = args[1];
    page = require('webpage').create();
    if (args[2] !== undefined) {
        timeout = parseInt(args[2], 10);
    }

    // Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
    page.onConsoleMessage = function (msg) {
        console.log(msg);
    };

    page.onInitialized = function () {
        page.evaluate(addLogging);
    };

    page.onCallback = function (message) {
        var result,
            failed;

        if (message) {
            if (message.name === 'QUnit.done') {
                result = message.data;
                failed = !result || !result.total || result.failed;

                if (!result.total) {
                    console.error('No tests were executed. Are you loading tests asynchronously?');
                }

                phantom.exit(failed ? 1 : 0);
            }
        }
    };

    page.open(url, function (status) {
        if (status !== 'success') {
            console.error('Unable to access network: ' + status);
            phantom.exit(1);
        } else {
            // Cannot do this verification with the 'DOMContentLoaded' handler because it
            // will be too late to attach it if a page does not have any script tags.
            var qunitMissing = page.evaluate(function () {
                return (typeof QUnit === 'undefined' || !QUnit);
            });
            if (qunitMissing) {
                console.error('The `QUnit` object is not present on this page.');
                phantom.exit(1);
            }

            // Set a timeout on the test running, otherwise tests with async problems will hang forever
            if (typeof timeout === 'number') {
                setTimeout(function () {
                    console.error('The specified timeout of ' + timeout + ' seconds has expired. Aborting...');
                    phantom.exit(1);
                }, timeout * 1000);
            }

            // Do nothing... the callback mechanism will handle everything!
        }
    });

    function addLogging() {
        window.document.addEventListener('DOMContentLoaded', function () {
            var currentTestAssertions = [];

            QUnit.log(function (details) {
                var response;

                // Ignore passing assertions
                if (details.result) {
                    return;
                }

                response = details.message || '';

                if (typeof details.expected !== 'undefined') {
                    if (response) {
                        response += ', ';
                    }

                    response += 'expected: ' + details.expected + ', but was: ' + details.actual;
                }

                if (details.source) {
                    response += '\n' + details.source;
                }

                currentTestAssertions.push('Failed assertion: ' + response);
            });

            QUnit.testDone(function (result) {
                var i,
                    len,
                    name = '';

                if (result.module) {
                    name += result.module + ': ';
                }
                name += result.name;

                if (result.failed) {
                    console.log('\n' + 'Test failed: ' + name);

                    for (i = 0, len = currentTestAssertions.length; i < len; i++) {
                        console.log('    ' + currentTestAssertions[i]);
                    }
                }

                currentTestAssertions.length = 0;
            });

            QUnit.done(function (result) {
                console.log('\n' + 'Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');

                if (typeof window.callPhantom === 'function') {
                    window.callPhantom({
                        'name': 'QUnit.done',
                        'data': result
                    });
                }
            });
        }, false);
    }
})();
<|endoftext|>


<commit_before>'use strict';

function checkActive(plugin, path) {
  var checked = plugin.id;
  if (checked === 'processes') {
    checked = 'process';
  }
  return path.indexOf(plugin.id) > -1;
}

module.exports = [
  '$scope',
  '$location',
  'Views',
function($scope, $location, Views) {
  $scope.navbarVars = { read: [] };
  $scope.navbarActions = Views.getProviders({ component: 'cockpit.dashboard.section' });
  $scope.activeClass = function(plugin) {
    var path = $location.absUrl();
    return (typeof plugin.checkActive === 'function' ?
                plugin.checkActive(path) :
                checkActive(plugin, path)) ? 'active' : '';
  };
}];
<commit_msg>refactor(navigation): remove dead code<commit_after>'use strict';

function checkActive(plugin, path) {
  return path.indexOf(plugin.id) > -1;
}

module.exports = [
  '$scope',
  '$location',
  'Views',
function($scope, $location, Views) {
  $scope.navbarVars = { read: [] };
  $scope.navbarActions = Views.getProviders({ component: 'cockpit.dashboard.section' });
  $scope.activeClass = function(plugin) {
    var path = $location.absUrl();
    return (typeof plugin.checkActive === 'function' ?
                plugin.checkActive(path) :
                checkActive(plugin, path)) ? 'active' : '';
  };
}];
<|endoftext|>