<commit_before>/* eslint-disable max-lines */

var db = require('tresdb-db');
var io = require('../../services/io');
var proj = require('../../services/proj');

// Private methods

var timestamp = function () {
  return (new Date()).toISOString();
};

var emitOne = function (ev) {
  if (!ev.hasOwnProperty('_id')) {
    throw new Error('Event must have a _id before emitting');
  }

  io.get().emit('tresdb_event', ev);
};

var insertOne = function (ev, callback) {
  // Parameters:
  //   ev
  //     event object to insert
  //   callback
  //     function (err, eventId);
  var coll = db.get().collection('events');

  coll.insertOne(ev, function (err, result) {
    if (err) {
      return callback(err);
    }
    return callback(null, result.insertedId);
  });
};

var insertAndEmit = function (ev, callback) {
  // Parameters:
  //   ev
  //     event object to insert and emit after insertion. Ev is given a _id.
  //   callback
  //     function (err)
  //
  insertOne(ev, function (err, newId) {
    if (err) {
      return callback(err);
    }
    ev._id = newId;
    emitOne(ev);
    return callback(null);
  });
};

// Public methods

exports.createLocationCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //       ObjectId, location id
  //     locationName
  //     lat
  //     lng
  //       float
  //     username
  //       string
  //   callback
  //     function (err);

  var newEvent = {
    type: 'location_created',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      lat: params.lat,
      lng: params.lng,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     oldEntry
  //       raw entry object
  //     locationName
  //       string
  //     markdown
  //       string or null
  //     isVisit
  //       boolean
  //     filepath
  //       string or null
  //       The relative path of the file in the uploads dir
  //     mimetype
  //       string or null
  //     thumbfilepath
  //       string or null
  //       The relative path of the thumbnail file in the uploads dir
  //     thumbmimetype
  //       string or null

  if (typeof params.oldEntry._id !== 'object') {
    throw new Error('invalid entryId type');
  }

  var newEvent = {
    type: 'location_entry_changed',
    user: params.oldEntry.user,
    time: timestamp(),
    locationId: params.oldEntry.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.oldEntry._id,
      oldMarkdown: params.oldEntry.data.markdown,
      newMarkdown: params.markdown,
      oldIsVisit: params.oldEntry.data.isVisit,
      newIsVisit: params.isVisit,
      oldFilepath: params.oldEntry.data.filepath,
      newFilepath: params.filepath,
      oldMimetype: params.oldEntry.data.mimetype,
      newMimetype: params.mimetype,
      oldThumbfilepath: params.oldEntry.data.thumbfilepath,
      newThumbfilepath: params.thumbfilepath,
      oldThumbmimetype: params.oldEntry.data.thumbmimetype,
      newThumbmimetype: params.thumbmimetype,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //     markdown
  //       string or null
  //     isVisit
  //       boolean
  //     filepath
  //       string or null
  //       The relative path of the file in the uploads dir
  //     mimetype
  //       string or null
  //     thumbfilepath
  //       string or null
  //       The relative path of the thumbnail file in the uploads dir
  //     thumbmimetype
  //       string or null
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_created',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      markdown: params.markdown,
      isVisit: params.isVisit,
      filepath: params.filepath,
      mimetype: params.mimetype,
      thumbfilepath: params.thumbfilepath,
      thumbmimetype: params.thumbmimetype,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_removed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //     commentId
  //     time
  //     message
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_created',
    user: params.username,
    time: params.time,
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
      message: params.message,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     username
  //     locationId
  //     locationName
  //     entryId
  //     commentId
  //     newMessage
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
      newMessage: params.newMessage,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     username
  //     locationId
  //     locationName
  //     entryId
  //     commentId
  //     commentUsername
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_removed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationGeomChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newGeom
  //       GeoJSON Point
  //     oldGeom
  //       GeoJSON Point

  var newEvent = {
    type: 'location_geom_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newGeom: params.newGeom,
      oldGeom: params.oldGeom,
    },
  };

  // Insert the basic version and emit an extended version with alt coords.
  // The alt coords are needed in client.
  insertOne(newEvent, function (err, newId) {
    if (err) {
      return callback(err);
    }
    newEvent._id = newId;
    // Compute additional coodinate systems
    var newAltGeom = proj.getAltPositions(params.newGeom.coordinates);
    newEvent.data.newAltGeom = newAltGeom;
    // Emit the extended version.
    emitOne(newEvent);
    return callback(null);
  });
};

exports.createLocationNameChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newName
  //       string
  //     oldName
  //       string

  var newEvent = {
    type: 'location_name_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newName: params.newName,
      oldName: params.oldName,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationStatusChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newStatus
  //       string
  //     oldStatus
  //       string

  var newEvent = {
    type: 'location_status_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newStatus: params.newStatus,
      oldStatus: params.oldStatus,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationTypeChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newType
  //       string
  //     oldType
  //       string

  var newEvent = {
    type: 'location_type_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newType: params.newType,
      oldType: params.oldType,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //       ObjectId, location id
  //     locationName
  //       string
  //     username
  //       string
  //   callback
  //     function (err);

  var newEvent = {
    type: 'location_removed',
    user: params.username,
    time: (new Date()).toISOString(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {},
  };

  insertAndEmit(newEvent, callback);
};

exports.getAllOfUser = function (username, callback) {
  // Parameters
  //   username
  //     string
  //   callback
  //     function (err, events)

  var coll = db.collection('events');

  coll.find({ user: username }).toArray(callback);
};

exports.getAllOfLocation = function (locationId, callback) {
  // Parameters:
  //   locationId
  //   callback
  //     function (err, events)
  db.collection('events').find({ locationId: locationId }).toArray(callback);
};

exports.getRecent = function (n, beforeTime, callback) {
  // Parameters
  //   n
  //     number of events to return
  //   beforeTime
  //     time as ISOString
  //   callback
  //     function (err, events)
  return exports.getRecentFiltered({}, n, beforeTime, callback);
};

exports.getRecentOfUser = function (username, n, beforeTime, callback) {
  var filter = { user: username };
  return exports.getRecentFiltered(filter, n, beforeTime, callback);
};

exports.getRecentFiltered = function (filter, n, beforeTime, callback) {
  // Parameters
  //   filter
  //     the value of $match operator. See
  //     https://docs.mongodb.com/manual/reference/operator/aggregation/match/
  //     Use {} to filter nothing.
  //   n
  //     number of events to return
  //   beforeTime
  //     time as ISOString. Only events before this time are selected.
  //   callback
  //     function (err, events)

  var eventsColl = db.get().collection('events');

  eventsColl.aggregate([
    {
      $match: filter,
    },
    {
      $sort: {
        time: -1,
      },
    },
    {
      // Filter out the events with time after or equal to beforeTime
      $match: {
        time: {
          $lt: beforeTime,
        },
      },
    },
    {
      // Specify last document to return
      $limit: n,
    },
    // {
    //   // Join with location data
    //   $lookup: {
    //     from: 'locations',
    //     localField: 'locationId',
    //     foreignField: '_id',
    //     as: 'location',
    //   },
    // },
    // {
    //   // Change the location array to the single location (the first item).
    //   $unwind: '$location',
    // },
  ]).toArray(function (err, docs) {
    if (err) {
      return callback(err);
    }
    return callback(null, docs);
  });
};
<commit_msg>Improve comments<commit_after>/* eslint-disable max-lines */
//
// Location events
//

var db = require('tresdb-db');
var io = require('../../services/io');
var proj = require('../../services/proj');

// Private methods

var timestamp = function () {
  return (new Date()).toISOString();
};

var emitOne = function (ev) {
  if (!ev.hasOwnProperty('_id')) {
    throw new Error('Event must have a _id before emitting');
  }

  io.get().emit('tresdb_event', ev);
};

var insertOne = function (ev, callback) {
  // Parameters:
  //   ev
  //     event object to insert
  //   callback
  //     function (err, eventId);
  var coll = db.get().collection('events');

  coll.insertOne(ev, function (err, result) {
    if (err) {
      return callback(err);
    }
    return callback(null, result.insertedId);
  });
};

var insertAndEmit = function (ev, callback) {
  // Parameters:
  //   ev
  //     event object to insert and emit after insertion. Ev is given a _id.
  //   callback
  //     function (err)
  //
  insertOne(ev, function (err, newId) {
    if (err) {
      return callback(err);
    }
    ev._id = newId;
    emitOne(ev);
    return callback(null);
  });
};

// Public methods

exports.createLocationCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //       ObjectId, location id
  //     locationName
  //     lat
  //     lng
  //       float
  //     username
  //       string
  //   callback
  //     function (err);

  var newEvent = {
    type: 'location_created',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      lat: params.lat,
      lng: params.lng,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     oldEntry
  //       raw entry object
  //     locationName
  //       string
  //     markdown
  //       string or null
  //     isVisit
  //       boolean
  //     filepath
  //       string or null
  //       The relative path of the file in the uploads dir
  //     mimetype
  //       string or null
  //     thumbfilepath
  //       string or null
  //       The relative path of the thumbnail file in the uploads dir
  //     thumbmimetype
  //       string or null

  if (typeof params.oldEntry._id !== 'object') {
    throw new Error('invalid entryId type');
  }

  var newEvent = {
    type: 'location_entry_changed',
    user: params.oldEntry.user,
    time: timestamp(),
    locationId: params.oldEntry.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.oldEntry._id,
      oldMarkdown: params.oldEntry.data.markdown,
      newMarkdown: params.markdown,
      oldIsVisit: params.oldEntry.data.isVisit,
      newIsVisit: params.isVisit,
      oldFilepath: params.oldEntry.data.filepath,
      newFilepath: params.filepath,
      oldMimetype: params.oldEntry.data.mimetype,
      newMimetype: params.mimetype,
      oldThumbfilepath: params.oldEntry.data.thumbfilepath,
      newThumbfilepath: params.thumbfilepath,
      oldThumbmimetype: params.oldEntry.data.thumbmimetype,
      newThumbmimetype: params.thumbmimetype,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //     markdown
  //       string or null
  //     isVisit
  //       boolean
  //     filepath
  //       string or null
  //       The relative path of the file in the uploads dir
  //     mimetype
  //       string or null
  //     thumbfilepath
  //       string or null
  //       The relative path of the thumbnail file in the uploads dir
  //     thumbmimetype
  //       string or null
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_created',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      markdown: params.markdown,
      isVisit: params.isVisit,
      filepath: params.filepath,
      mimetype: params.mimetype,
      thumbfilepath: params.thumbfilepath,
      thumbmimetype: params.thumbmimetype,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_removed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentCreated = function (params, callback) {
  // Parameters:
  //   params:
  //     entryId
  //     locationId
  //     locationName
  //     username
  //     commentId
  //     time
  //     message
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_created',
    user: params.username,
    time: params.time,
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
      message: params.message,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     username
  //     locationId
  //     locationName
  //     entryId
  //     commentId
  //     newMessage
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
      newMessage: params.newMessage,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationEntryCommentRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     username
  //     locationId
  //     locationName
  //     entryId
  //     commentId
  //     commentUsername
  //   callback
  //     function (err)

  var newEvent = {
    type: 'location_entry_comment_removed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      entryId: params.entryId,
      commentId: params.commentId,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationGeomChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newGeom
  //       GeoJSON Point
  //     oldGeom
  //       GeoJSON Point

  var newEvent = {
    type: 'location_geom_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newGeom: params.newGeom,
      oldGeom: params.oldGeom,
    },
  };

  // Insert the basic version and emit an extended version with alt coords.
  // The alt coords are needed in client.
  insertOne(newEvent, function (err, newId) {
    if (err) {
      return callback(err);
    }
    newEvent._id = newId;
    // Compute additional coodinate systems
    var newAltGeom = proj.getAltPositions(params.newGeom.coordinates);
    newEvent.data.newAltGeom = newAltGeom;
    // Emit the extended version.
    emitOne(newEvent);
    return callback(null);
  });
};

exports.createLocationNameChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newName
  //       string
  //     oldName
  //       string

  var newEvent = {
    type: 'location_name_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newName: params.newName,
      oldName: params.oldName,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationStatusChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newStatus
  //       string
  //     oldStatus
  //       string

  var newEvent = {
    type: 'location_status_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newStatus: params.newStatus,
      oldStatus: params.oldStatus,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationTypeChanged = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //     locationName
  //     username
  //     newType
  //       string
  //     oldType
  //       string

  var newEvent = {
    type: 'location_type_changed',
    user: params.username,
    time: timestamp(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {
      newType: params.newType,
      oldType: params.oldType,
    },
  };

  insertAndEmit(newEvent, callback);
};

exports.createLocationRemoved = function (params, callback) {
  // Parameters:
  //   params:
  //     locationId
  //       ObjectId, location id
  //     locationName
  //       string
  //     username
  //       string
  //   callback
  //     function (err);

  var newEvent = {
    type: 'location_removed',
    user: params.username,
    time: (new Date()).toISOString(),
    locationId: params.locationId,
    locationName: params.locationName,
    data: {},
  };

  insertAndEmit(newEvent, callback);
};

exports.getAllOfUser = function (username, callback) {
  // Parameters
  //   username
  //     string
  //   callback
  //     function (err, events)

  var coll = db.collection('events');

  coll.find({ user: username }).toArray(callback);
};

exports.getAllOfLocation = function (locationId, callback) {
  // Parameters:
  //   locationId
  //   callback
  //     function (err, events)
  db.collection('events').find({ locationId: locationId }).toArray(callback);
};

exports.getRecent = function (n, beforeTime, callback) {
  // Parameters
  //   n
  //     number of events to return
  //   beforeTime
  //     time as ISOString
  //   callback
  //     function (err, events)
  return exports.getRecentFiltered({}, n, beforeTime, callback);
};

exports.getRecentOfUser = function (username, n, beforeTime, callback) {
  var filter = { user: username };
  return exports.getRecentFiltered(filter, n, beforeTime, callback);
};

exports.getRecentFiltered = function (filter, n, beforeTime, callback) {
  // Parameters
  //   filter
  //     the value of $match operator. See
  //     https://docs.mongodb.com/manual/reference/operator/aggregation/match/
  //     Use {} to filter nothing.
  //   n
  //     number of events to return
  //   beforeTime
  //     time as ISOString. Only events before this time are selected.
  //   callback
  //     function (err, events)

  var eventsColl = db.get().collection('events');

  eventsColl.aggregate([
    {
      $match: filter,
    },
    {
      $sort: {
        time: -1,
      },
    },
    {
      // Filter out the events with time after or equal to beforeTime
      $match: {
        time: {
          $lt: beforeTime,
        },
      },
    },
    {
      // Specify last document to return
      $limit: n,
    },
    // {
    //   // Join with location data
    //   $lookup: {
    //     from: 'locations',
    //     localField: 'locationId',
    //     foreignField: '_id',
    //     as: 'location',
    //   },
    // },
    // {
    //   // Change the location array to the single location (the first item).
    //   $unwind: '$location',
    // },
  ]).toArray(function (err, docs) {
    if (err) {
      return callback(err);
    }
    return callback(null, docs);
  });
};
<|endoftext|>


<commit_before>/*
 * Windshaft-CartoDB
 * ===============
 *
 * ./app.js [environment]
 *
 * environments: [development, production]
 */

var cluster = require('cluster');

// sanity check
var ENV = process.argv[2]
if (ENV != 'development' && ENV != 'production'){
    console.error("\nnode app.js [environment]");
    console.error("environments: [development, production]\n");
    process.exit(1);
}

var _ = require('underscore')
    , Step       = require('step')
	, CartodbWindshaft = require('./lib/cartodb/cartodb_windshaft');

// set environment specific variables
global.settings     = require(__dirname + '/config/settings');
global.environment  = require(__dirname + '/config/environments/' + ENV);
_.extend(global.settings, global.environment);

// Include cart_data.js only _after_ the "global" variable is set
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/28
var cartoData = require('./lib/cartodb/carto_data');

var Windshaft = require('windshaft');
var serverOptions = require('./lib/cartodb/server_options');

ws = CartodbWindshaft(serverOptions);
cluster(ws)
  .use(cluster.logger('logs'))
  .use(cluster.stats())
  .use(cluster.pidfiles('pids'))
  .set('workers', 1)
  .listen(global.environment.port, global.environment.host);

console.log("Windshaft tileserver started on port " + global.environment.port);
<commit_msg>added staging to the list of allowed envs<commit_after>/*
 * Windshaft-CartoDB
 * ===============
 *
 * ./app.js [environment]
 *
 * environments: [development, production]
 */

var cluster = require('cluster');

// sanity check
var ENV = process.argv[2]
if (ENV != 'development' && ENV != 'production' && ENV != 'staging'){
    console.error("\nnode app.js [environment]");
    console.error("environments: [development, production, staging]\n");
    process.exit(1);
}

var _ = require('underscore')
    , Step       = require('step')
	, CartodbWindshaft = require('./lib/cartodb/cartodb_windshaft');

// set environment specific variables
global.settings     = require(__dirname + '/config/settings');
global.environment  = require(__dirname + '/config/environments/' + ENV);
_.extend(global.settings, global.environment);

// Include cart_data.js only _after_ the "global" variable is set
// See https://github.com/Vizzuality/Windshaft-cartodb/issues/28
var cartoData = require('./lib/cartodb/carto_data');

var Windshaft = require('windshaft');
var serverOptions = require('./lib/cartodb/server_options');

ws = CartodbWindshaft(serverOptions);
cluster(ws)
  .use(cluster.logger('logs'))
  .use(cluster.stats())
  .use(cluster.pidfiles('pids'))
  .set('workers', 1)
  .listen(global.environment.port, global.environment.host);

console.log("Windshaft tileserver started on port " + global.environment.port);
<|endoftext|>


<commit_before>ZBase.registerView((function() {
  var kPathPrefix = "/a/datastore/tables/";
  var query_mgr;

  var init = function(path) {
    query_mgr = EventSourceHandler();
    load(path);
  };

  var load = function(path) {
    destroy();
    $.showLoader();

    var table_id = path.substr(kPathPrefix.length);
    loadChart(table_id);

    //load schema
    $.httpGet("/api/v1/tables/" + table_id, function(r) {
      if (r.status == 200) {
        render(JSON.parse(r.response).table);
      } else {
        renderError(r.statusText, kPathPrefix + table_id);
      }
      $.hideLoader();
    });
  };

  var destroy = function() {
    if (query_mgr) {
      query_mgr.closeAll();
    }
  };

  var loadChart = function(table_id) {
    //FIXME remove limit
    var query_str =
      "select (TRUNCATE(time / 3600000000) * 3600000) as time, count(*) / 3600 " +
      "as num_inserts from '" + table_id + ".last7d' group by " +
      "TRUNCATE(time / 3600000000) order by time asc limit 3600;";

    var query = query_mgr.get(
      "sql_query",
      "/api/v1/sql?format=json_sse&query=" + encodeURIComponent(query_str));

    query.addEventListener('result', function(e) {
      query_mgr.close("sql_query");

      var data = JSON.parse(e.data);
      renderChart(data.results);
    });

    query.addEventListener('query_error', function(e) {
      query_mgr.close("sql_query");
      console.log("query execution failed");
      renderChartError();
    });

    query.addEventListener('error', function(e) {
      query_mgr.close("sql_query");
      console.log("server error while executing query");
      renderChartError();
    });
  };

  var render = function(schema) {
    var page = $.getTemplate(
        "views/table_overview",
        "zbase_table_overview_main_tpl");

    //set table name
    var table_breadcrumb = $(".table_name_breadcrumb", page);
    table_breadcrumb.innerHTML = schema.name;
    table_breadcrumb.href = kPathPrefix + schema.name;
    $(".pagetitle .table_name", page).innerHTML = schema.name;

    //set tab links
    var tabs = page.querySelectorAll("z-tab a");
    for (var i = 0; i < tabs.length; i++) {
      var link = tabs[i].getAttribute("href");
      tabs[i].setAttribute("href", link + schema.name);
    }

    renderSchemaTable($(".table_schema tbody", page), schema.schema.columns, "");

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderSchemaTable = function(tbody, columns, prefix) {
    columns.forEach(function(column) {
      var tr = document.createElement("tr");
      var column_name = prefix + column.name;
      tr.innerHTML = [
        "", column_name, "	", column.type,
        "	", column.optional, "	"].join("");

      tbody.appendChild(tr);
      if (column.type == "OBJECT") {
        renderSchemaTable(tbody, column.schema.columns, column_name + ".");
      }
    });
  };

  var renderChart = function(data) {
    var x_values = ["x"];
    var y_values = ["inserts"];
    var y_max = 0;

    data[0].rows.forEach(function(row) {
      x_values.push(parseInt(row[0], 10));

      var y_value = parseFloat(row[1]);
      y_values.push(y_value);
      if (y_value > y_max) {
        y_max = y_value;
      }
    });

    hideChartLoader();
    var chart = c3.generate({
      bindto: "#table_overview_chart",
      size: {
        width: $(".zbase_table_overview .inner_chart").offsetWidth
      },
      padding: {
        bottom: 10
      },
      interaction: true,
      data: {
        x: 'x',
        type: "area",
        columns: [
          x_values, y_values
        ],
        colors: {
          "inserts": '#eaf2fa'
        },
        selection: {
          enabled: true
        },
      },
      line: {
        connectNull: false
      },
      axis: {
        x: {
          show: false,
          type: "timeseries",
          padding: {
            left: 0,
            right: 0
          },
          tick: {
            format: "%Y-%m-%d %H:%M:%S",
            count: 10
          }
        },
        y: {
          show: false,
          min: 0,
          tick: {
            count: 3,
            values: [-0.1, (y_max + 10) / 2, y_max + 10]
          }
        }
      },
      legend: {
        show: false
      },
      grid: {
        y: {
          show: true
        }
      },
      point: {
        show: false
      }
    });
  };

  var hideChartLoader = function() {
    $(".zbase_table_overview .chart_container .zbase_loader").classList.add("hidden");
  };

  var renderChartError = function() {
    var error_msg = document.createElement("div");
    error_msg.classList.add("error_msg");
    error_msg.innerHTML = "No data received.";

    $.replaceContent(
      $(".zbase_table_overview .chart_container .inner_chart"),
      error_msg);
  };

  var renderError = function(msg, path) {
    var error_elem = document.createElement("div");
    error_elem.classList.add("zbase_error");
    error_elem.innerHTML =
        "" +
        "
We're sorry
" +
        "
An error occured.

" + msg + "
 " +
        "
Please try it again or contact support if the problem persists.
" +
        "" +
        " Back" +
        "" +
        " Reload" +
        "";

    $.replaceViewport(error_elem);
  };

  return {
    name: "table_overview",
    loadView: function(params) { init(params.path); },
    unloadView: destroy,
    handleNavigationChange: load
  };
})());
<commit_msg>table overview chart with x-axis labels<commit_after>ZBase.registerView((function() {
  var kPathPrefix = "/a/datastore/tables/";
  var query_mgr;

  var init = function(path) {
    query_mgr = EventSourceHandler();
    load(path);
  };

  var load = function(path) {
    destroy();
    $.showLoader();

    var table_id = path.substr(kPathPrefix.length);
    loadChart(table_id);

    //load schema
    $.httpGet("/api/v1/tables/" + table_id, function(r) {
      if (r.status == 200) {
        render(JSON.parse(r.response).table);
      } else {
        renderError(r.statusText, kPathPrefix + table_id);
      }
      $.hideLoader();
    });
  };

  var destroy = function() {
    if (query_mgr) {
      query_mgr.closeAll();
    }
  };

  var loadChart = function(table_id) {
    //FIXME remove limit
    var query_str =
      "select (TRUNCATE(time / 3600000000) * 3600000) as time, count(*) / 3600 " +
      "as num_inserts from '" + table_id + ".last7d' group by " +
      "TRUNCATE(time / 3600000000) order by time asc limit 3600;";

    var query = query_mgr.get(
      "sql_query",
      "/api/v1/sql?format=json_sse&query=" + encodeURIComponent(query_str));

    query.addEventListener('result', function(e) {
      query_mgr.close("sql_query");

      var data = JSON.parse(e.data);
      renderChart(data.results);
    });

    query.addEventListener('query_error', function(e) {
      query_mgr.close("sql_query");
      console.log("query execution failed");
      renderChartError();
    });

    query.addEventListener('error', function(e) {
      query_mgr.close("sql_query");
      console.log("server error while executing query");
      renderChartError();
    });
  };

  var render = function(schema) {
    var page = $.getTemplate(
        "views/table_overview",
        "zbase_table_overview_main_tpl");

    //set table name
    var table_breadcrumb = $(".table_name_breadcrumb", page);
    table_breadcrumb.innerHTML = schema.name;
    table_breadcrumb.href = kPathPrefix + schema.name;
    $(".pagetitle .table_name", page).innerHTML = schema.name;

    //set tab links
    var tabs = page.querySelectorAll("z-tab a");
    for (var i = 0; i < tabs.length; i++) {
      var link = tabs[i].getAttribute("href");
      tabs[i].setAttribute("href", link + schema.name);
    }

    renderSchemaTable($(".table_schema tbody", page), schema.schema.columns, "");

    $.handleLinks(page);
    $.replaceViewport(page);
  };

  var renderSchemaTable = function(tbody, columns, prefix) {
    columns.forEach(function(column) {
      var tr = document.createElement("tr");
      var column_name = prefix + column.name;
      tr.innerHTML = [
        "", column_name, "	", column.type,
        "	", column.optional, "	"].join("");

      tbody.appendChild(tr);
      if (column.type == "OBJECT") {
        renderSchemaTable(tbody, column.schema.columns, column_name + ".");
      }
    });
  };

  var renderChart = function(data) {
    var x_values = ["x"];
    var y_values = ["inserts"];
    var y_max = 0;

    data[0].rows.forEach(function(row) {
      x_values.push(parseInt(row[0], 10));

      var y_value = parseFloat(row[1]);
      y_values.push(y_value);
      if (y_value > y_max) {
        y_max = y_value;
      }
    });

    hideChartLoader();
    var chart = c3.generate({
      bindto: "#table_overview_chart",
      size: {
        width: $(".zbase_table_overview .inner_chart").offsetWidth
      },
      padding: {
        bottom: 10
      },
      interaction: true,
      data: {
        x: 'x',
        type: "area",
        columns: [
          x_values, y_values
        ],
        colors: {
          "inserts": '#eaf2fa'
        },
        selection: {
          enabled: true
        },
      },
      line: {
        connectNull: false
      },
      axis: {
        x: {
          show: true,
          type: "timeseries",
          padding: {
            left: 0,
            right: 0
          },
          tick: {
            format: "%Y-%m-%d",
            count: 10
          }
        },
        y: {
          show: false,
          min: 0,
          tick: {
            count: 3,
            values: [-0.1, (y_max + 10) / 2, y_max + 10]
          }
        }
      },
      tooltip: {
        format: {
          title: function(d) {
            return d3.time.format("%Y-%m-%d %H:%M")(d);
          }
        }
      },
      legend: {
        show: false
      },
      grid: {
        y: {
          show: true
        }
      },
      point: {
        show: false
      }
    });
  };

  var hideChartLoader = function() {
    $(".zbase_table_overview .chart_container .zbase_loader").classList.add("hidden");
  };

  var renderChartError = function() {
    var error_msg = document.createElement("div");
    error_msg.classList.add("error_msg");
    error_msg.innerHTML = "No data received.";

    $.replaceContent(
      $(".zbase_table_overview .chart_container .inner_chart"),
      error_msg);
  };

  var renderError = function(msg, path) {
    var error_elem = document.createElement("div");
    error_elem.classList.add("zbase_error");
    error_elem.innerHTML =
        "" +
        "
We're sorry
" +
        "
An error occured.

" + msg + "
 " +
        "
Please try it again or contact support if the problem persists.
" +
        "" +
        " Back" +
        "" +
        " Reload" +
        "";

    $.replaceViewport(error_elem);
  };

  return {
    name: "table_overview",
    loadView: function(params) { init(params.path); },
    unloadView: destroy,
    handleNavigationChange: load
  };
})());
<|endoftext|>


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

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import { useCallback } from '@wordpress/element';

/**
 * WordPress dependencies
 */
import { __, sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Button from '../../components/Button';
import SurveyHeader from './SurveyHeader';
import SurveyUnhappy from '../../../svg/survey-unhappy.svg';
import SurveyDissatisfied from '../../../svg/survey-dissatisfied.svg';
import SurveyNeutral from '../../../svg/survey-neutral.svg';
import SurveySatisfied from '../../../svg/survey-satisfied.svg';
import SurveyDelighted from '../../../svg/survey-delighted.svg';

const SurveyQuestionRating = ( { question, choices, answerQuestion, dismissSurvey } ) => {
	const getIcon = ( answerOrdinal ) => {
		if ( ! answerOrdinal ) {
			return null;
		}

		switch ( parseInt( answerOrdinal, 10 ) ) {
			case 1:
				return <SurveyUnhappy />;
			case 2:
				return <SurveyDissatisfied />;
			case 3:
				return <SurveyNeutral />;
			case 4:
				return <SurveySatisfied />;
			case 5:
				return <SurveyDelighted />;
		}
	};

	const handleButtonClick = useCallback( ( answer ) => {
		if ( typeof answerQuestion === 'function' ) {
			answerQuestion( answer );
		}
	}, [ answerQuestion ] );

	return (

			<SurveyHeader
				title={ question }
				dismissSurvey={ dismissSurvey }
			/>

					{ choices.map( ( choice, index ) => {
						return (

								<Button
									icon={ getIcon( choice.answer_ordinal ) }
									aria-label={
										sprintf(
											/* translators: %s: Icon Expression */
											__( '%s icon', 'google-site-kit' ),
											choice.text,
										)
									}
									onClick={ handleButtonClick.bind( null, choice.answer_ordinal ) }
								/>

									{ choice.text }

						);
					} ) }

	);
};

SurveyQuestionRating.propTypes = {
	question: PropTypes.string.isRequired,
	choices: PropTypes.arrayOf(
		PropTypes.shape( {
			answer_ordinal: PropTypes.oneOfType( [
				PropTypes.string,
				PropTypes.number,
			] ),
			text: PropTypes.string,
		} ),
	),
	answerQuestion: PropTypes.func,
	dismissSurvey: PropTypes.func,
};

SurveyQuestionRating.defaultProps = {
	choices: [],
	answerQuestion: null,
	dismissSurvey: null,
};

export default SurveyQuestionRating;
<commit_msg>Use implicit return for map function.<commit_after>/**
 * SurveyQuestionRating component.
 *
 * Site Kit by Google, Copyright 2021 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import { useCallback } from '@wordpress/element';

/**
 * WordPress dependencies
 */
import { __, sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Button from '../../components/Button';
import SurveyHeader from './SurveyHeader';
import SurveyUnhappy from '../../../svg/survey-unhappy.svg';
import SurveyDissatisfied from '../../../svg/survey-dissatisfied.svg';
import SurveyNeutral from '../../../svg/survey-neutral.svg';
import SurveySatisfied from '../../../svg/survey-satisfied.svg';
import SurveyDelighted from '../../../svg/survey-delighted.svg';

const SurveyQuestionRating = ( { question, choices, answerQuestion, dismissSurvey } ) => {
	const getIcon = ( answerOrdinal ) => {
		if ( ! answerOrdinal ) {
			return null;
		}

		switch ( parseInt( answerOrdinal, 10 ) ) {
			case 1:
				return <SurveyUnhappy />;
			case 2:
				return <SurveyDissatisfied />;
			case 3:
				return <SurveyNeutral />;
			case 4:
				return <SurveySatisfied />;
			case 5:
				return <SurveyDelighted />;
		}
	};

	const handleButtonClick = useCallback( ( answer ) => {
		if ( typeof answerQuestion === 'function' ) {
			answerQuestion( answer );
		}
	}, [ answerQuestion ] );

	return (

			<SurveyHeader
				title={ question }
				dismissSurvey={ dismissSurvey }
			/>

					{ choices.map( ( choice, index ) => (

							<Button
								icon={ getIcon( choice.answer_ordinal ) }
								aria-label={
									sprintf(
										/* translators: %s: Icon Expression */
										__( '%s icon', 'google-site-kit' ),
										choice.text,
									)
								}
								onClick={ handleButtonClick.bind( null, choice.answer_ordinal ) }
							/>

								{ choice.text }

					) ) }

	);
};

SurveyQuestionRating.propTypes = {
	question: PropTypes.string.isRequired,
	choices: PropTypes.arrayOf(
		PropTypes.shape( {
			answer_ordinal: PropTypes.oneOfType( [
				PropTypes.string,
				PropTypes.number,
			] ),
			text: PropTypes.string,
		} ),
	),
	answerQuestion: PropTypes.func,
	dismissSurvey: PropTypes.func,
};

SurveyQuestionRating.defaultProps = {
	choices: [],
	answerQuestion: null,
	dismissSurvey: null,
};

export default SurveyQuestionRating;
<|endoftext|>


<commit_before>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as Common from '../common/common.js';

import {DebuggerModel, Events as DebuggerModelEvents} from './DebuggerModel.js';
import {DeferredDOMNode, DOMModel, DOMNode} from './DOMModel.js';  // eslint-disable-line no-unused-vars
import {RemoteObject} from './RemoteObject.js';                    // eslint-disable-line no-unused-vars
import {Capability, SDKModel, Target, TargetManager} from './SDKModel.js';  // eslint-disable-line no-unused-vars

/**
 * @typedef {{r: number, g: number, b: number, a: number}}
 */
export let HighlightColor;

/**
 * @typedef {{x: number, y: number, width: number, height: number, color: HighlightColor, outlineColor: HighlightColor}}
 */
export let HighlightRect;

/**
 * @implements {Protocol.OverlayDispatcher}
 */
export class OverlayModel extends SDKModel {
  /**
   * @param {!Target} target
   */
  constructor(target) {
    super(target);
    this._domModel = /** @type {!DOMModel} */ (target.model(DOMModel));

    target.registerOverlayDispatcher(this);
    this._overlayAgent = target.overlayAgent();

    this._debuggerModel = target.model(DebuggerModel);
    if (this._debuggerModel) {
      Common.Settings.Settings.instance()
          .moduleSetting('disablePausedStateOverlay')
          .addChangeListener(this._updatePausedInDebuggerMessage, this);
      this._debuggerModel.addEventListener(DebuggerModelEvents.DebuggerPaused, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
      this._debuggerModel.addEventListener(DebuggerModelEvents.DebuggerResumed, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
      // TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
      this._debuggerModel.addEventListener(DebuggerModelEvents.GlobalObjectCleared, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
    }

    this._inspectModeEnabled = false;
    this._hideHighlightTimeout = null;
    this._defaultHighlighter = new DefaultHighlighter(this);
    this._highlighter = this._defaultHighlighter;

    this._showPaintRectsSetting = Common.Settings.Settings.instance().moduleSetting('showPaintRects');
    this._showLayoutShiftRegionsSetting = Common.Settings.Settings.instance().moduleSetting('showLayoutShiftRegions');
    this._showAdHighlightsSetting = Common.Settings.Settings.instance().moduleSetting('showAdHighlights');
    this._showDebugBordersSetting = Common.Settings.Settings.instance().moduleSetting('showDebugBorders');
    this._showFPSCounterSetting = Common.Settings.Settings.instance().moduleSetting('showFPSCounter');
    this._showScrollBottleneckRectsSetting =
        Common.Settings.Settings.instance().moduleSetting('showScrollBottleneckRects');
    this._showHitTestBordersSetting = Common.Settings.Settings.instance().moduleSetting('showHitTestBorders');

    this._registeredListeners = [];
    this._showViewportSizeOnResize = true;
    if (!target.suspended()) {
      this._overlayAgent.enable();
      this._wireAgentToSettings();
    }
  }

  /**
   * @param {!RemoteObject} object
   */
  static highlightObjectAsDOMNode(object) {
    const domModel = object.runtimeModel().target().model(DOMModel);
    if (domModel) {
      domModel.overlayModel().highlightInOverlay({object});
    }
  }

  static hideDOMNodeHighlight() {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel._delayedHideHighlight(0);
    }
  }

  static async muteHighlight() {
    return Promise.all(TargetManager.instance().models(OverlayModel).map(model => model.suspendModel()));
  }

  static async unmuteHighlight() {
    return Promise.all(TargetManager.instance().models(OverlayModel).map(model => model.resumeModel()));
  }

  /**
   * @param {!HighlightRect} rect
   */
  static highlightRect(rect) {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel.highlightRect(rect);
    }
  }

  static clearHighlight() {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel.clearHighlight();
    }
  }

  /**
   * @param {!HighlightRect} rect
   * @return {!Promise}
   */
  highlightRect({x, y, width, height, color, outlineColor}) {
    const highlightColor = color || {r: 255, g: 0, b: 255, a: 0.3};
    const highlightOutlineColor = outlineColor || {r: 255, g: 0, b: 255, a: 0.5};
    return this._overlayAgent.invoke_highlightRect(
        {x, y, width, height, color: highlightColor, outlineColor: highlightOutlineColor});
  }

  /**
   * @return {!Promise}
   */
  clearHighlight() {
    return this._overlayAgent.invoke_hideHighlight({});
  }

  /**
   * @return {!Promise}
   */
  _wireAgentToSettings() {
    this._registeredListeners = [
      this._showPaintRectsSetting.addChangeListener(
          () => this._overlayAgent.setShowPaintRects(this._showPaintRectsSetting.get())),
      this._showLayoutShiftRegionsSetting.addChangeListener(
          () => this._overlayAgent.setShowLayoutShiftRegions(this._showLayoutShiftRegionsSetting.get())),
      this._showAdHighlightsSetting.addChangeListener(
          () => this._overlayAgent.setShowAdHighlights(this._showAdHighlightsSetting.get())),
      this._showDebugBordersSetting.addChangeListener(
          () => this._overlayAgent.setShowDebugBorders(this._showDebugBordersSetting.get())),
      this._showFPSCounterSetting.addChangeListener(
          () => this._overlayAgent.setShowFPSCounter(this._showFPSCounterSetting.get())),
      this._showScrollBottleneckRectsSetting.addChangeListener(
          () => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get())),
      this._showHitTestBordersSetting.addChangeListener(
          () => this._overlayAgent.setShowHitTestBorders(this._showHitTestBordersSetting.get()))
    ];

    if (this._showPaintRectsSetting.get()) {
      this._overlayAgent.setShowPaintRects(true);
    }
    if (this._showLayoutShiftRegionsSetting.get()) {
      this._overlayAgent.setShowLayoutShiftRegions(true);
    }
    if (this._showAdHighlightsSetting.get()) {
      this._overlayAgent.setShowAdHighlights(true);
    }
    if (this._showDebugBordersSetting.get()) {
      this._overlayAgent.setShowDebugBorders(true);
    }
    if (this._showFPSCounterSetting.get()) {
      this._overlayAgent.setShowFPSCounter(true);
    }
    if (this._showScrollBottleneckRectsSetting.get()) {
      this._overlayAgent.setShowScrollBottleneckRects(true);
    }
    if (this._showHitTestBordersSetting.get()) {
      this._overlayAgent.setShowHitTestBorders(true);
    }
    if (this._debuggerModel.isPaused()) {
      this._updatePausedInDebuggerMessage();
    }
    return this._overlayAgent.setShowViewportSizeOnResize(this._showViewportSizeOnResize);
  }

  /**
   * @override
   * @return {!Promise}
   */
  suspendModel() {
    Common.EventTarget.EventTarget.removeEventListeners(this._registeredListeners);
    return this._overlayAgent.disable();
  }

  /**
   * @override
   * @return {!Promise}
   */
  resumeModel() {
    this._overlayAgent.enable();
    return this._wireAgentToSettings();
  }

  /**
   * @param {boolean} show
   */
  setShowViewportSizeOnResize(show) {
    this._showViewportSizeOnResize = show;
    if (this.target().suspended()) {
      return;
    }
    this._overlayAgent.setShowViewportSizeOnResize(show);
  }

  _updatePausedInDebuggerMessage() {
    if (this.target().suspended()) {
      return;
    }
    const message = this._debuggerModel.isPaused() &&
            !Common.Settings.Settings.instance().moduleSetting('disablePausedStateOverlay').get() ?
        Common.UIString.UIString('Paused in debugger') :
        undefined;
    this._overlayAgent.setPausedInDebuggerMessage(message);
  }

  /**
   * @param {?Highlighter} highlighter
   */
  setHighlighter(highlighter) {
    this._highlighter = highlighter || this._defaultHighlighter;
  }

  /**
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {boolean=} showStyles
   * @return {!Promise}
   */
  async setInspectMode(mode, showStyles = true) {
    await this._domModel.requestDocument();
    this._inspectModeEnabled = mode !== Protocol.Overlay.InspectMode.None;
    this.dispatchEventToListeners(Events.InspectModeWillBeToggled, this);
    this._highlighter.setInspectMode(mode, this._buildHighlightConfig('all', showStyles));
  }

  /**
   * @return {boolean}
   */
  inspectModeEnabled() {
    return this._inspectModeEnabled;
  }

  /**
   * @param {!HighlightData} data
   * @param {string=} mode
   * @param {boolean=} showInfo
   */
  highlightInOverlay(data, mode, showInfo) {
    if (this._hideHighlightTimeout) {
      clearTimeout(this._hideHighlightTimeout);
      this._hideHighlightTimeout = null;
    }
    const highlightConfig = this._buildHighlightConfig(mode);
    if (typeof showInfo !== 'undefined') {
      highlightConfig.showInfo = showInfo;
    }
    this._highlighter.highlightInOverlay(data, highlightConfig);
  }

  /**
   * @param {!HighlightData} data
   */
  highlightInOverlayForTwoSeconds(data) {
    this.highlightInOverlay(data);
    this._delayedHideHighlight(2000);
  }

  /**
   * @param {number} delay
   */
  _delayedHideHighlight(delay) {
    if (this._hideHighlightTimeout === null) {
      this._hideHighlightTimeout = setTimeout(() => this.highlightInOverlay({}), delay);
    }
  }

  /**
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {
    if (this._hideHighlightTimeout) {
      clearTimeout(this._hideHighlightTimeout);
      this._hideHighlightTimeout = null;
    }
    this._highlighter.highlightFrame(frameId);
  }

  /**
   * @param {string=} mode
   * @param {boolean=} showStyles
   * @return {!Protocol.Overlay.HighlightConfig}
   */
  _buildHighlightConfig(mode = 'all', showStyles = false) {
    const showRulers = Common.Settings.Settings.instance().moduleSetting('showMetricsRulers').get();
    const highlightConfig =
        {showInfo: mode === 'all', showRulers: showRulers, showStyles, showExtensionLines: showRulers};
    if (mode === 'all' || mode === 'content') {
      highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'padding') {
      highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'border') {
      highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'margin') {
      highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
    }

    if (mode === 'all') {
      highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
      highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
      highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
    }

    if (mode === 'all') {
      highlightConfig.cssGridColor = Common.Color.PageHighlight.CssGrid.toProtocolRGBA();
    }

    return highlightConfig;
  }

  /**
   * @override
   * @param {!Protocol.DOM.NodeId} nodeId
   */
  nodeHighlightRequested(nodeId) {
    const node = this._domModel.nodeForId(nodeId);
    if (node) {
      this.dispatchEventToListeners(Events.HighlightNodeRequested, node);
    }
  }

  /**
   * @param {function(!DOMNode)} handler
   */
  static setInspectNodeHandler(handler) {
    OverlayModel._inspectNodeHandler = handler;
  }

  /**
   * @override
   * @param {!Protocol.DOM.BackendNodeId} backendNodeId
   */
  inspectNodeRequested(backendNodeId) {
    const deferredNode = new DeferredDOMNode(this.target(), backendNodeId);
    if (OverlayModel._inspectNodeHandler) {
      deferredNode.resolvePromise().then(node => {
        if (node) {
          OverlayModel._inspectNodeHandler(node);
        }
      });
    } else {
      Common.Revealer.reveal(deferredNode);
    }
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }

  /**
   * @override
   * @param {!Protocol.Page.Viewport} viewport
   */
  screenshotRequested(viewport) {
    this.dispatchEventToListeners(Events.ScreenshotRequested, viewport);
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }

  /**
   * @override
   */
  inspectModeCanceled() {
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }
}

/** @enum {symbol} */
export const Events = {
  InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
  ExitedInspectMode: Symbol('InspectModeExited'),
  HighlightNodeRequested: Symbol('HighlightNodeRequested'),
  ScreenshotRequested: Symbol('ScreenshotRequested'),
};

/**
 * @interface
 */
export class Highlighter {
  /**
   * @param {!HighlightData} data
   * @param {!Protocol.Overlay.HighlightConfig} config
   */
  highlightInOverlay(data, config) {
  }

  /**
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {!Protocol.Overlay.HighlightConfig} config
   * @return {!Promise}
   */
  setInspectMode(mode, config) {
  }

  /**
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {}
}

/**
 * @implements {Highlighter}
 */
class DefaultHighlighter {
  /**
   * @param {!OverlayModel} model
   */
  constructor(model) {
    this._model = model;
  }

  /**
   * @override
   * @param {!HighlightData} data
   * @param {!Protocol.Overlay.HighlightConfig} config
   */
  highlightInOverlay(data, config) {
    const {node, deferredNode, object, selectorList} = data;
    const nodeId = node ? node.id : undefined;
    const backendNodeId = deferredNode ? deferredNode.backendNodeId() : undefined;
    const objectId = object ? object.objectId : undefined;
    if (nodeId || backendNodeId || objectId) {
      this._model._overlayAgent.highlightNode(config, nodeId, backendNodeId, objectId, selectorList);
    } else {
      this._model._overlayAgent.hideHighlight();
    }
  }

  /**
   * @override
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {!Protocol.Overlay.HighlightConfig} config
   * @return {!Promise}
   */
  setInspectMode(mode, config) {
    return this._model._overlayAgent.setInspectMode(mode, config);
  }

  /**
   * @override
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {
    this._model._overlayAgent.highlightFrame(
        frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
        Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
  }
}

SDKModel.register(OverlayModel, Capability.DOM, true);

/** @typedef {{node: (!DOMNode|undefined),
 deferredNode: (!DeferredDOMNode|undefined),
 selectorList: (string|undefined),
 object:(!RemoteObject|undefined)}} */
export let HighlightData;
<commit_msg>Forward the color format preference to the backend<commit_after>// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @ts-nocheck
// TODO(crbug.com/1011811): Enable TypeScript compiler checks

import * as Common from '../common/common.js';

import {DebuggerModel, Events as DebuggerModelEvents} from './DebuggerModel.js';
import {DeferredDOMNode, DOMModel, DOMNode} from './DOMModel.js';  // eslint-disable-line no-unused-vars
import {RemoteObject} from './RemoteObject.js';                    // eslint-disable-line no-unused-vars
import {Capability, SDKModel, Target, TargetManager} from './SDKModel.js';  // eslint-disable-line no-unused-vars

/**
 * @typedef {{r: number, g: number, b: number, a: number}}
 */
export let HighlightColor;

/**
 * @typedef {{x: number, y: number, width: number, height: number, color: HighlightColor, outlineColor: HighlightColor}}
 */
export let HighlightRect;

/**
 * @implements {Protocol.OverlayDispatcher}
 */
export class OverlayModel extends SDKModel {
  /**
   * @param {!Target} target
   */
  constructor(target) {
    super(target);
    this._domModel = /** @type {!DOMModel} */ (target.model(DOMModel));

    target.registerOverlayDispatcher(this);
    this._overlayAgent = target.overlayAgent();

    this._debuggerModel = target.model(DebuggerModel);
    if (this._debuggerModel) {
      Common.Settings.Settings.instance()
          .moduleSetting('disablePausedStateOverlay')
          .addChangeListener(this._updatePausedInDebuggerMessage, this);
      this._debuggerModel.addEventListener(DebuggerModelEvents.DebuggerPaused, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
      this._debuggerModel.addEventListener(DebuggerModelEvents.DebuggerResumed, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
      // TODO(dgozman): we should get DebuggerResumed on navigations instead of listening to GlobalObjectCleared.
      this._debuggerModel.addEventListener(DebuggerModelEvents.GlobalObjectCleared, event => {
        this._updatePausedInDebuggerMessage();
      }, this);
    }

    this._inspectModeEnabled = false;
    this._hideHighlightTimeout = null;
    this._defaultHighlighter = new DefaultHighlighter(this);
    this._highlighter = this._defaultHighlighter;

    this._showPaintRectsSetting = Common.Settings.Settings.instance().moduleSetting('showPaintRects');
    this._showLayoutShiftRegionsSetting = Common.Settings.Settings.instance().moduleSetting('showLayoutShiftRegions');
    this._showAdHighlightsSetting = Common.Settings.Settings.instance().moduleSetting('showAdHighlights');
    this._showDebugBordersSetting = Common.Settings.Settings.instance().moduleSetting('showDebugBorders');
    this._showFPSCounterSetting = Common.Settings.Settings.instance().moduleSetting('showFPSCounter');
    this._showScrollBottleneckRectsSetting =
        Common.Settings.Settings.instance().moduleSetting('showScrollBottleneckRects');
    this._showHitTestBordersSetting = Common.Settings.Settings.instance().moduleSetting('showHitTestBorders');

    this._registeredListeners = [];
    this._showViewportSizeOnResize = true;
    if (!target.suspended()) {
      this._overlayAgent.enable();
      this._wireAgentToSettings();
    }
  }

  /**
   * @param {!RemoteObject} object
   */
  static highlightObjectAsDOMNode(object) {
    const domModel = object.runtimeModel().target().model(DOMModel);
    if (domModel) {
      domModel.overlayModel().highlightInOverlay({object});
    }
  }

  static hideDOMNodeHighlight() {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel._delayedHideHighlight(0);
    }
  }

  static async muteHighlight() {
    return Promise.all(TargetManager.instance().models(OverlayModel).map(model => model.suspendModel()));
  }

  static async unmuteHighlight() {
    return Promise.all(TargetManager.instance().models(OverlayModel).map(model => model.resumeModel()));
  }

  /**
   * @param {!HighlightRect} rect
   */
  static highlightRect(rect) {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel.highlightRect(rect);
    }
  }

  static clearHighlight() {
    for (const overlayModel of TargetManager.instance().models(OverlayModel)) {
      overlayModel.clearHighlight();
    }
  }

  /**
   * @param {!HighlightRect} rect
   * @return {!Promise}
   */
  highlightRect({x, y, width, height, color, outlineColor}) {
    const highlightColor = color || {r: 255, g: 0, b: 255, a: 0.3};
    const highlightOutlineColor = outlineColor || {r: 255, g: 0, b: 255, a: 0.5};
    return this._overlayAgent.invoke_highlightRect(
        {x, y, width, height, color: highlightColor, outlineColor: highlightOutlineColor});
  }

  /**
   * @return {!Promise}
   */
  clearHighlight() {
    return this._overlayAgent.invoke_hideHighlight({});
  }

  /**
   * @return {!Promise}
   */
  _wireAgentToSettings() {
    this._registeredListeners = [
      this._showPaintRectsSetting.addChangeListener(
          () => this._overlayAgent.setShowPaintRects(this._showPaintRectsSetting.get())),
      this._showLayoutShiftRegionsSetting.addChangeListener(
          () => this._overlayAgent.setShowLayoutShiftRegions(this._showLayoutShiftRegionsSetting.get())),
      this._showAdHighlightsSetting.addChangeListener(
          () => this._overlayAgent.setShowAdHighlights(this._showAdHighlightsSetting.get())),
      this._showDebugBordersSetting.addChangeListener(
          () => this._overlayAgent.setShowDebugBorders(this._showDebugBordersSetting.get())),
      this._showFPSCounterSetting.addChangeListener(
          () => this._overlayAgent.setShowFPSCounter(this._showFPSCounterSetting.get())),
      this._showScrollBottleneckRectsSetting.addChangeListener(
          () => this._overlayAgent.setShowScrollBottleneckRects(this._showScrollBottleneckRectsSetting.get())),
      this._showHitTestBordersSetting.addChangeListener(
          () => this._overlayAgent.setShowHitTestBorders(this._showHitTestBordersSetting.get()))
    ];

    if (this._showPaintRectsSetting.get()) {
      this._overlayAgent.setShowPaintRects(true);
    }
    if (this._showLayoutShiftRegionsSetting.get()) {
      this._overlayAgent.setShowLayoutShiftRegions(true);
    }
    if (this._showAdHighlightsSetting.get()) {
      this._overlayAgent.setShowAdHighlights(true);
    }
    if (this._showDebugBordersSetting.get()) {
      this._overlayAgent.setShowDebugBorders(true);
    }
    if (this._showFPSCounterSetting.get()) {
      this._overlayAgent.setShowFPSCounter(true);
    }
    if (this._showScrollBottleneckRectsSetting.get()) {
      this._overlayAgent.setShowScrollBottleneckRects(true);
    }
    if (this._showHitTestBordersSetting.get()) {
      this._overlayAgent.setShowHitTestBorders(true);
    }
    if (this._debuggerModel.isPaused()) {
      this._updatePausedInDebuggerMessage();
    }
    return this._overlayAgent.setShowViewportSizeOnResize(this._showViewportSizeOnResize);
  }

  /**
   * @override
   * @return {!Promise}
   */
  suspendModel() {
    Common.EventTarget.EventTarget.removeEventListeners(this._registeredListeners);
    return this._overlayAgent.disable();
  }

  /**
   * @override
   * @return {!Promise}
   */
  resumeModel() {
    this._overlayAgent.enable();
    return this._wireAgentToSettings();
  }

  /**
   * @param {boolean} show
   */
  setShowViewportSizeOnResize(show) {
    this._showViewportSizeOnResize = show;
    if (this.target().suspended()) {
      return;
    }
    this._overlayAgent.setShowViewportSizeOnResize(show);
  }

  _updatePausedInDebuggerMessage() {
    if (this.target().suspended()) {
      return;
    }
    const message = this._debuggerModel.isPaused() &&
            !Common.Settings.Settings.instance().moduleSetting('disablePausedStateOverlay').get() ?
        Common.UIString.UIString('Paused in debugger') :
        undefined;
    this._overlayAgent.setPausedInDebuggerMessage(message);
  }

  /**
   * @param {?Highlighter} highlighter
   */
  setHighlighter(highlighter) {
    this._highlighter = highlighter || this._defaultHighlighter;
  }

  /**
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {boolean=} showStyles
   * @return {!Promise}
   */
  async setInspectMode(mode, showStyles = true) {
    await this._domModel.requestDocument();
    this._inspectModeEnabled = mode !== Protocol.Overlay.InspectMode.None;
    this.dispatchEventToListeners(Events.InspectModeWillBeToggled, this);
    this._highlighter.setInspectMode(mode, this._buildHighlightConfig('all', showStyles));
  }

  /**
   * @return {boolean}
   */
  inspectModeEnabled() {
    return this._inspectModeEnabled;
  }

  /**
   * @param {!HighlightData} data
   * @param {string=} mode
   * @param {boolean=} showInfo
   */
  highlightInOverlay(data, mode, showInfo) {
    if (this._hideHighlightTimeout) {
      clearTimeout(this._hideHighlightTimeout);
      this._hideHighlightTimeout = null;
    }
    const highlightConfig = this._buildHighlightConfig(mode);
    if (typeof showInfo !== 'undefined') {
      highlightConfig.showInfo = showInfo;
    }
    this._highlighter.highlightInOverlay(data, highlightConfig);
  }

  /**
   * @param {!HighlightData} data
   */
  highlightInOverlayForTwoSeconds(data) {
    this.highlightInOverlay(data);
    this._delayedHideHighlight(2000);
  }

  /**
   * @param {number} delay
   */
  _delayedHideHighlight(delay) {
    if (this._hideHighlightTimeout === null) {
      this._hideHighlightTimeout = setTimeout(() => this.highlightInOverlay({}), delay);
    }
  }

  /**
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {
    if (this._hideHighlightTimeout) {
      clearTimeout(this._hideHighlightTimeout);
      this._hideHighlightTimeout = null;
    }
    this._highlighter.highlightFrame(frameId);
  }

  /**
   * @param {string=} mode
   * @param {boolean=} showStyles
   * @return {!Protocol.Overlay.HighlightConfig}
   */
  _buildHighlightConfig(mode = 'all', showStyles = false) {
    const showRulers = Common.Settings.Settings.instance().moduleSetting('showMetricsRulers').get();
    const colorFormat = Common.Settings.Settings.instance().moduleSetting('colorFormat').get();
    const highlightConfig =
        {showInfo: mode === 'all', showRulers: showRulers, showStyles, showExtensionLines: showRulers};
    if (mode === 'all' || mode === 'content') {
      highlightConfig.contentColor = Common.Color.PageHighlight.Content.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'padding') {
      highlightConfig.paddingColor = Common.Color.PageHighlight.Padding.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'border') {
      highlightConfig.borderColor = Common.Color.PageHighlight.Border.toProtocolRGBA();
    }

    if (mode === 'all' || mode === 'margin') {
      highlightConfig.marginColor = Common.Color.PageHighlight.Margin.toProtocolRGBA();
    }

    if (mode === 'all') {
      highlightConfig.eventTargetColor = Common.Color.PageHighlight.EventTarget.toProtocolRGBA();
      highlightConfig.shapeColor = Common.Color.PageHighlight.Shape.toProtocolRGBA();
      highlightConfig.shapeMarginColor = Common.Color.PageHighlight.ShapeMargin.toProtocolRGBA();
    }

    if (mode === 'all') {
      highlightConfig.cssGridColor = Common.Color.PageHighlight.CssGrid.toProtocolRGBA();
    }

    // the backend does not support the 'original' format because
    // it currently cannot retrieve the original format using computed styles
    const supportedColorFormats = new Set(['rgb', 'hsl', 'hex']);
    if (supportedColorFormats.has(colorFormat)) {
      highlightConfig.colorFormat = colorFormat;
    }

    return highlightConfig;
  }

  /**
   * @override
   * @param {!Protocol.DOM.NodeId} nodeId
   */
  nodeHighlightRequested(nodeId) {
    const node = this._domModel.nodeForId(nodeId);
    if (node) {
      this.dispatchEventToListeners(Events.HighlightNodeRequested, node);
    }
  }

  /**
   * @param {function(!DOMNode)} handler
   */
  static setInspectNodeHandler(handler) {
    OverlayModel._inspectNodeHandler = handler;
  }

  /**
   * @override
   * @param {!Protocol.DOM.BackendNodeId} backendNodeId
   */
  inspectNodeRequested(backendNodeId) {
    const deferredNode = new DeferredDOMNode(this.target(), backendNodeId);
    if (OverlayModel._inspectNodeHandler) {
      deferredNode.resolvePromise().then(node => {
        if (node) {
          OverlayModel._inspectNodeHandler(node);
        }
      });
    } else {
      Common.Revealer.reveal(deferredNode);
    }
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }

  /**
   * @override
   * @param {!Protocol.Page.Viewport} viewport
   */
  screenshotRequested(viewport) {
    this.dispatchEventToListeners(Events.ScreenshotRequested, viewport);
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }

  /**
   * @override
   */
  inspectModeCanceled() {
    this.dispatchEventToListeners(Events.ExitedInspectMode);
  }
}

/** @enum {symbol} */
export const Events = {
  InspectModeWillBeToggled: Symbol('InspectModeWillBeToggled'),
  ExitedInspectMode: Symbol('InspectModeExited'),
  HighlightNodeRequested: Symbol('HighlightNodeRequested'),
  ScreenshotRequested: Symbol('ScreenshotRequested'),
};

/**
 * @interface
 */
export class Highlighter {
  /**
   * @param {!HighlightData} data
   * @param {!Protocol.Overlay.HighlightConfig} config
   */
  highlightInOverlay(data, config) {
  }

  /**
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {!Protocol.Overlay.HighlightConfig} config
   * @return {!Promise}
   */
  setInspectMode(mode, config) {
  }

  /**
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {}
}

/**
 * @implements {Highlighter}
 */
class DefaultHighlighter {
  /**
   * @param {!OverlayModel} model
   */
  constructor(model) {
    this._model = model;
  }

  /**
   * @override
   * @param {!HighlightData} data
   * @param {!Protocol.Overlay.HighlightConfig} config
   */
  highlightInOverlay(data, config) {
    const {node, deferredNode, object, selectorList} = data;
    const nodeId = node ? node.id : undefined;
    const backendNodeId = deferredNode ? deferredNode.backendNodeId() : undefined;
    const objectId = object ? object.objectId : undefined;
    if (nodeId || backendNodeId || objectId) {
      this._model._overlayAgent.highlightNode(config, nodeId, backendNodeId, objectId, selectorList);
    } else {
      this._model._overlayAgent.hideHighlight();
    }
  }

  /**
   * @override
   * @param {!Protocol.Overlay.InspectMode} mode
   * @param {!Protocol.Overlay.HighlightConfig} config
   * @return {!Promise}
   */
  setInspectMode(mode, config) {
    return this._model._overlayAgent.setInspectMode(mode, config);
  }

  /**
   * @override
   * @param {!Protocol.Page.FrameId} frameId
   */
  highlightFrame(frameId) {
    this._model._overlayAgent.highlightFrame(
        frameId, Common.Color.PageHighlight.Content.toProtocolRGBA(),
        Common.Color.PageHighlight.ContentOutline.toProtocolRGBA());
  }
}

SDKModel.register(OverlayModel, Capability.DOM, true);

/** @typedef {{node: (!DOMNode|undefined),
 deferredNode: (!DeferredDOMNode|undefined),
 selectorList: (string|undefined),
 object:(!RemoteObject|undefined)}} */
export let HighlightData;
<|endoftext|>


<commit_before>const fs = require("fs");
const assert = require("assert");
const parse = require("../../parser.js");

/* eslint-disable */
describe("The parser", () => {
  fs.readdirSync(__dirname).forEach((name) => {
    if (name.endsWith(".jml")) {
      it(`produces the correct AST for ${name}`, (done) => {
        fs.readFile(`${__dirname}/${name}`, "utf-8", (err, input) => {
          const ast = parse(input);
          console.log(ast);
          fs.readFile(`${__dirname}/${name}.json`, "utf-8", (_err, expected) => {
            assert.equal(JSON.stringify(ast), expected.trim());
            done();
          });
        });
      });
    }
  });
});
<commit_msg>Fix require line<commit_after>const fs = require("fs");
const assert = require("assert");
const parse = require("../../parser.js").parse;

/* eslint-disable */
describe("The parser", () => {
  fs.readdirSync(__dirname).forEach((name) => {
    if (name.endsWith(".jml")) {
      it(`produces the correct AST for ${name}`, (done) => {
        fs.readFile(`${__dirname}/${name}`, "utf-8", (err, input) => {
          const ast = parse(input);
          console.log(ast);
          fs.readFile(`${__dirname}/${name}.json`, "utf-8", (_err, expected) => {
            assert.equal(JSON.stringify(ast), expected.trim());
            done();
          });
        });
      });
    }
  });
});
<|endoftext|>


<commit_before>Ui.Element.extend('Ui.Video',
/**@lends Ui.Video#*/
{
	src: undefined,
	poster: undefined,
	oggSrc: undefined,
	mp4Src: undefined,
	webmSrc: undefined,
	loaddone: false,
	videoDrawing: undefined,
	canplaythrough: false,
	// possible values [initial|playing|paused|buffering|error]
	state: 'initial',

	/**
	*	@constructs
	*	@class
	*	@extends Ui.Element
	*/
	constructor: function(config) {
		this.addEvents('ready', 'ended', 'timeupdate', 'bufferingupdate', 'statechange', 'error');
		this.connect(this, 'unload', this.onVideoUnload);
		if((config.oggSrc != undefined) || (config.mp4Src != undefined) || (config.webmSrc != undefined)) {
			if((config.oggSrc != undefined) && (Ui.Video.supportOgg))
				this.setSrc(config.oggSrc);
			else if((config.mp4Src != undefined) && (Ui.Video.supportMp4))
				this.setSrc(config.mp4Src);
			else if((config.webmSrc != undefined) && (Ui.Video.supportWebm))
				this.setSrc(config.webmSrc);
			delete(config.oggSrc);
			delete(config.mp4Src);
			delete(config.webmSrc);
		}
	},

	/**
	* Set the file URL for the current video element
	*/
	setSrc: function(src) {
		this.canplaythrough = false;
		this.state = 'initial';
		this.src = src;
		this.videoDrawing.setAttribute('src', src);
		try {
			this.videoDrawing.load();
		} catch(e) {}
	},

	/**
	* Set the file URL for the current video poster (preview)
	*/
	setPoster: function(src) {
		this.poster = src;
		this.videoDrawing.setAttribute('poster', src);
	},

	/**
	* Play the video element. If the element is already playing
	* stop it and restart from the begining.
	*/
	play: function() {
		this.state = 'playing';
		this.fireEvent('statechange', this, this.state);
		if(this.canplaythrough)
			this.videoDrawing.play();
		else
			this.videoDrawing.load();
	},

	/**
	* Pause the video element. If the element is not
	* currently playing, do nothing.
	*/
	pause: function() {
		this.state = 'paused';
		this.fireEvent('statechange', this, this.state);
		if(this.canplaythrough)
			this.videoDrawing.pause();
		else
			this.videoDrawing.load();
	},

	/**
	* Stop the sound if playing.
	*/
	stop: function() {
		this.videoDrawing.pause();
		this.onEnded();
	},

	/**
	* Set the video volume between 0 and 1
	*/
	setVolume: function(volume) {
		this.videoDrawing.volume = volume;
	},

	/**
	* Get the video volume between 0 and 1
	*/
	getVolume: function() {
		return this.videoDrawing.volume;
	},

	/**
	* @return the duration in seconds of the video file
	* or undefined if unknown. This value is only known
	* after the ready event.
	*/
	getDuration: function() {
		return this.videoDrawing.duration;
	},

	/**
	 * Seek the current position of the video file.
	 */
	setCurrentTime: function(time) {
		this.videoDrawing.currentTime = time;
	},

	/**
	 * Return the current position in seconds.
	 * This value is only known after the ready event.
	 */
	getCurrentTime: function() {
		if(this.videoDrawing.currentTime == undefined)
			return 0;
		else
			return this.videoDrawing.currentTime;
	},

	/**
	 * Return the current state of the media
	 */
	getState: function() {
		return this.state;
	},

	/**
	 * Return true if the video is ready to play
	 * and infos like duration, currentTime... are
	 * known
	 */
	getIsReady: function() {
		return this.canplaythrough;
	},

	/**
	 * Return the natural width of the image as defined
	 * in the image file. Return undefined if the image is
	 * not ready
	 */
	getNaturalWidth: function() {
		return this.naturalWidth;
	},

	/**
	 * Return the natural height of the image as defined
	 * in the image file. Return undefined if the image is
	 * not ready
	 */
	getNaturalHeight: function() {
		return this.naturalHeight;
	},

	/**#@+
	* @private
	*/
	onReady: function() {
		this.canplaythrough = true;
		this.naturalWidth = this.videoDrawing.videoWidth;
		this.naturalHeight = this.videoDrawing.videoHeight;
		if(this.state == 'playing')
			this.videoDrawing.play();
		else if(this.state == 'paused')
			this.videoDrawing.pause();
		this.fireEvent('ready');
	},

	onTimeUpdate: function() {
		this.fireEvent('timeupdate', this, this.videoDrawing.currentTime);
		this.checkBuffering();
	},

	onEnded: function() {
		this.videoDrawing.pause();
		this.state = 'initial';
		this.videoDrawing.currentTime = 0;
		this.fireEvent('ended', this);
		this.fireEvent('statechange', this, this.state);
	},

	onProgress: function() {
		this.checkBuffering();
	},

	getCurrentBufferSize: function() {
		var buffered = this.videoDrawing.buffered;
		var timebuffer = 0;
		var time = this.videoDrawing.currentTime;
		if(time == undefined)
			time = 0;
		var lastEnd = undefined;
		for(var i = 0; i < buffered.length; i++) {
			var start = buffered.start(i);
			var end = buffered.end(i);
			if(lastEnd == undefined) {
				if((start <= time) && (end >= time)) {
					timebuffer = end - time;
					lastEnd = end;
				}
			}
			else {
				if((lastEnd >= (start-0.01)) && (lastEnd <= end)) {
					timebuffer += (end - lastEnd);
					lastEnd = end;
				}
			}
		}
		return timebuffer;
	},

	checkBuffering: function() {
		var timebuffer = this.getCurrentBufferSize();
		var time = this.videoDrawing.currentTime;
		var duration = this.videoDrawing.duration;

		if(this.state == 'buffering') {
			// if we have 5s in the buffer or if the browser already decided
			// to stop buffering or if we are at the end
			if((timebuffer >= 5) || (this.videoDrawing.networkState == 1) || (time + timebuffer >= duration)) {
				this.state = 'playing';
				this.videoDrawing.play();
				this.fireEvent('statechange', this, this.state);
			}
		}
		else if(this.state == 'playing') {
			// if remains less than 100ms in the buffer, pause
			// to let enought time for the buffer to grow
			if((timebuffer <= 0.1) && (time + timebuffer < duration)) {
				this.state = 'buffering';
				this.videoDrawing.pause();
				this.fireEvent('statechange', this, this.state);
			}
		}
		this.fireEvent('bufferingupdate', this, timebuffer);
	},

	onError: function() {
		this.state = 'error';
		this.fireEvent('error', this, this.videoDrawing.error.code);
		this.fireEvent('statechange', this, this.state);
	},

	onWaiting: function() {
		if(!this.canplaythrough)
			this.videoDrawing.load();
	},

	onVideoUnload: function() {
		if(this.canplaythrough)
			this.pause();
	}
	/**#@-*/
},
/**@lends Ui.Video#*/
{
	renderDrawing: function() {
		if(Ui.Video.htmlVideo) {
			this.videoDrawing = document.createElement('video');
			this.connect(this.videoDrawing, 'canplaythrough', this.onReady);
			this.connect(this.videoDrawing, 'ended', this.onEnded);
			this.connect(this.videoDrawing, 'timeupdate', this.onTimeUpdate);
			this.connect(this.videoDrawing, 'error', this.onError);
			this.connect(this.videoDrawing, 'progress', this.onProgress);
			this.connect(this.videoDrawing, 'waiting', this.onWaiting);
			this.videoDrawing.setAttribute('preload', 'auto');
			this.videoDrawing.load();
			this.videoDrawing.style.position = 'absolute';
			this.videoDrawing.style.left = '0px';
			this.videoDrawing.style.top = '0px';
		}
		return this.videoDrawing;
	},

	arrangeCore: function(width, height) {
		if(Ui.Video.htmlVideo) {
			this.videoDrawing.setAttribute('width', width);
			this.videoDrawing.setAttribute('height', height);
		}
	}
});

// detect what video system is supported
Ui.Video.htmlVideo = false;
Ui.Video.flashVideo = false;
Ui.Video.supportOgg = false;
Ui.Video.supportMp4 = false;
Ui.Video.supportWebm = false;

// check for HTMLVideoElement
Ui.Video.videoTest = document.createElement('video');
if(Ui.Video.videoTest.play != undefined) {
	Ui.Video.htmlVideo = true;
	Ui.Video.supportMp4 = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
	Ui.Video.supportOgg = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/ogg; codecs="theora, vorbis"');
	Ui.Video.supportWebm = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/webm; codecs="vp8, vorbis"');
}
Ui.Video.videoTest = undefined;

<commit_msg>provide control on "autoplay" for Ui.Video and allow to provide an object as a source. This allow to use Ui.Video with getUserMedia API<commit_after>Ui.Element.extend('Ui.Video',
/**@lends Ui.Video#*/
{
	src: undefined,
	poster: undefined,
	oggSrc: undefined,
	mp4Src: undefined,
	webmSrc: undefined,
	loaddone: false,
	videoDrawing: undefined,
	canplaythrough: false,
	// possible values [initial|playing|paused|buffering|error]
	state: 'initial',

	/**
	*	@constructs
	*	@class
	*	@extends Ui.Element
	*/
	constructor: function(config) {
		this.addEvents('ready', 'ended', 'timeupdate', 'bufferingupdate', 'statechange', 'error');
		this.connect(this, 'unload', this.onVideoUnload);
		if((config.oggSrc != undefined) || (config.mp4Src != undefined) || (config.webmSrc != undefined)) {
			if((config.oggSrc != undefined) && (Ui.Video.supportOgg))
				this.setSrc(config.oggSrc);
			else if((config.mp4Src != undefined) && (Ui.Video.supportMp4))
				this.setSrc(config.mp4Src);
			else if((config.webmSrc != undefined) && (Ui.Video.supportWebm))
				this.setSrc(config.webmSrc);
			delete(config.oggSrc);
			delete(config.mp4Src);
			delete(config.webmSrc);
		}
	},

	/**
	* Set the file URL for the current video element
	*/
	setSrc: function(src) {
		this.canplaythrough = false;
		this.state = 'initial';
		this.src = src;
		if(typeof(src) === 'object')
			this.videoDrawing.src = URL.createObjectURL(src);
		else
			this.videoDrawing.setAttribute('src', src);
		try {
			this.videoDrawing.load();
		} catch(e) {}
	},

	/**
	* Set the file URL for the current video poster (preview)
	*/
	setPoster: function(src) {
		this.poster = src;
		this.videoDrawing.setAttribute('poster', src);
	},

	/**
	 * Whether or not to autoplay videos
	 */
	setAutoplay: function(autoplay) {
		this.videoDrawing.autoplay = autoplay;
	},

	/**
	* Play the video element. If the element is already playing
	* stop it and restart from the begining.
	*/
	play: function() {
		this.state = 'playing';
		this.fireEvent('statechange', this, this.state);
		if(this.canplaythrough)
			this.videoDrawing.play();
		else
			this.videoDrawing.load();
	},

	/**
	* Pause the video element. If the element is not
	* currently playing, do nothing.
	*/
	pause: function() {
		this.state = 'paused';
		this.fireEvent('statechange', this, this.state);
		if(this.canplaythrough)
			this.videoDrawing.pause();
		else
			this.videoDrawing.load();
	},

	/**
	* Stop the sound if playing.
	*/
	stop: function() {
		this.videoDrawing.pause();
		this.onEnded();
	},

	/**
	* Set the video volume between 0 and 1
	*/
	setVolume: function(volume) {
		this.videoDrawing.volume = volume;
	},

	/**
	* Get the video volume between 0 and 1
	*/
	getVolume: function() {
		return this.videoDrawing.volume;
	},

	/**
	* @return the duration in seconds of the video file
	* or undefined if unknown. This value is only known
	* after the ready event.
	*/
	getDuration: function() {
		return this.videoDrawing.duration;
	},

	/**
	 * Seek the current position of the video file.
	 */
	setCurrentTime: function(time) {
		this.videoDrawing.currentTime = time;
	},

	/**
	 * Return the current position in seconds.
	 * This value is only known after the ready event.
	 */
	getCurrentTime: function() {
		if(this.videoDrawing.currentTime == undefined)
			return 0;
		else
			return this.videoDrawing.currentTime;
	},

	/**
	 * Return the current state of the media
	 */
	getState: function() {
		return this.state;
	},

	/**
	 * Return true if the video is ready to play
	 * and infos like duration, currentTime... are
	 * known
	 */
	getIsReady: function() {
		return this.canplaythrough;
	},

	/**
	 * Return the natural width of the image as defined
	 * in the image file. Return undefined if the image is
	 * not ready
	 */
	getNaturalWidth: function() {
		return this.naturalWidth;
	},

	/**
	 * Return the natural height of the image as defined
	 * in the image file. Return undefined if the image is
	 * not ready
	 */
	getNaturalHeight: function() {
		return this.naturalHeight;
	},

	/**#@+
	* @private
	*/
	onReady: function() {
		this.canplaythrough = true;
		this.naturalWidth = this.videoDrawing.videoWidth;
		this.naturalHeight = this.videoDrawing.videoHeight;
		if(this.state == 'playing')
			this.videoDrawing.play();
		else if(this.state == 'paused')
			this.videoDrawing.pause();
		this.fireEvent('ready');
	},

	onTimeUpdate: function() {
		this.fireEvent('timeupdate', this, this.videoDrawing.currentTime);
		this.checkBuffering();
	},

	onEnded: function() {
		this.videoDrawing.pause();
		this.state = 'initial';
		this.videoDrawing.currentTime = 0;
		this.fireEvent('ended', this);
		this.fireEvent('statechange', this, this.state);
	},

	onProgress: function() {
		this.checkBuffering();
	},

	getCurrentBufferSize: function() {
		var buffered = this.videoDrawing.buffered;
		var timebuffer = 0;
		var time = this.videoDrawing.currentTime;
		if(time == undefined)
			time = 0;
		var lastEnd = undefined;
		for(var i = 0; i < buffered.length; i++) {
			var start = buffered.start(i);
			var end = buffered.end(i);
			if(lastEnd == undefined) {
				if((start <= time) && (end >= time)) {
					timebuffer = end - time;
					lastEnd = end;
				}
			}
			else {
				if((lastEnd >= (start-0.01)) && (lastEnd <= end)) {
					timebuffer += (end - lastEnd);
					lastEnd = end;
				}
			}
		}
		return timebuffer;
	},

	checkBuffering: function() {
		var timebuffer = this.getCurrentBufferSize();
		var time = this.videoDrawing.currentTime;
		var duration = this.videoDrawing.duration;

		if(this.state == 'buffering') {
			// if we have 5s in the buffer or if the browser already decided
			// to stop buffering or if we are at the end
			if((timebuffer >= 5) || (this.videoDrawing.networkState == 1) || (time + timebuffer >= duration)) {
				this.state = 'playing';
				this.videoDrawing.play();
				this.fireEvent('statechange', this, this.state);
			}
		}
		else if(this.state == 'playing') {
			// if remains less than 100ms in the buffer, pause
			// to let enought time for the buffer to grow
			if((timebuffer <= 0.1) && (time + timebuffer < duration)) {
				this.state = 'buffering';
				this.videoDrawing.pause();
				this.fireEvent('statechange', this, this.state);
			}
		}
		this.fireEvent('bufferingupdate', this, timebuffer);
	},

	onError: function() {
		this.state = 'error';
		this.fireEvent('error', this, this.videoDrawing.error.code);
		this.fireEvent('statechange', this, this.state);
	},

	onWaiting: function() {
		if(!this.canplaythrough)
			this.videoDrawing.load();
	},

	onVideoUnload: function() {
		if(this.canplaythrough)
			this.pause();
	}
	/**#@-*/
},
/**@lends Ui.Video#*/
{
	renderDrawing: function() {
		if(Ui.Video.htmlVideo) {
			this.videoDrawing = document.createElement('video');
			this.connect(this.videoDrawing, 'canplaythrough', this.onReady);
			this.connect(this.videoDrawing, 'ended', this.onEnded);
			this.connect(this.videoDrawing, 'timeupdate', this.onTimeUpdate);
			this.connect(this.videoDrawing, 'error', this.onError);
			this.connect(this.videoDrawing, 'progress', this.onProgress);
			this.connect(this.videoDrawing, 'waiting', this.onWaiting);
			this.videoDrawing.setAttribute('preload', 'auto');
			this.videoDrawing.load();
			this.videoDrawing.style.position = 'absolute';
			this.videoDrawing.style.left = '0px';
			this.videoDrawing.style.top = '0px';
		}
		return this.videoDrawing;
	},

	arrangeCore: function(width, height) {
		if(Ui.Video.htmlVideo) {
			this.videoDrawing.setAttribute('width', width);
			this.videoDrawing.setAttribute('height', height);
		}
	}
});

// detect what video system is supported
Ui.Video.htmlVideo = false;
Ui.Video.flashVideo = false;
Ui.Video.supportOgg = false;
Ui.Video.supportMp4 = false;
Ui.Video.supportWebm = false;

// check for HTMLVideoElement
Ui.Video.videoTest = document.createElement('video');
if(Ui.Video.videoTest.play != undefined) {
	Ui.Video.htmlVideo = true;
	Ui.Video.supportMp4 = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
	Ui.Video.supportOgg = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/ogg; codecs="theora, vorbis"');
	Ui.Video.supportWebm = !!Ui.Video.videoTest.canPlayType && "" != Ui.Video.videoTest.canPlayType('video/webm; codecs="vp8, vorbis"');
}
Ui.Video.videoTest = undefined;

<|endoftext|>


<commit_before>function getAppInfo() {
    return {
        "clientId": "21b67bb82b7af444a7ef",
        "redirectUri": "https://livelykernel.github.io/lively4-core/oauth/github.html"
    };
}

function popup(url) {
    var width = 525,
        height = 525,
        screenX = window.screenX,
        screenY = window.screenY,
        outerWidth = window.outerWidth,
        outerHeight = window.outerHeight;

    var left = screenX + Math.max(outerWidth - width, 0) / 2;
    var top = screenY + Math.max(outerHeight - height, 0) / 2;

    var features = [
              "width=" + width,
              "height=" + height,
              "top=" + top,
              "left=" + left,
              "status=no",
              "resizable=yes",
              "toolbar=no",
              "menubar=no",
              "scrollbars=yes"];
    popup = window.open(url, "oauth", features.join(","));
    if (!popup) {
        alert("failed to pop up auth window");
    }
    // popup.uuid = lively.net.CloudStorage.addPendingRequest(req);
    popup.focus();
}

challengeForAuth =  function challengeForAuth() {
    var appInfo = getAppInfo();
    var url =
        "https://github.com/login/oauth/authorize/" +
        "?client_id=" + appInfo.clientId +
        "&response_type=token" +
        // "&state=" + uuid +
        "&redirect_uri=" + encodeURIComponent(appInfo.redirectUri);
    popup(url);
}
<commit_msg>auto commit<commit_after>function getAppInfo() {
    return {
        "clientId": "21b67bb82b7af444a7ef",
        "redirectUri": "https://livelykernel.github.io/lively4-core/oauth/github.html"
    };
}

function popup(url) {
    var width = 525,
        height = 525,
        screenX = window.screenX,
        screenY = window.screenY,
        outerWidth = window.outerWidth,
        outerHeight = window.outerHeight;

    var left = screenX + Math.max(outerWidth - width, 0) / 2;
    var top = screenY + Math.max(outerHeight - height, 0) / 2;

    var features = [
              "width=" + width,
              "height=" + height,
              "top=" + top,
              "left=" + left,
              "status=no",
              "resizable=yes",
              "toolbar=no",
              "menubar=no",
              "scrollbars=yes"];
    popup = window.open(url, "oauth", features.join(","));
    if (!popup) {
        alert("failed to pop up auth window");
    }
    // popup.uuid = lively.net.CloudStorage.addPendingRequest(req);
    popup.focus();
}

window.challengeForAuth =  function challengeForAuth() {
    var appInfo = getAppInfo();
    var url =
        "https://github.com/login/oauth/authorize/" +
        "?client_id=" + appInfo.clientId +
        "&response_type=token" +
        // "&state=" + uuid +
        "&redirect_uri=" + encodeURIComponent(appInfo.redirectUri);
    popup(url);
}

<|endoftext|>