<commit_before>function SigmaPublic(sigmaInstance) {
  var s = sigmaInstance;
  var self = this;
  sigma.classes.EventDispatcher.call(this);

  // Config:
  this.configProperties = function(a1, a2) {
    var res = s.config(a1, a2);
    return res == s ? self : res;
  };

  this.drawingProperties = function(a1, a2) {
    var res = s.plotter.config(a1, a2);
    return res == s.plotter ? self : res;
  };

  this.mouseProperties = function(a1, a2) {
    var res = s.mousecaptor.config(a1, a2);
    return res == s.mousecaptor ? self : res;
  };

  this.graphProperties = function(a1, a2) {
    var res = s.graph.config(a1, a2);
    return res == s.graph ? self : res;
  };

  this.getMouse = function() {
    return {
      mouseX: s.mousecaptor.mouseX,
      mouseY: s.mousecaptor.mouseY,
      down: s.mousecaptor.isMouseDown
    };
  };

  // Actions:
  this.position = function(stageX, stageY, ratio) {
    if (arguments.length == 0) {
      return {
        stageX: s.mousecaptor.stageX,
        stageY: s.mousecaptor.stageY,
        ratio: s.mousecaptor.ratio
      };
    }else {
      s.mousecaptor.stageX = stageX != undefined ?
        stageX :
        s.mousecaptor.stageX;
      s.mousecaptor.stageY = stageY != undefined ?
        stageY :
        s.mousecaptor.stageY;
      s.mousecaptor.ratio = ratio != undefined ?
        ratio :
        s.mousecaptor.ratio;

      return self;
    }
  };

  this.resize = function(w, h) {
    s.resize(w, h);
    return self;
  };

  this.draw = function(nodes, edges, labels, safe) {
    s.draw(nodes, edges, labels, safe);
    return self;
  };

  // Tasks methods:
  this.addGenerator = function(id, task, condition) {
    sigma.chronos.addGenerator(id + '_ext_' + s.id, task, condition);
    return self;
  };

  this.removeGenerator = function(id) {
    sigma.chronos.removeGenerator(id + '_ext_' + s.id);
    return self;
  };

  // Graph methods:
  this.addNode = function(id, params) {
    s.graph.addNode(id, params);
    return self;
  };

  this.addEdge = function(id, source, target, params) {
    s.graph.addEdge(id, source, target, params);
    return self;
  }

  this.dropNode = function(v) {
    s.graph.dropNode(v);
    return self;
  };

  this.dropEdge = function(v) {
    s.graph.dropEdge(v);
    return self;
  };

  this.getGraph = function() {
    return s.graph;
  };

  this.pushGraph = function(object, safe) {
    object.nodes && object.nodes.forEach(function(node) {
      node['id'] && (!safe || !s.graph.nodesIndex[node['id']]) &&
                    self.addNode(node['id'], node);
    });

    var isEdgeValid;
    object.edges && object.edges.forEach(function(edge) {
      validID = edge['source'] && edge['target'] && edge['id'];
      validID &&
        (!safe || !s.graph.edgesIndex[edge['id']]) &&
        self.addNode(
          edge['id'],
          edge['source'],
          edge['target'],
          edge
        );
    });

    return self;
  };

  this.emptyGraph = function() {
    s.graph.empty();
    return self;
  };

  this.getNodesCount = function() {
    return s.graph.nodes.length;
  };

  this.getEdgesCount = function() {
    return s.graph.edges.length;
  };

  this.iterNodes = function(fun, ids) {
    s.graph.iterNodes(fun, ids);
    return self;
  };

  this.iterEdges = function(fun, ids) {
    s.graph.iterEdges(fun, ids);
    return self;
  };

  this.getNodes = function(ids) {
    return s.graph.getNodes(ids);
  };

  this.getEdges = function(ids) {
    return s.graph.getEdges(ids);
  };

  // Monitoring
  this.activateMonitoring = function() {
    return s.monitor.activate();
  };

  this.desactivateMonitoring = function() {
    return s.monitor.desactivate();
  };

  // Events
  s.bind('downnodes upnodes', function(e) {
    self.dispatch(e.type, e.content);
  });

  s.graph.bind('overnodes outnodes', function(e) {
    self.dispatch(e.type, e.content);
  });
}

<commit_msg>minor changes<commit_after>function SigmaPublic(sigmaInstance) {
  var s = sigmaInstance;
  var self = this;
  sigma.classes.EventDispatcher.call(this);

  this.kill = function() {
    // TODO
  };

  // Config:
  this.configProperties = function(a1, a2) {
    var res = s.config(a1, a2);
    return res == s ? self : res;
  };

  this.drawingProperties = function(a1, a2) {
    var res = s.plotter.config(a1, a2);
    return res == s.plotter ? self : res;
  };

  this.mouseProperties = function(a1, a2) {
    var res = s.mousecaptor.config(a1, a2);
    return res == s.mousecaptor ? self : res;
  };

  this.graphProperties = function(a1, a2) {
    var res = s.graph.config(a1, a2);
    return res == s.graph ? self : res;
  };

  this.getMouse = function() {
    return {
      mouseX: s.mousecaptor.mouseX,
      mouseY: s.mousecaptor.mouseY,
      down: s.mousecaptor.isMouseDown
    };
  };

  // Actions:
  this.position = function(stageX, stageY, ratio) {
    if (arguments.length == 0) {
      return {
        stageX: s.mousecaptor.stageX,
        stageY: s.mousecaptor.stageY,
        ratio: s.mousecaptor.ratio
      };
    }else {
      s.mousecaptor.stageX = stageX != undefined ?
        stageX :
        s.mousecaptor.stageX;
      s.mousecaptor.stageY = stageY != undefined ?
        stageY :
        s.mousecaptor.stageY;
      s.mousecaptor.ratio = ratio != undefined ?
        ratio :
        s.mousecaptor.ratio;

      return self;
    }
  };

  this.resize = function(w, h) {
    s.resize(w, h);
    return self;
  };

  this.draw = function(nodes, edges, labels, safe) {
    s.draw(nodes, edges, labels, safe);
    return self;
  };

  // Tasks methods:
  this.addGenerator = function(id, task, condition) {
    sigma.chronos.addGenerator(id + '_ext_' + s.id, task, condition);
    return self;
  };

  this.removeGenerator = function(id) {
    sigma.chronos.removeGenerator(id + '_ext_' + s.id);
    return self;
  };

  // Graph methods:
  this.addNode = function(id, params) {
    s.graph.addNode(id, params);
    return self;
  };

  this.addEdge = function(id, source, target, params) {
    s.graph.addEdge(id, source, target, params);
    return self;
  }

  this.dropNode = function(v) {
    s.graph.dropNode(v);
    return self;
  };

  this.dropEdge = function(v) {
    s.graph.dropEdge(v);
    return self;
  };

  this.getGraph = function() {
    return s.graph;
  };

  this.pushGraph = function(object, safe) {
    object.nodes && object.nodes.forEach(function(node) {
      node['id'] && (!safe || !s.graph.nodesIndex[node['id']]) &&
                    self.addNode(node['id'], node);
    });

    var isEdgeValid;
    object.edges && object.edges.forEach(function(edge) {
      validID = edge['source'] && edge['target'] && edge['id'];
      validID &&
        (!safe || !s.graph.edgesIndex[edge['id']]) &&
        self.addNode(
          edge['id'],
          edge['source'],
          edge['target'],
          edge
        );
    });

    return self;
  };

  this.emptyGraph = function() {
    s.graph.empty();
    return self;
  };

  this.getNodesCount = function() {
    return s.graph.nodes.length;
  };

  this.getEdgesCount = function() {
    return s.graph.edges.length;
  };

  this.iterNodes = function(fun, ids) {
    s.graph.iterNodes(fun, ids);
    return self;
  };

  this.iterEdges = function(fun, ids) {
    s.graph.iterEdges(fun, ids);
    return self;
  };

  this.getNodes = function(ids) {
    return s.graph.getNodes(ids);
  };

  this.getEdges = function(ids) {
    return s.graph.getEdges(ids);
  };

  // Monitoring
  this.activateMonitoring = function() {
    return s.monitor.activate();
  };

  this.desactivateMonitoring = function() {
    return s.monitor.desactivate();
  };

  // Events
  s.bind('downnodes upnodes', function(e) {
    self.dispatch(e.type, e.content);
  });

  s.graph.bind('overnodes outnodes', function(e) {
    self.dispatch(e.type, e.content);
  });
}

<|endoftext|>


<commit_before>var express = require('express'),
    path = require('path'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),
    http  = require('http');

var port = process.env.PORT || 5000;
var visitor_count=0;
server.listen(port);
console.log("Connected on port " + port);
// ----------------------------------socket.io

var channels = {};
var senders={};

//Only because we have one dynamo
/*io.configure(function () {
  io.set("transports", ["xhr-polling"]);
  io.set("polling duration", 10);
});*/

io.sockets.on('connection', function (socket) {
    var initiatorChannel = '';
    if (!io.isConnected)
        io.isConnected = true;

    socket.on('new-channel', function (data) {
        console.log('CREATING NEW CHANNEL:: ' + data.channel);
        channels[data.channel] = data.channel;
        if(senders[data.sender] == undefined) {
            onNewNamespace(data.channel, data.sender);
            senders[data.sender] = data.sender;
        }
    });

    socket.on('presence', function (channel) {
        var isChannelPresent = !! channels[channel];
        socket.emit('presence', isChannelPresent);
        if (!isChannelPresent)
            initiatorChannel = channel;
    });

    socket.on('disconnect', function (channel) {
        if (initiatorChannel)
            channels[initiatorChannel] = null;
    });
});

function onNewNamespace(channel, sender) {
    io.of('/' + channel).on('connection', function (socket) {
        if (io.isConnected) {
            io.isConnected = false;
            socket.emit('connect', true);
        }
        var socketid = socket.id;
        console.error("VISITOR NUMBER " + ++visitor_count/3);
    	//socket.join(socket.handshake.sessionID);

        socket.on('message', function (data) {
            if (data.sender == sender)
                socket.broadcast.emit('message', data);
        });
	   socket.on('presence', function (data) {
            if (data.sender == sender) {
                console.log('Got PRESENCE--> ' + data);
                socket.broadcast.emit('presence', data);
            }
        });
	   socket.on('chat',funcion (data) {
		  console.log('GOT CHAT msg for ' + data.reciever + ' for id ' +socketid);
		  socketId = data.reciever;
          if(data.sender == sender) {
		      io.of('/' + channel).socket(socketId).emit('chat',data);
          } else {
            console.log('CHAT DROPPED ' +data.sender + ' ' + sender);
          }
	   });
        socket.on('call',function (data) {
          console.log('GOT CALL for for ' + data.reciever + ' for id ' +socketid);
          socketId = data.reciever;
          data.senderId = socketid;
          if(data.sender == sender) {
              io.of('/' + channel).socket(socketId).emit('call',data);
          } else {
            console.log('CALL DROPPED ' +data.sender + ' ' + sender);
          }
       });
    });
}

// ----------------------------------extras
//
app.enable('trust proxy');

app.use(express.compress());

app.get('/', function (req, res) {
    res.sendfile(__dirname + '/static/call/index1.html');
});

app.get('/admin', function (req, res) {
    res.sendfile(__dirname + '/static/call/admin1.html');
});

app.get('/conference.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference.js');
});

app.get('/conference-ui.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference-ui.js');
});

app.get('/chat', function (req, res) {
    res.sendfile(__dirname + '/static/text-chat.html');
});

app.get('/RTCMultiConnection', function (req, res) {
    res.sendfile(__dirname + '/static/RTCMultiConnection/index.html');
});

app.get('/call.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/call.js');
});

app.get('/tour', function (req, res) {
    res.sendfile(__dirname + '/static/tour.html');
});

app.get('/tour.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/tour.js');
});

app.get('/location', function(req, res) {
    console.log(req.ip);
    console.log(req.ips);
    res.header("Access-Control-Allow-Origin", "*");
    var ip = req.ip;
    var url = "http://www.geoplugin.net/json.gp?ip="+ip;
    if(ip == '127.0.0.1') {
    	url = "http://www.geoplugin.net/json.gp";
    }
    console.log("Making a request to fetch location data. for " + url);
    http.get(url, function(response) {
	      	console.log("Got location response status code: " + response.statusCode);
	      	res.setHeader('Content-Type','application/json');
		response.on('data', function (body) {
			    	console.log('location response : ' + body);
			    	res.send(body);
			      	});
	      }).on('error', function(e) {
		console.log("Got error: " + e.message);
		res.setHeader('Content-Type','application/json');
	      	res.send(e.message);
	});

});

app.use('/img',express.static(path.join(__dirname, 'static/img')));
app.use('/css',express.static(path.join(__dirname, 'static/css')));
app.use('/js',express.static(path.join(__dirname, 'static/js')));
app.use('/tmp',express.static(path.join(__dirname, 'static/tmp')));

app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});
<commit_msg>Switching off polling<commit_after>var express = require('express'),
    path = require('path'),
    app = express(),
    server = require('http').createServer(app),
    io = require('socket.io').listen(server),
    http  = require('http');

var port = process.env.PORT || 5000;
var visitor_count=0;
server.listen(port);
console.log("Connected on port " + port);
// ----------------------------------socket.io

var channels = {};
var senders={};

//Only because we have one dynamo
/*io.configure(function () {
  io.set("transports", ["xhr-polling"]);
  io.set("polling duration", 10);
});*/

io.sockets.on('connection', function (socket) {
    var initiatorChannel = '';
    if (!io.isConnected)
        io.isConnected = true;

    socket.on('new-channel', function (data) {
        console.log('CREATING NEW CHANNEL:: ' + data.channel);
        channels[data.channel] = data.channel;
        if(senders[data.sender] == undefined) {
            onNewNamespace(data.channel, data.sender);
            senders[data.sender] = data.sender;
        }
    });

    socket.on('presence', function (channel) {
        var isChannelPresent = !! channels[channel];
        socket.emit('presence', isChannelPresent);
        if (!isChannelPresent)
            initiatorChannel = channel;
    });

    socket.on('disconnect', function (channel) {
        if (initiatorChannel)
            channels[initiatorChannel] = null;
    });
});

function onNewNamespace(channel, sender) {
    io.of('/' + channel).on('connection', function (socket) {
        if (io.isConnected) {
            io.isConnected = false;
            socket.emit('connect', true);
        }
        var socketid = socket.id;
        console.error("VISITOR NUMBER " + ++visitor_count/3);
    	//socket.join(socket.handshake.sessionID);

        socket.on('message', function (data) {
            if (data.sender == sender)
                socket.broadcast.emit('message', data);
        });
	   socket.on('presence', function (data) {
            if (data.sender == sender) {
                console.log('PRESENCE --> ' +data);
                socket.broadcast.emit('presence', data);
            }
        });
	   socket.on('chat',function (data) {
		  console.log('GOT CHAT msg for ' + data.reciever + ' for id ' +socketid);
		  socketId = data.reciever;
          if(data.sender == sender) {
		      io.of('/' + channel).socket(socketId).emit('chat',data);
          } else {
            console.log('CHAT DROPPED ' +data.sender + ' ' + sender);
          }
	   });
        socket.on('call',function (data) {
          console.log('GOT CALL for for ' + data.reciever + ' for id ' +socketid);
          socketId = data.reciever;
          data.senderId = socketid;
          if(data.sender == sender) {
              io.of('/' + channel).socket(socketId).emit('call',data);
          } else {
            console.log('CALL DROPPED ' +data.sender + ' ' + sender);
          }
       });
    });
}

// ----------------------------------extras
//
app.enable('trust proxy');

app.use(express.compress());

app.get('/', function (req, res) {
    res.sendfile(__dirname + '/static/call/index1.html');
});

app.get('/admin', function (req, res) {
    res.sendfile(__dirname + '/static/call/admin1.html');
});

app.get('/conference.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference.js');
});

app.get('/conference-ui.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/video-conferencing/conference-ui.js');
});

app.get('/chat', function (req, res) {
    res.sendfile(__dirname + '/static/text-chat.html');
});

app.get('/RTCMultiConnection', function (req, res) {
    res.sendfile(__dirname + '/static/RTCMultiConnection/index.html');
});

app.get('/call.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/call.js');
});

app.get('/tour', function (req, res) {
    res.sendfile(__dirname + '/static/tour.html');
});

app.get('/tour.js', function (req, res) {
    res.setHeader('Content-Type', 'application/javascript');
    res.sendfile(__dirname + '/static/tour.js');
});

app.get('/location', function(req, res) {
    console.log(req.ip);
    console.log(req.ips);
    res.header("Access-Control-Allow-Origin", "*");
    var ip = req.ip;
    var url = "http://www.geoplugin.net/json.gp?ip="+ip;
    if(ip == '127.0.0.1') {
    	url = "http://www.geoplugin.net/json.gp";
    }
    console.log("Making a request to fetch location data. for " + url);
    http.get(url, function(response) {
	      	console.log("Got location response status code: " + response.statusCode);
	      	res.setHeader('Content-Type','application/json');
		response.on('data', function (body) {
			    	console.log('location response : ' + body);
			    	res.send(body);
			      	});
	      }).on('error', function(e) {
		console.log("Got error: " + e.message);
		res.setHeader('Content-Type','application/json');
	      	res.send(e.message);
	});

});

app.use('/img',express.static(path.join(__dirname, 'static/img')));
app.use('/css',express.static(path.join(__dirname, 'static/css')));
app.use('/js',express.static(path.join(__dirname, 'static/js')));
app.use('/tmp',express.static(path.join(__dirname, 'static/tmp')));

app.use(function (req, res, next) {

    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

    // Pass to next layer of middleware
    next();
});
<|endoftext|>


<commit_before>angular.module('services', [])

.factory('Auth', function($cordovaOauth, Spotify) {
  const CLIENT_ID = 'd3fe3362f8634a1b82b89ab344238891'
  const SCOPE = ['user-read-private', 'playlist-read-private', 'playlist-modify-public', 'playlist-modify-private']

  //Private
  /**
   * Utility function valled by verifyToken
   * @return {promise} - Returns promise that resolves after user logs in
   */
  function performLogin() {
    return $cordovaOauth.spotify(CLIENT_ID, SCOPE).then(function(result) {
      window.localStorage.setItem('spotify-token', result.access_token)
      Spotify.setAuthToken(result.access_token)
    }, function(error) {
      console.dir(error)
    })
  }

  //Public
  /**
   * Returns id of current user
   * @return {string} - user id of current user
   */
  function getCurrentUser() {
    return Spotify.getCurrentUser().then(user => { return user.id })
  }

  /**
   * Performed upon entry to every view in app
   * Does these things:
   *   -Checks for stored auth token
   *   -Sets auth token if stored token found
   *   -If not found, prompts user for login then sets auth token
   * @return {Promise} - Returns promise either after token is found, or after login succeeded
   */
  function verify() {
    let storedToken = window.localStorage.getItem('spotify-token')
    console.log('checking for Auth')
    if(storedToken) {
      Spotify.setAuthToken(storedToken)
      return Promise.resolve()
    } else {
      return performLogin()
    }
  }

  return {
    getCurrentUser,
    verify
  }
})

.factory('Playlists', function(Spotify, Auth) {
  return {
    /**
     * Fetches current user's id, then returns array of playlists
     * @return {array} - array of playlist objects
     */
    get: function() {
      return Auth.getCurrentUser().then(userid => {
        return Spotify.getUserPlaylists(userid).then(data => data.items)
      })
    },
    /**
     * Fetches current user's id, then playlists, then returns array of playlist ids
     * @return {array} - array of playlist ids
     */
    getIds: function() {
      return Auth.getCurrentUser().then(userid => {
        return Spotify.getUserPlaylists(userid).then(data => {
          let ids = []
          data.items.forEach(item => ids.push(item.id))
          return ids
        })
      })
    },
    commitChanges: commitChanges
  }

  /**
   * Takes locally saved track list and makes necessary reorder and delete requests to spotify
   * to update playlist
   * @param  {array} oldList - current state of playlist on Spotify before commiting changes
   * @param  {array} newList - locally saved array of track objects
   */
  function commitChanges(oldList, newList, userid, listid) {
    let oldUris = []
    let newUris = []
    oldList.forEach(item => oldUris.push(item.track.uri))
    newList.forEach(item => newUris.push(item.track.uri))

    let deleted = oldUris.filter(x => newUris.indexOf(x) == -1);
    console.dir(deleted)
    Spotify
      .removePlaylistTracks(userid, listid, deleted)
      .then(() => console.log('tracks deleted'))
  }

})
<commit_msg>refactoring to perform get request before every reorder<commit_after>angular.module('services', [])

.factory('Auth', function($cordovaOauth, Spotify) {
  const CLIENT_ID = 'd3fe3362f8634a1b82b89ab344238891'
  const SCOPE = ['user-read-private', 'playlist-read-private', 'playlist-modify-public', 'playlist-modify-private']

  //Private
  /**
   * Utility function valled by verifyToken
   * @return {promise} - Returns promise that resolves after user logs in
   */
  function performLogin() {
    return $cordovaOauth.spotify(CLIENT_ID, SCOPE).then(function(result) {
      window.localStorage.setItem('spotify-token', result.access_token)
      Spotify.setAuthToken(result.access_token)
    }, function(error) {
      console.dir(error)
    })
  }

  //Public
  /**
   * Returns id of current user
   * @return {string} - user id of current user
   */
  function getCurrentUser() {
    return Spotify.getCurrentUser().then(user => { return user.id })
  }

  /**
   * Performed upon entry to every view in app
   * Does these things:
   *   -Checks for stored auth token
   *   -Sets auth token if stored token found
   *   -If not found, prompts user for login then sets auth token
   * @return {Promise} - Returns promise either after token is found, or after login succeeded
   */
  function verify() {
    let storedToken = window.localStorage.getItem('spotify-token')
    console.log('checking for Auth')
    if(storedToken) {
      Spotify.setAuthToken(storedToken)
      return Promise.resolve()
    } else {
      return performLogin()
    }
  }

  return {
    getCurrentUser,
    verify
  }
})

.factory('Playlists', function(Spotify, Auth) {
  return {
    /**
     * Fetches current user's id, then returns array of playlists
     * @return {array} - array of playlist objects
     */
    get: function() {
      return Auth.getCurrentUser().then(userid => {
        return Spotify.getUserPlaylists(userid).then(data => data.items)
      })
    },
    /**
     * Fetches current user's id, then playlists, then returns array of playlist ids
     * @return {array} - array of playlist ids
     */
    getIds: function() {
      return Auth.getCurrentUser().then(userid => {
        return Spotify.getUserPlaylists(userid).then(data => {
          let ids = []
          data.items.forEach(item => ids.push(item.id))
          return ids
        })
      })
    },
    commitChanges: commitChanges
  }

  /**
   * Takes locally saved track list and makes necessary reorder and delete requests to spotify
   * to update playlist
   * @param  {array} oldList - current state of playlist on Spotify before commiting changes
   * @param  {array} newList - locally saved array of track objects
   */
  function commitChanges(oldList, newList, userid, listid) {
    let oldUris = []
    let newUris = []
    oldList.forEach(item => oldUris.push(item.track.uri))
    newList.forEach(item => newUris.push(item.track.uri))

    let deleted = oldUris.filter(x => newUris.indexOf(x) == -1)
    let remaining = oldUris.filter(x => newUris.indexOf(x) >= 0)

    console.dir(newUris)
    console.dir(remaining)
    Spotify
      .removePlaylistTracks(userid, listid, deleted)
      .then(() => reorderTracks())

    let i = 0
    function reorderTracks() {
      if(i > newUris.length - 1) {
        i = 0
        return
      }
      console.log(`${i}: moving track from ${remaining.indexOf(newUris[i])} to before ${i}`)
      Spotify.reorderPlaylistTracks(userid, listid, {
        range_start: remaining.indexOf(newUris[i]),
        insert_before: i
      }).then(() => {
        i++
        reorderTracks()
      })
    }
  }
})

<|endoftext|>


<commit_before>'use strict';

const Boom = require('boom');

const createLambdaContext = require('./createLambdaContext');
const functionHelper = require('./functionHelper');
const debugLog = require('./debugLog');
const utils = require('./utils');
const _ = require('lodash');
const authCanExecuteResource = require('./authCanExecuteResource');

module.exports = function createAuthScheme(authFun, authorizerOptions, funName, endpointPath, options, serverlessLog, servicePath, serverless) {
  const authFunName = authorizerOptions.name;

  let identityHeader = 'authorization';

  if (authorizerOptions.type !== 'request') {
    const identitySourceMatch = /^method.request.header.((?:\w+-?)+\w+)$/.exec(authorizerOptions.identitySource);
    if (!identitySourceMatch || identitySourceMatch.length !== 2) {
      throw new Error(`Serverless Offline only supports retrieving tokens from the headers (λ: ${authFunName})`);
    }
    identityHeader = identitySourceMatch[1].toLowerCase();
  }

  const funOptions = functionHelper.getFunctionOptions(authFun, funName, servicePath);

  const serviceRuntime = serverless.service.provider.runtime;

  // Create Auth Scheme
  return () => ({
    authenticate(request, reply) {
      process.env = _.extend({}, serverless.service.provider.environment, authFun.environment, process.env);
      console.log(''); // Just to make things a little pretty
      serverlessLog(`Running Authorization function for ${request.method} ${request.path} (λ: ${authFunName})`);

      // Get Authorization header
      const req = request.raw.req;

      // Get path params
      const pathParams = {};
      Object.keys(request.params).forEach(key => {
        // aws doesn't auto decode path params - hapi does
        pathParams[key] = encodeURIComponent(request.params[key]);
      });

      let event, handler;

      // Create event Object for authFunction
      //   methodArn is the ARN of the function we are running we are authorizing access to (or not)
      //   Account ID and API ID are not simulated
      if (authorizerOptions.type === 'request') {
        event = {
          type: 'REQUEST',
          path: request.path,
          httpMethod: request.method.toUpperCase(),
          headers: {},
          multiValueHeaders: {},
          pathParameters: utils.nullIfEmpty(pathParams),
          queryStringParameters: request.query ? utils.normalizeQuery(request.query) : {},
          multiValueQueryStringParameters: request.query ? utils.normalizeMultiValueQuery(request.query) : {},
        };
        if (req.rawHeaders) {
          for (let i = 0; i < req.rawHeaders.length; i += 2) {
            event.headers[req.rawHeaders[i]] = req.rawHeaders[i + 1];
            event.multiValueHeaders[req.rawHeaders[i]] = (event.multiValueHeaders[req.rawHeaders[i]] || []).concat(req.rawHeaders[i + 1]);
          }
        }
        else {
          event.headers = Object.assign(request.headers, utils.capitalizeKeys(request.headers));
          event.multiValueHeaders = utils.normalizeMultiValueQuery(event.headers);
        }
      }
      else {
        const authorization = req.headers[identityHeader];
        debugLog(`Retrieved ${identityHeader} header ${authorization}`);
        event = {
          type: 'TOKEN',
          authorizationToken: authorization,
        };
      }
      event.methodArn = `arn:aws:execute-api:${options.region}:random-account-id:random-api-id/${options.stage}/${request.method.toUpperCase()}${request.path.replace(new RegExp(`^/${options.stage}`), '')}`;

      // Create the Authorization function handler
      try {
        handler = functionHelper.createHandler(funOptions, options);
      }
      catch (err) {
        debugLog(`create authorization function handler error: ${err}`);

        return reply(Boom.badImplementation(null, `Error while loading ${authFunName}: ${err.message}`));
      }

      let done = false;
      // Creat the Lambda Context for the Auth function
      const lambdaContext = createLambdaContext(authFun, (err, result, fromPromise) => {
        if (done) {
          const warning = fromPromise
            ? `Warning: Auth function '${authFunName}' returned a promise and also uses a callback!\nThis is problematic and might cause issues in your lambda.`
            : `Warning: callback called twice within Auth function '${authFunName}'!`;

          serverlessLog(warning);

          return;
        }

        done = true;

        // Return an unauthorized response
        const onError = error => {
          serverlessLog(`Authorization function returned an error response: (λ: ${authFunName})`, error);

          return reply(Boom.unauthorized('Unauthorized'));
        };

        if (err) {
          return onError(err);
        }

        const onSuccess = policy => {
        // Validate that the policy document has the principalId set
          if (!policy.principalId) {
            serverlessLog(`Authorization response did not include a principalId: (λ: ${authFunName})`, err);

            return reply(Boom.forbidden('No principalId set on the Response'));
          }

          if (!authCanExecuteResource(policy.policyDocument, event.methodArn)) {
            serverlessLog(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`, err);

            return reply(Boom.forbidden('User is not authorized to access this resource'));
          }

          serverlessLog(`Authorization function returned a successful response: (λ: ${authFunName})`, policy);

          // Set the credentials for the rest of the pipeline
          return reply.continue({ credentials: { user: policy.principalId, context: policy.context, usageIdentifierKey: policy.usageIdentifierKey } });
        };

        if (result && typeof result.then === 'function' && typeof result.catch === 'function') {
          debugLog('Auth function returned a promise');
          result.then(onSuccess).catch(onError);
        }
        else if (result instanceof Error) {
          onError(result);
        }
        else {
          onSuccess(result);
        }
      });

      const x = handler(event, lambdaContext, lambdaContext.done);

      // Promise support
      if ((serviceRuntime === 'nodejs8.10' || serviceRuntime === 'babel') && !done) {
        if (x && typeof x.then === 'function' && typeof x.catch === 'function') x.then(lambdaContext.succeed).catch(lambdaContext.fail);
        else if (x instanceof Error) lambdaContext.fail(x);
      }
    },
  });
};
<commit_msg>add some requestContext to auth event<commit_after>'use strict';

const Boom = require('boom');

const createLambdaContext = require('./createLambdaContext');
const functionHelper = require('./functionHelper');
const debugLog = require('./debugLog');
const utils = require('./utils');
const _ = require('lodash');
const authCanExecuteResource = require('./authCanExecuteResource');

module.exports = function createAuthScheme(authFun, authorizerOptions, funName, endpointPath, options, serverlessLog, servicePath, serverless) {
  const authFunName = authorizerOptions.name;

  let identityHeader = 'authorization';

  if (authorizerOptions.type !== 'request') {
    const identitySourceMatch = /^method.request.header.((?:\w+-?)+\w+)$/.exec(authorizerOptions.identitySource);
    if (!identitySourceMatch || identitySourceMatch.length !== 2) {
      throw new Error(`Serverless Offline only supports retrieving tokens from the headers (λ: ${authFunName})`);
    }
    identityHeader = identitySourceMatch[1].toLowerCase();
  }

  const funOptions = functionHelper.getFunctionOptions(authFun, funName, servicePath);

  const serviceRuntime = serverless.service.provider.runtime;

  // Create Auth Scheme
  return () => ({
    authenticate(request, reply) {
      process.env = _.extend({}, serverless.service.provider.environment, authFun.environment, process.env);
      console.log(''); // Just to make things a little pretty
      serverlessLog(`Running Authorization function for ${request.method} ${request.path} (λ: ${authFunName})`);

      // Get Authorization header
      const req = request.raw.req;

      // Get path params
      const pathParams = {};
      Object.keys(request.params).forEach(key => {
        // aws doesn't auto decode path params - hapi does
        pathParams[key] = encodeURIComponent(request.params[key]);
      });

      let event, handler;

      // Create event Object for authFunction
      //   methodArn is the ARN of the function we are running we are authorizing access to (or not)
      //   Account ID and API ID are not simulated
      if (authorizerOptions.type === 'request') {
        event = {
          type: 'REQUEST',
          path: request.path,
          httpMethod: request.method.toUpperCase(),
          headers: {},
          multiValueHeaders: {},
          pathParameters: utils.nullIfEmpty(pathParams),
          queryStringParameters: request.query ? utils.normalizeQuery(request.query) : {},
          multiValueQueryStringParameters: request.query ? utils.normalizeMultiValueQuery(request.query) : {},
        };
        if (req.rawHeaders) {
          for (let i = 0; i < req.rawHeaders.length; i += 2) {
            event.headers[req.rawHeaders[i]] = req.rawHeaders[i + 1];
            event.multiValueHeaders[req.rawHeaders[i]] = (event.multiValueHeaders[req.rawHeaders[i]] || []).concat(req.rawHeaders[i + 1]);
          }
        }
        else {
          event.headers = Object.assign(request.headers, utils.capitalizeKeys(request.headers));
          event.multiValueHeaders = utils.normalizeMultiValueQuery(event.headers);
        }
      }
      else {
        const authorization = req.headers[identityHeader];
        debugLog(`Retrieved ${identityHeader} header ${authorization}`);
        event = {
          type: 'TOKEN',
          authorizationToken: authorization,
        };
      }

      const httpMethod = request.method.toUpperCase();
      const apiId = 'random-api-id';
      const accountId = 'random-account-id';
      const resourcePath = request.path.replace(new RegExp(`^/${options.stage}`), '');

      event.methodArn = `arn:aws:execute-api:${options.region}:${accountId}:${apiId}/${options.stage}/${httpMethod}${resourcePath}`;

      event.requestContext = {
        accountId,
        resourceId: 'random-resource-id',
        stage: options.stage,
        requestId: 'random-request-id',
        resourcePath,
        httpMethod,
        apiId
      };

      // Create the Authorization function handler
      try {
        handler = functionHelper.createHandler(funOptions, options);
      }
      catch (err) {
        debugLog(`create authorization function handler error: ${err}`);

        return reply(Boom.badImplementation(null, `Error while loading ${authFunName}: ${err.message}`));
      }

      let done = false;
      // Creat the Lambda Context for the Auth function
      const lambdaContext = createLambdaContext(authFun, (err, result, fromPromise) => {
        if (done) {
          const warning = fromPromise
            ? `Warning: Auth function '${authFunName}' returned a promise and also uses a callback!\nThis is problematic and might cause issues in your lambda.`
            : `Warning: callback called twice within Auth function '${authFunName}'!`;

          serverlessLog(warning);

          return;
        }

        done = true;

        // Return an unauthorized response
        const onError = error => {
          serverlessLog(`Authorization function returned an error response: (λ: ${authFunName})`, error);

          return reply(Boom.unauthorized('Unauthorized'));
        };

        if (err) {
          return onError(err);
        }

        const onSuccess = policy => {
        // Validate that the policy document has the principalId set
          if (!policy.principalId) {
            serverlessLog(`Authorization response did not include a principalId: (λ: ${authFunName})`, err);

            return reply(Boom.forbidden('No principalId set on the Response'));
          }

          if (!authCanExecuteResource(policy.policyDocument, event.methodArn)) {
            serverlessLog(`Authorization response didn't authorize user to access resource: (λ: ${authFunName})`, err);

            return reply(Boom.forbidden('User is not authorized to access this resource'));
          }

          serverlessLog(`Authorization function returned a successful response: (λ: ${authFunName})`, policy);

          // Set the credentials for the rest of the pipeline
          return reply.continue({ credentials: { user: policy.principalId, context: policy.context, usageIdentifierKey: policy.usageIdentifierKey } });
        };

        if (result && typeof result.then === 'function' && typeof result.catch === 'function') {
          debugLog('Auth function returned a promise');
          result.then(onSuccess).catch(onError);
        }
        else if (result instanceof Error) {
          onError(result);
        }
        else {
          onSuccess(result);
        }
      });

      const x = handler(event, lambdaContext, lambdaContext.done);

      // Promise support
      if ((serviceRuntime === 'nodejs8.10' || serviceRuntime === 'babel') && !done) {
        if (x && typeof x.then === 'function' && typeof x.catch === 'function') x.then(lambdaContext.succeed).catch(lambdaContext.fail);
        else if (x instanceof Error) lambdaContext.fail(x);
      }
    },
  });
};
<|endoftext|>


<commit_before>(function () {

var
  _             = Flotr._,

  DOT           = '.',

  CN_EXAMPLE    = 'flotr-example',
  CN_LABEL      = 'flotr-example-label',
  CN_TITLE      = 'flotr-example-title',
  CN_MARKUP     = 'flotr-example-description',
  CN_EDITOR     = 'flotr-example-editor',

  ID_GRAPH      = 'flotr-example-graph',

  TEMPLATE      = '' +
    '
' +
      '

' +
      '

' +
      '

' +
    '
',

Example = function (o) {

  this.options = o;
  this.example = null;

  this._initNodes();
};

Example.prototype = {

  setExample : function (example) {

    this.example = example;

    Math.seedrandom(example.key);
    this._exampleNode.css({ display: 'block' });

    if (!this._editor) {
      this._editor = new Flotr.Examples.Editor(this._editorNode, {
          example : example.callback
      });
    } else {
      this._editor.setExample(example.callback);
    }
  },

  executeCallback : function (example, node) {
    if (!_.isElement(node)) node = node[0];
    var args = (example.args ? [node].concat(example.args) : [node]);
    Math.seedrandom(example.key);
    return example.callback.apply(this, args);
  },

  _initNodes : function () {

    var
      node    = this.options.node,
      example = $(TEMPLATE);

    this._titleNode   = example.find(DOT + CN_TITLE);
    this._markupNode  = example.find(DOT + CN_MARKUP);
    this._editorNode  = example.find(DOT + CN_EDITOR);
    this._exampleNode = example;

    node.append(example);
  }
};

Flotr.Examples.Example = Example;

})();
<commit_msg>Added title and description.<commit_after>(function () {

var
  _             = Flotr._,

  DOT           = '.',

  CN_EXAMPLE    = 'flotr-example',
  CN_LABEL      = 'flotr-example-label',
  CN_TITLE      = 'flotr-example-title',
  CN_MARKUP     = 'flotr-example-description',
  CN_EDITOR     = 'flotr-example-editor',

  ID_GRAPH      = 'flotr-example-graph',

  TEMPLATE      = '' +
    '
' +
      '

' +
      '

' +
      '

' +
    '
',

Example = function (o) {

  this.options = o;
  this.example = null;

  this._initNodes();
};

Example.prototype = {

  setExample : function (example) {

    this.example = example;

    Math.seedrandom(example.key);
    this._exampleNode.css({ display: 'block' });
    this._titleNode.html(example.name || '');
    this._markupNode.html(example.description || '');

    if (!this._editor) {
      this._editor = new Flotr.Examples.Editor(this._editorNode, {
          example : example.callback
      });
    } else {
      this._editor.setExample(example.callback);
    }
  },

  executeCallback : function (example, node) {
    if (!_.isElement(node)) node = node[0];
    var args = (example.args ? [node].concat(example.args) : [node]);
    Math.seedrandom(example.key);
    return example.callback.apply(this, args);
  },

  _initNodes : function () {

    var
      node    = this.options.node,
      example = $(TEMPLATE);

    this._titleNode   = example.find(DOT + CN_TITLE);
    this._markupNode  = example.find(DOT + CN_MARKUP);
    this._editorNode  = example.find(DOT + CN_EDITOR);
    this._exampleNode = example;

    node.append(example);
  }
};

Flotr.Examples.Example = Example;

})();
<|endoftext|>


<commit_before>import knex from '../knex';
import PollingMode from './PollingMode';
import { canSee, canMutate, Models } from '../../core/accessControl';
import { Groups } from '../../organization';
import { transactify } from './utils';
// eslint-disable-next-line no-unused-vars
function checkCanSee(viewer, data) {
  // TODO change data returned based on permissions
  return true;
}

const MAX_DESCRIPTION_LENGTH = 10000;

const checkOption = (option, counters) => {
  const validated = {};
  if ('id' in option) {
    // check uniqness of id
    if (
      option.id > counters.currentId &&
      !counters.otherIds.includes(option.id)
    ) {
      validated.id = option.id;
      counters.currentId = option.id; // eslint-disable-line
      counters.otherIds.push(option.id);
    }
  }
  if ('order' in option) {
    // check right order
    if (
      option.order > counters.currentOrder &&
      !counters.otherOrders.includes(option.order)
    ) {
      validated.order = option.order;
      counters.currentOrder = option.order; // eslint-disable-line
      counters.otherOrders.push(option.order);
    }
  }
  if ('description' in option) {
    // check keys , content
    const description = Object.keys(option.description).reduce(
      (obj, locale) => {
        const text =
          option.description[locale] && option.description[locale].trim();
        if (text.length < MAX_DESCRIPTION_LENGTH && text.length > 0) {
          obj[locale] = text; // eslint-disable-line
        }
        return obj;
      },
      {},
    );
    if (Object.keys(description).length) {
      validated.description = description;
    }
  }
  if ('numVotes' in option) {
    //
  } else {
    validated.numVotes = 0;
  }

  if (
    'id' in validated &&
    'order' in validated &&
    'description' in validated &&
    'numVotes' in validated
  ) {
    return validated;
  }
  throw new Error('Option not correct');
};
const validateOptions = options => {
  const counters = {
    currentId: -1,
    currentOrder: -1,
    otherIds: [],
    otherOrders: [],
  };
  const data = options.map(option => checkOption(option, counters));
  return data;
};

const validateDates = data => {
  const serverTime = new Date();
  const startTime =
    data && data.startTime ? new Date(data.startTime) : serverTime;
  if (!startTime.getMonth || typeof startTime.getMonth !== 'function')
    return null;

  let endTime;
  if (data && data.endTime) {
    endTime = new Date(data.endTime);
  } else {
    endTime = new Date();
    endTime.setDate(startTime.getDate() + 3);
  }
  if (!endTime.getMonth || typeof endTime.getMonth !== 'function') return null;
  if (startTime < serverTime || startTime >= endTime)
    throw Error('DateTime wrong');
  return { startTime, endTime };
};

class Poll {
  constructor(data) {
    this.id = data.id;
    this.pollingModeId = data.polling_mode_id;
    this.secret = data.secret;
    this.threshold = data.threshold;
    this.upvotes = data.upvotes;
    this.downvotes = data.downvotes;
    this.numVoter = data.num_voter;
    this.startTime = data.start_time;
    this.endTime = data.end_time;
    this.closedAt = data.closed_at;
    this.extended = data.extended;
    this.multipeChoice = data.multipe_choice;
    this.options = data.options;
  }

  static async gen(viewer, id, { polls }) {
    if (!id) return null;
    const data = await polls.load(id);
    if (data === null) return null;
    return canSee(viewer, data, Models.POLL) ? new Poll(data) : null;
  }

  // eslint-disable-next-line class-methods-use-this
  isVotable() {
    if (this.closedAt || new Date(this.endTime) < new Date()) {
      return false;
    }
    // TODO regional voting here
    return true;
  }

  async isUnipolar(viewer, loaders) {
    const mode = await PollingMode.gen(viewer, this.pollingModeId, loaders);
    return mode.unipolar === true;
  }

  async isCommentable(viewer, loaders) {
    if (this.closedAt) return false;
    const mode = await PollingMode.gen(viewer, this.pollingModeId, loaders);
    return mode.withStatements === true;
  }
  /* eslint-disable class-methods-use-this */

  // eslint-disable-next-line no-unused-vars
  async validate(viewer) {
    // TODO
    return true;
  }

  /* eslint-enable class-methods-use-this */
  static async create(viewer, data, loaders, trx) {
    // authorize
    if (!canMutate(viewer, data, Models.POLL)) return null;

    // validate
    if (!data.pollingModeId) return null;
    if (!data.threshold) return null;

    const newData = { created_at: new Date() };

    if (data.options) {
      // check options
      const validatedOptions = validateOptions(data.options);
      newData.options = JSON.stringify(validatedOptions);
    }
    if ('extended' in data) {
      if (newData.options && newData.options.length) {
        newData.extended = data.extended;
      }
    }
    //

    if ('multipleChoice' in data) {
      newData.multipe_choice = data.multipeChoice;
    }
    if ('secret' in data) {
      newData.secret = data.secret;
    }

    const { startTime, endTime } = validateDates(data);

    if (startTime) {
      newData.start_time = startTime;
    }
    if (endTime) {
      newData.end_time = endTime;
    }
    if (data.pollingModeId) {
      newData.polling_mode_id = data.pollingModeId;
    }

    if (data.threshold) {
      newData.threshold = data.threshold;
    }

    // create

    const createPoll = async transaction => {
      const pollingModeData = await knex('polling_modes')
        .transacting(transaction)
        .where({ id: data.pollingModeId })
        .limit(1)
        .select('*');
      if (!pollingModeData) throw Error('No valid PollingMode provided');
      const pollingMode = new PollingMode(pollingModeData);
      let numVoter = 0;

      if (!newData.extended) {
        const options = [
          { id: 0, order: 0, numVotes: 0, description: { _default: 'up' } },
        ];

        if (!pollingMode.unipolar) {
          options.push({
            id: 1,
            order: 1,
            numVotes: 0,
            description: { _default: 'down' },
          });
        }
        newData.options = JSON.stringify(options);
      }

      if (pollingMode.thresholdRef === 'all') {
        // TODO change completely in case of group model
        if (data.workTeamId) {
          numVoter = await knex('user_work_teams')
            .transacting(transaction)
            .where({ work_team_id: data.workTeamId })
            .join('users', 'users.id', 'user_work_teams.user_id') // bc also viewers can be members
            .whereRaw('users.groups & ? > 0', [Groups.VIEWER]) // TODO whitelist
            .count('users.id');
        } else {
          numVoter = await transaction
            .whereRaw('groups & ? > 0', [Groups.VOTER]) // TODO whitelist
            .count('id')
            .into('users');
        }
        numVoter = Number(numVoter[0].count);
        if (numVoter < 1) throw Error('Not enough user');
      }

      if (numVoter) {
        newData.num_voter = numVoter;
      }

      const [pollinDB = null] = await knex('polls')
        .transacting(transaction)
        .insert(newData)
        .returning('*');
      return pollinDB;
    };

    const newPoll = await transactify(createPoll, knex, trx);
    if (!newPoll) return null;
    return new Poll(newPoll);
  }

  static async update(viewer, data, loaders, trx) {
    // authorize
    if (!canMutate(viewer, data, Models.POLL)) return null;
    // validate
    if (!data.id) return null;
    const newData = {};
    if (data.closedAt) {
      newData.closed_at = data.closedAt;
      newData.updated_at = new Date();
    }

    const updatePoll = async transaction =>
      knex('polls')
        .transacting(transaction)
        .where({ id: data.id })
        .update(newData)
        .returning('*');

    const pollData = await transactify(updatePoll, knex, trx);
    return pollData && new Poll(pollData);
  }
}

export default Poll;
<commit_msg>added flowtypes to poll, fixed some issues<commit_after>// @flow

import knex from '../knex';
import PollingMode from './PollingMode';
import { canSee, canMutate, Models } from '../../core/accessControl';
import { Groups } from '../../organization';
import { transactify } from './utils';
// eslint-disable-next-line no-unused-vars
function checkCanSee(viewer, data) {
  // TODO change data returned based on permissions
  return true;
}

const MAX_DESCRIPTION_LENGTH = 10000;

const checkOption = (option, counters) => {
  const validated = {};
  if ('pos' in option) {
    // check uniqness of pos
    if (
      option.pos > counters.currentPos &&
      !counters.otherPos.includes(option.pos)
    ) {
      validated.pos = option.pos;
      counters.currentPos = option.pos; // eslint-disable-line
      counters.otherPos.push(option.pos);
    }
  }
  if ('order' in option) {
    // check right order
    if (
      option.order > counters.currentOrder &&
      !counters.otherOrders.includes(option.order)
    ) {
      validated.order = option.order;
      counters.currentOrder = option.order; // eslint-disable-line
      counters.otherOrders.push(option.order);
    }
  }
  if ('description' in option) {
    // check keys , content
    const description = Object.keys(option.description).reduce(
      (obj, locale) => {
        const text =
          option.description[locale] && option.description[locale].trim();
        if (text.length < MAX_DESCRIPTION_LENGTH && text.length > 0) {
          obj[locale] = text; // eslint-disable-line
        }
        return obj;
      },
      {},
    );
    if (Object.keys(description).length) {
      validated.description = description;
    }
  }
  if ('numVotes' in option) {
    //
  } else {
    validated.numVotes = 0;
  }

  if (
    'pos' in validated &&
    'order' in validated &&
    'description' in validated &&
    'numVotes' in validated
  ) {
    return validated;
  }
  throw new Error('Option not correct');
};
const validateOptions = options => {
  const counters = {
    currentPos: -1,
    currentOrder: -1,
    otherPos: [],
    otherOrders: [],
  };
  const data = options.map(option => checkOption(option, counters));
  return data;
};

const validateDates = data => {
  const serverTime = new Date();
  const startTime =
    data && data.startTime ? new Date(data.startTime) : serverTime;
  if (!startTime.getMonth || typeof startTime.getMonth !== 'function')
    return null;

  let endTime;
  if (data && data.endTime) {
    endTime = new Date(data.endTime);
  } else {
    endTime = new Date();
    endTime.setDate(startTime.getDate() + 3);
  }
  if (!endTime.getMonth || typeof endTime.getMonth !== 'function') return null;
  if (startTime < serverTime || startTime >= endTime)
    throw Error('DateTime wrong');
  return { startTime, endTime };
};

class Poll {
  id: ID;

  pollingModeId: ID;

  secret: boolean;

  threshold: number;

  numVoter: number;

  startTime: ?string;

  endTime: string;

  closedAt: ?string;

  extended: boolean;

  multipleChoice: boolean;

  options: OptionShape[];

  numVotes: number;

  constructor(data) {
    this.id = data.id;
    this.pollingModeId = data.polling_mode_id;
    this.secret = data.secret;
    this.threshold = data.threshold;
    this.numVoter = data.num_voter;
    this.startTime = data.start_time;
    this.endTime = data.end_time;
    this.closedAt = data.closed_at;
    this.extended = data.extended;
    this.multipleChoice = data.multiple_choice;
    this.options = data.options;
    this.numVotes = data.num_votes;
  }

  static async gen(viewer: ViewerShape, id: ID, { polls }) {
    if (!id) return null;
    const data = await polls.load(id);
    if (data === null) return null;
    return canSee(viewer, data, Models.POLL) ? new Poll(data) : null;
  }

  // eslint-disable-next-line class-methods-use-this
  isVotable() {
    if (this.closedAt || new Date(this.endTime) < new Date()) {
      return false;
    }
    // TODO regional voting here
    return true;
  }

  hasEnded() {
    return new Date(this.endTime) <= new Date();
  }

  async isUnipolar(viewer: ViewerShape, loaders) {
    const mode = await PollingMode.gen(viewer, this.pollingModeId, loaders);
    return mode.unipolar === true;
  }

  async isCommentable(viewer: ViewerShape, loaders) {
    if (this.closedAt) return false;
    const mode = await PollingMode.gen(viewer, this.pollingModeId, loaders);
    return mode.withStatements === true;
  }
  /* eslint-disable class-methods-use-this */

  // eslint-disable-next-line no-unused-vars
  async validate(viewer) {
    // TODO
    return true;
  }

  /* eslint-enable class-methods-use-this */
  static async create(viewer: ViewerShape, data, loaders, trx) {
    // authorize
    if (!canMutate(viewer, data, Models.POLL)) return null;

    // validate
    if (!data.pollingModeId) return null;
    if (!data.threshold) return null;

    const newData = { created_at: new Date() };

    if (data.options) {
      // check options
      const validatedOptions = validateOptions(data.options);
      newData.options = JSON.stringify(validatedOptions);
    }
    if ('extended' in data) {
      if (newData.options && newData.options.length) {
        newData.extended = data.extended;
      }
    }
    //

    if ('multipleChoice' in data) {
      newData.multiple_choice = data.multipleChoice;
    }
    if ('secret' in data) {
      newData.secret = data.secret;
    }

    const { startTime, endTime } = validateDates(data);

    if (startTime) {
      newData.start_time = startTime;
    }
    if (endTime) {
      newData.end_time = endTime;
    }
    if (data.pollingModeId) {
      newData.polling_mode_id = data.pollingModeId;
    }

    if (data.threshold) {
      newData.threshold = data.threshold;
    }

    // create

    const createPoll = async transaction => {
      const [pollingModeData = null] = await knex('polling_modes')
        .transacting(transaction)
        .where({ id: data.pollingModeId })
        .limit(1)
        .select('*');
      if (!pollingModeData) throw Error('No valid PollingMode provided');
      const pollingMode = new PollingMode(pollingModeData);
      let numVoter = 0;

      if (!newData.extended) {
        const options = [
          { pos: 0, order: 0, numVotes: 0, description: { _default: 'up' } },
        ];

        if (!pollingMode.unipolar) {
          options.push({
            pos: 1,
            order: 1,
            numVotes: 0,
            description: { _default: 'down' },
          });
        }
        newData.options = JSON.stringify(options);
      }

      if (pollingMode.thresholdRef === 'all') {
        // TODO change completely in case of group model
        if (data.workTeamId) {
          numVoter = await knex('user_work_teams')
            .transacting(transaction)
            .where({ work_team_id: data.workTeamId })
            .join('users', 'users.id', 'user_work_teams.user_id') // bc also viewers can be members
            .whereRaw('users.groups & ? > 0', [Groups.VIEWER]) // TODO whitelist
            .count('users.id');
        } else {
          numVoter = await transaction
            .whereRaw('groups & ? > 0', [Groups.VOTER]) // TODO whitelist
            .count('id')
            .into('users');
        }
        numVoter = Number(numVoter[0].count);
        if (numVoter < 1) throw Error('Not enough user');
      }

      if (numVoter) {
        newData.num_voter = numVoter;
      }

      const [pollinDB = null] = await knex('polls')
        .transacting(transaction)
        .insert(newData)
        .returning('*');
      return pollinDB;
    };

    const newPoll = await transactify(createPoll, knex, trx);
    if (!newPoll) return null;
    return new Poll(newPoll);
  }

  static async update(viewer, data, loaders, trx) {
    // authorize
    if (!canMutate(viewer, data, Models.POLL)) return null;
    // validate
    if (!data.id) return null;
    const newData = {};
    if (data.closedAt) {
      newData.closed_at = data.closedAt;
      newData.updated_at = new Date();
    }

    const updatePoll = async transaction =>
      knex('polls')
        .transacting(transaction)
        .where({ id: data.id })
        .update(newData)
        .returning('*');

    const pollData = await transactify(updatePoll, knex, trx);
    return pollData && new Poll(pollData);
  }
}

export default Poll;
<|endoftext|>


<commit_before>import DataType from 'sequelize';
import Model from '../sequelize';

const Unit = Model.define('unit', {
  id: {
    type: DataType.UUID,
    defaultValue: DataType.UUIDV1,
    primaryKey: true,
  },

  title: {
    type: DataType.STRING(255),
    allowNull: false,
  },

  body: {
    type: DataType.STRING,
  },

  schema: {
    type: DataType.STRING,
  },
});

export default Unit;
<commit_msg>add unit access rights<commit_after>import DataType from 'sequelize';
import Model from '../sequelize';
import * as util from './util';

const Unit = Model.define('unit', {
  id: {
    type: DataType.UUID,
    defaultValue: DataType.UUIDV1,
    primaryKey: true,
  },

  title: {
    type: DataType.STRING(255),
    allowNull: false,
  },

  body: {
    type: DataType.STRING,
  },

  schema: {
    type: DataType.STRING,
  },
});

Unit.prototype.canRead = async function canRead(user) {
  if (util.haveAccess(user)) return true;
  const courses = await this.getCourses();
  for (let i = 0; i < courses.length; i += 1) {
    // eslint-disable-next-line no-await-in-loop
    const role = await user.getRole(courses[i].id);
    if (!role) return false;
  }
  return true;
};

Unit.prototype.canWrite = function canWrite(user) {
  return util.haveRootAccess(user);
};

export default Unit;
<|endoftext|>


<commit_before>'use strict';
debugger;
let FE=require('./../');
let myfe=new FE('%%pat*ern%%');

let match=myfe.exec('pattern patern pattttttttttttttern paern',{multiline:true});
console.log(match);<commit_msg>fixed path error in node example<commit_after>'use strict';
debugger;
let FE=require('./../../');
let myfe=new FE('%%pat*ern%%');

let match=myfe.exec('pattern patern pattttttttttttttern paern',{multiline:true});
console.log(match);<|endoftext|>


<commit_before>/*global PDFJS:false*/
/*eslint-env browser*/
/*eslint-env es6*/
!function PDFViewClosure() {
    'use strict';
    var page_gap = 10;
    var xform = 'transform';
    ['', 'webkit', 'Moz', 'O', 'ms'].every(function (prefix) {
        var e = prefix + (prefix ? 'T' : 't') + 'ransform';
        if (typeof document.body.style[e] !== 'undefined') {
            xform = e;
            return false;
        }
        return true;
    });

    function getPixelRatio() {
        //On mobile devices this is the ratio css pixel height / device pixel height, whilst at 1.0 scale
        //On desktop devices this is typically the current scale.
        var dpr = window.devicePixelRatio || 1;
        //On mobile devices this adequately measures scale on a page using viewport width=device-width.
        //On desktop devices it is 1 (or slightly less to compensate for a scroll bar.)
        var scale = (document.documentElement.clientWidth / window.innerWidth) || 1;
        scale = scale < 1 ? 1 : scale;
        return dpr * scale;
    }

    function getOutputScale(ctx) {
        var canvas;
        if (ctx === undefined) {
            if (canvas === undefined) {
                canvas = document.createElement('canvas');
            }
            ctx = canvas.getContext('2d');
        }
        var devicePixelRatio = getPixelRatio();
        var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            ctx.backingStorePixelRatio || 1; //backing store ratio is deprecated and will likely always be 1.
        var pixelRatio = devicePixelRatio / backingStoreRatio;
        return {
            sx: pixelRatio,
            sy: pixelRatio,
            scaled: pixelRatio !== 1
        };
    }
    /*
    !function () {
        PDFJS.getDocument('1609.01714.pdf').then(function (pdf) {
            var pageDivs = [];
            function createPage(n) {
                if (n > pdf.numPages) {
                    return;
                }
                var div = document.createElement('div');
                pageDivs.push(div);
                var promise = new Promise(function (resolve, reject) {

                    pdf.getPage(n).then(function (page) {
                        var scale = 1;
                        var viewport = page.getViewport(scale * CSS_UNITS);

                        var canvas = document.createElement('canvas');
                        var context = canvas.getContext('2d');

                        var outputScale = getOutputScale(canvas);
                        if (PDFJS.maxCanvasPixels > 0) {
                            var pixelsInViewport = viewport.width * viewport.height;
                            var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
                            if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
                                outputScale.sx = maxScale;
                                outputScale.sy = maxScale;
                                outputScale.scaled = true;
                                var hasRestrictedScaling = true;//TODO: use this to css transform element larger.
                            } else {
                                hasRestrictedScaling = false;
                            }
                        }

                        canvas.height = viewport.height * outputScale.sy;
                        canvas.width = viewport.width * outputScale.sx;
                        canvas.style.height = viewport.height;
                        canvas.style.width = viewport.width;

                        div.appendChild(canvas);
                        var transform = !outputScale.scaled ? null :
                            [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
                        page.render({
                            canvasContext: context,
                            transform: transform,
                            viewport: viewport
                        }).then(resolve(), reject());
                    });
                });
                return promise;
            }
            createPage(1).then(function () {
                return createPage(2);
            }).then(function () {
                pageDivs.forEach(function (div) {
                    document.body.appendChild(div);
                });
            });
        });
    } ();
    */
/*
    window.PdfViewController = function PdfViewController(pdfViewPromise) {
        var pdfView;
        pdfViewPromise.then(function (pdfViewModel) {
            pdfView = pdfViewModel;
            var kinetic = window.kinetic({
                listeners: [xposChanged],
                restrictFn: function (x) {
                    if (x < 0) {
                        return 0;
                    }
                    var finalPage = pdfView.pages[pdfView.pages.length];
                    var max = finalPage.baseTotalPrevPagesWidth
                        + finalPage.baseSize.w
                        + (pdfView.pages.length - 1) * page_gap
                        - pdfView.container.clientWidth;
                    if (x > max) {
                        return max;
                    }
                    return x;
                }
            });
        });

        function xposChanged(pos) {
            pdfView.position({ x: pos });
        }

        var prevPanDelta = { x: 0, y: 0 };
        function onPan(ev) {

        }
    };
*/
    window.PdfView = function PdfView(container, pdfLocation) {

        var pdfViewModel = {
            pages: [],
            scale: scale,
            position: position,
            container: container,
        };
        var _scale = 1;
        var _position = { x: 0, y: 0 };

        container.classList.add('pdfview-container');
        var finalPageInitialisedResolve;
        var promise = new Promise(function (resolve) {
            finalPageInitialisedResolve = resolve;
        });
        PDFJS.getDocument(pdfLocation).then(function (pdf) {
            var totalWidth = 0;
            function initPage(pageNum) {
                if (pageNum === pdf.numPages){
                    window.addEventListener('resize', render);
                    container.addEventListener('scroll', render);
                    render();
                    finalPageInitialisedResolve(pdfViewModel);
                    return;
                }
                pdf.getPage(pageNum+1).then(function (page) {
                    var pageView = PdfPageView(page);
                    pageView.pageNo = pageNum;
                    pageView.baseTotalPrevPagesWidth = totalWidth;
                    totalWidth += pageView.baseSize.w;
                    pdfViewModel.pages.push(pageView);
                    pdfViewModel.container.appendChild(pageView.div);
                    initPage(pageNum + 1);
                });
            }
            initPage(0);
        });

        var renderQueued = false;
        function render() {
            if (renderQueued) {
                return;
            }
            renderQueued = true;
            window.requestAnimationFrame(function () {
                renderWork();
                renderQueued = false;
            });
        }

        function renderWork() {
            var pages = pdfViewModel.pages;
            var scale = _scale;
            pages.forEach(function (page) {
                page.scale(scale);
                var index = page.pageNo;
                var x = scale * (page.baseTotalPrevPagesWidth + index * page_gap - _position.x);
                var y = scale * (-_position.y);
                var transformText = 'translate( ' + x + 'px, ' + y + 'px )';
                page.div.style[xform] = transformText;

                var inView = false;
                var container = pdfViewModel.container;
                if (x + page.baseSize.w * scale > container.scrollLeft //the right of the page is not to the left of the container
                    && x < container.scrollLeft + container.clientWidth //the left of the page is not to the right of the container
                ) {
                    inView = true;
                }
                page.onMove(inView); //trigger the page to hide/draw itself if necessary
            });
        }

        function scale(value) {
            if (value) {
                _scale = value;
                render();
                return;
            }
            return _scale;
        }
        function position(value) {
            if (value) {
                if (value.x !== undefined) {
                    _position.x = value.x;
                }
                if (value.y !== undefined) {
                    _position.y = value.y;
                }
                render();
            }
            return {
                x: _position.x,
                y: _position.y
            };
        }

        var zres = ZoomResizeEventSource();
        zres.start();
        return promise;
    };

    function PdfPageView(pdfPage) {
        var CLASS_LOADING = 'pdfview-loading';
        var CLASS_DIV = 'pdfview-pageContainer';
        var RENDER_INIT = 'inital';
        var RENDER_RUNNING = 'running';
        var RENDER_COMPLETE = 'complete';
        var RENDER_PAUSED = 'paused';
        var _scale = 0;
        var pageView = {
            pdfPage: pdfPage, //the PdfPageProxy object
            baseSize: { w: 0, h: 0 }, //the unscaled natural css size for the canvas
            size: { w: 0, h: 0 }, //the current space that this wants to take up
            scale: function (value) {
                if (value) {
                    _scale = value;
                    if (pageView.div && pageView.baseSize && pageView.baseSize.w) {
                        pageView.div.style.width = '' + (pageView.baseSize.w * _scale) + 'px';
                    }
                    return;
                }
                return _scale;
            }, //the current scale to draw at. can be different to previous render.
            baseTotalPrevPagesWidth: 0, //total width of pages before this one. used in conjunction with scaling to position page.
            pageNo: 0, //the 0-indexed page number.
            renderStatus: RENDER_INIT,
            renderGraphicsScale: 0, //the previous scale * outputscale this page was rendered at.
            renderLogicalScale: 0, //the previous scale this page was rendered at.
            renderTask: null, //the current rendertask for this page.
            canvas: null,
            context: null,
            div: null,
            onMove: onMove,
            inView: false,
        };

        function onMove(inView) {
            if (inView === pageView.inView) {
                //page hasn't moved in or out of view, but might have rescaled enough to redraw.
                if (!pageView.renderGraphicsScale || !pageView.renderLogicalScale) {
                    return;
                }
                if (!pageView.scale()) {
                    return;
                }
                if (!pageView.context) {
                    return;
                }
                //Determine if scaling has changed enough to redraw.
                var outputScale = getOutputScale(pageView.context).sx;
                var newScale = pageView.scale() * outputScale;
                if (newScale - pageView.renderGraphicsScale > 0.25
                    || pageView.renderGraphicsScale - newScale > 0.25) {
                    render();
                } else if (inView && pageView.canvas) {
                    //ensure that current size is correct.
                    var canvas = pageView.canvas;
                    var viewport = pageView.viewport;
                    var scale = pageView.scale();
                    var height = viewport.height * (scale / pageView.renderLogicalScale) ;
                    var width = viewport.width * (scale / pageView.renderLogicalScale);
                    canvas.style.height = height + 'px';
                    canvas.style.width = width + 'px';
                    pageView.size.h = height;
                    pageView.size.w = width;

                }
            } else {
                //has changed visibility;
                pageView.inView = inView;
                if (pageView.inView) {
                    render();
                } else {
                    reset();
                }
            }
        }

        function initialise() {
            var vp = pdfPage.getViewport(1);
            pageView.baseSize.w = vp.width;
            pageView.baseSize.h = vp.height;
            pageView.div = document.createElement('div');
            pageView.div.classList.add(CLASS_DIV);
            pageView.div.classList.add(CLASS_LOADING);
        }

        function render() {
            reset(true);
            pageView.renderStatus = RENDER_RUNNING;
            var scale = pageView.scale();
            var page = pageView.pdfPage;
            var viewport = page.getViewport(scale);
            pageView.viewport = viewport;
            var canvas = document.createElement('canvas');
            var oldCanvas = pageView.canvas;
            pageView.canvas = canvas;
            var context = canvas.getContext('2d');
            pageView.context = context;

            var outputScale = getOutputScale(context);
            if (PDFJS.maxCanvasPixels > 0) {
                var pixelsInViewport = viewport.width * viewport.height;
                var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
                if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
                    outputScale.sx = maxScale;
                    outputScale.sy = maxScale;
                    outputScale.scaled = true;
                }
            }

            pageView.renderGraphicsScale = scale * outputScale.sx;
            pageView.renderLogicalScale = scale;
            canvas.height = viewport.height * outputScale.sy;
            canvas.width = viewport.width * outputScale.sx;
            canvas.style.height = viewport.height + 'px';
            canvas.style.width = viewport.width + 'px';
            pageView.size.h = viewport.height;
            pageView.size.w = viewport.width;
            canvas.setAttribute('hidden', 'hidden');

            var transform = !outputScale.scaled ? null :
                [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
            var renderTask = page.render({
                canvasContext: context,
                transform: transform,
                viewport: viewport
            });
            pageView.renderTask = renderTask;
            var resolveRenderPromise, rejectRenderPromise;
            var promise = new Promise(function (resolve, reject) {
                resolveRenderPromise = resolve;
                rejectRenderPromise = reject;
            });

            function renderComplete(error) {
                pageView.div.appendChild(canvas);
                if (pageView.canvas) {
                    pageView.canvas.removeAttribute('hidden');
                }
                if (oldCanvas && oldCanvas.parentElement === pageView.div) {
                    pageView.div.removeChild(oldCanvas);
                }
                if (pageView.renderTask === renderTask) {
                    pageView.renderTask = null;
                }
                if (error === 'cancelled') {
                    rejectRenderPromise(error);
                    return;
                }
                pageView.renderStatus = RENDER_COMPLETE;
                pageView.div.classList.remove(CLASS_LOADING);
                resolveRenderPromise();
            }

            renderTask.promise.then(function () {
                renderComplete(null);
            }, function (error) {
                renderComplete(error);
            });

            return promise;
        }

        function reset(leaveOldCanvas) {
            if (pageView.renderTask && (
                pageView.renderStatus === RENDER_RUNNING
                || pageView.renderStatus === RENDER_INIT
                || pageView.renderStatus === RENDER_PAUSED)
            ) {
                pageView.renderTask.cancel();
            }
            pageView.renderStatus = RENDER_INIT;

            if (pageView.div && pageView.canvas && !leaveOldCanvas) {
                if (pageView.canvas.parentElement === pageView.div) {
                    pageView.div.removeChild(pageView.canvas);
                }
                pageView.div.classList.add(CLASS_LOADING);
                delete pageView.canvas;
            }
        }

        initialise();
        return pageView;
    }

    var zoomResizeTimeout;
    /**
     * Sets up a source of resize events for when a mobile browser
     */
    function ZoomResizeEventSource() {
        if (zoomResizeTimeout) {
            return;
        }
        var scale = (document.documentElement.clientWidth / window.innerWidth) || 1;
        if (scale < 1) {
            scale = 1;
        }
        var started = false;
        function zoomResizeEventTick() {
            if (started) {
                return;
            }
            started = true;
            var newScale = (document.documentElement.clientWidth / window.innerWidth) || 1;
            if (newScale < 1) {
                newScale = 1;
            }
            if (Math.abs(scale - newScale) > 0.02) {
                var event = document.createEvent('Event');
                event.initEvent('resize', true, true);
                window.dispatchEvent(event);
            }
            scale = newScale;
            zoomResizeTimeout = window.setTimeout(150, zoomResizeEventTick); //150 ms period. Might feel a little sluggish, but prevents
        }
        return {
            start: zoomResizeEventTick,
            stop: function () {
                if (zoomResizeTimeout) {
                    window.clearTimeout(zoomResizeTimeout);
                }
                zoomResizeTimeout = undefined;
                started = false;
            }
        };
    }
} ();<commit_msg>fix removing old renders<commit_after>/*global PDFJS:false*/
/*eslint-env browser*/
/*eslint-env es6*/
!function PDFViewClosure() {
    'use strict';
    var page_gap = 10;
    var xform = 'transform';
    ['', 'webkit', 'Moz', 'O', 'ms'].every(function (prefix) {
        var e = prefix + (prefix ? 'T' : 't') + 'ransform';
        if (typeof document.body.style[e] !== 'undefined') {
            xform = e;
            return false;
        }
        return true;
    });

    function getPixelRatio() {
        //On mobile devices this is the ratio css pixel height / device pixel height, whilst at 1.0 scale
        //On desktop devices this is typically the current scale.
        var dpr = window.devicePixelRatio || 1;
        //On mobile devices this adequately measures scale on a page using viewport width=device-width.
        //On desktop devices it is 1 (or slightly less to compensate for a scroll bar.)
        var scale = (document.documentElement.clientWidth / window.innerWidth) || 1;
        scale = scale < 1 ? 1 : scale;
        return dpr * scale;
    }

    function getOutputScale(ctx) {
        var canvas;
        if (ctx === undefined) {
            if (canvas === undefined) {
                canvas = document.createElement('canvas');
            }
            ctx = canvas.getContext('2d');
        }
        var devicePixelRatio = getPixelRatio();
        var backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
            ctx.mozBackingStorePixelRatio ||
            ctx.msBackingStorePixelRatio ||
            ctx.oBackingStorePixelRatio ||
            ctx.backingStorePixelRatio || 1; //backing store ratio is deprecated and will likely always be 1.
        var pixelRatio = devicePixelRatio / backingStoreRatio;
        return {
            sx: pixelRatio,
            sy: pixelRatio,
            scaled: pixelRatio !== 1
        };
    }
    /*
    !function () {
        PDFJS.getDocument('1609.01714.pdf').then(function (pdf) {
            var pageDivs = [];
            function createPage(n) {
                if (n > pdf.numPages) {
                    return;
                }
                var div = document.createElement('div');
                pageDivs.push(div);
                var promise = new Promise(function (resolve, reject) {

                    pdf.getPage(n).then(function (page) {
                        var scale = 1;
                        var viewport = page.getViewport(scale * CSS_UNITS);

                        var canvas = document.createElement('canvas');
                        var context = canvas.getContext('2d');

                        var outputScale = getOutputScale(canvas);
                        if (PDFJS.maxCanvasPixels > 0) {
                            var pixelsInViewport = viewport.width * viewport.height;
                            var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
                            if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
                                outputScale.sx = maxScale;
                                outputScale.sy = maxScale;
                                outputScale.scaled = true;
                                var hasRestrictedScaling = true;//TODO: use this to css transform element larger.
                            } else {
                                hasRestrictedScaling = false;
                            }
                        }

                        canvas.height = viewport.height * outputScale.sy;
                        canvas.width = viewport.width * outputScale.sx;
                        canvas.style.height = viewport.height;
                        canvas.style.width = viewport.width;

                        div.appendChild(canvas);
                        var transform = !outputScale.scaled ? null :
                            [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
                        page.render({
                            canvasContext: context,
                            transform: transform,
                            viewport: viewport
                        }).then(resolve(), reject());
                    });
                });
                return promise;
            }
            createPage(1).then(function () {
                return createPage(2);
            }).then(function () {
                pageDivs.forEach(function (div) {
                    document.body.appendChild(div);
                });
            });
        });
    } ();
    */
/*
    window.PdfViewController = function PdfViewController(pdfViewPromise) {
        var pdfView;
        pdfViewPromise.then(function (pdfViewModel) {
            pdfView = pdfViewModel;
            var kinetic = window.kinetic({
                listeners: [xposChanged],
                restrictFn: function (x) {
                    if (x < 0) {
                        return 0;
                    }
                    var finalPage = pdfView.pages[pdfView.pages.length];
                    var max = finalPage.baseTotalPrevPagesWidth
                        + finalPage.baseSize.w
                        + (pdfView.pages.length - 1) * page_gap
                        - pdfView.container.clientWidth;
                    if (x > max) {
                        return max;
                    }
                    return x;
                }
            });
        });

        function xposChanged(pos) {
            pdfView.position({ x: pos });
        }

        var prevPanDelta = { x: 0, y: 0 };
        function onPan(ev) {

        }
    };
*/
    window.PdfView = function PdfView(container, pdfLocation) {

        var pdfViewModel = {
            pages: [],
            scale: scale,
            position: position,
            container: container,
        };
        var _scale = 1;
        var _position = { x: 0, y: 0 };

        container.classList.add('pdfview-container');
        var finalPageInitialisedResolve;
        var promise = new Promise(function (resolve) {
            finalPageInitialisedResolve = resolve;
        });
        PDFJS.getDocument(pdfLocation).then(function (pdf) {
            var totalWidth = 0;
            function initPage(pageNum) {
                if (pageNum === pdf.numPages){
                    window.addEventListener('resize', render);
                    container.addEventListener('scroll', render);
                    render();
                    finalPageInitialisedResolve(pdfViewModel);
                    return;
                }
                pdf.getPage(pageNum+1).then(function (page) {
                    var pageView = PdfPageView(page);
                    pageView.pageNo = pageNum;
                    pageView.baseTotalPrevPagesWidth = totalWidth;
                    totalWidth += pageView.baseSize.w;
                    pdfViewModel.pages.push(pageView);
                    pdfViewModel.container.appendChild(pageView.div);
                    initPage(pageNum + 1);
                });
            }
            initPage(0);
        });

        var renderQueued = false;
        function render() {
            if (renderQueued) {
                return;
            }
            renderQueued = true;
            window.requestAnimationFrame(function () {
                renderWork();
                renderQueued = false;
            });
        }

        function renderWork() {
            var pages = pdfViewModel.pages;
            var scale = _scale;
            pages.forEach(function (page) {
                page.scale(scale);
                var index = page.pageNo;
                var x = scale * (page.baseTotalPrevPagesWidth + index * page_gap - _position.x);
                var y = scale * (-_position.y);
                var transformText = 'translate( ' + x + 'px, ' + y + 'px )';
                page.div.style[xform] = transformText;

                var inView = false;
                var container = pdfViewModel.container;
                if (x + page.baseSize.w * scale > container.scrollLeft //the right of the page is not to the left of the container
                    && x < container.scrollLeft + container.clientWidth //the left of the page is not to the right of the container
                ) {
                    inView = true;
                }
                page.onMove(inView); //trigger the page to hide/draw itself if necessary
            });
        }

        function scale(value) {
            if (value) {
                _scale = value;
                render();
                return;
            }
            return _scale;
        }
        function position(value) {
            if (value) {
                if (value.x !== undefined) {
                    _position.x = value.x;
                }
                if (value.y !== undefined) {
                    _position.y = value.y;
                }
                render();
            }
            return {
                x: _position.x,
                y: _position.y
            };
        }

        var zres = ZoomResizeEventSource();
        zres.start();
        return promise;
    };

    function PdfPageView(pdfPage) {
        var CLASS_LOADING = 'pdfview-loading';
        var CLASS_DIV = 'pdfview-pageContainer';
        var RENDER_INIT = 'inital';
        var RENDER_RUNNING = 'running';
        var RENDER_COMPLETE = 'complete';
        var RENDER_PAUSED = 'paused';
        var _scale = 0;
        var pageView = {
            pdfPage: pdfPage, //the PdfPageProxy object
            baseSize: { w: 0, h: 0 }, //the unscaled natural css size for the canvas
            size: { w: 0, h: 0 }, //the current space that this wants to take up
            scale: function (value) {
                if (value) {
                    _scale = value;
                    if (pageView.div && pageView.baseSize && pageView.baseSize.w) {
                        pageView.div.style.width = '' + (pageView.baseSize.w * _scale) + 'px';
                    }
                    return;
                }
                return _scale;
            }, //the current scale to draw at. can be different to previous render.
            baseTotalPrevPagesWidth: 0, //total width of pages before this one. used in conjunction with scaling to position page.
            pageNo: 0, //the 0-indexed page number.
            renderStatus: RENDER_INIT,
            renderGraphicsScale: 0, //the previous scale * outputscale this page was rendered at.
            renderLogicalScale: 0, //the previous scale this page was rendered at.
            renderTask: null, //the current rendertask for this page.
            canvas: null,
            context: null,
            div: null,
            onMove: onMove,
            inView: false,
        };

        function onMove(inView) {
            if (inView === pageView.inView) {
                //page hasn't moved in or out of view, but might have rescaled enough to redraw.
                if (!pageView.renderGraphicsScale || !pageView.renderLogicalScale) {
                    return;
                }
                if (!pageView.scale()) {
                    return;
                }
                if (!pageView.context) {
                    return;
                }
                //Determine if scaling has changed enough to redraw.
                var outputScale = getOutputScale(pageView.context).sx;
                var newScale = pageView.scale() * outputScale;
                if (newScale - pageView.renderGraphicsScale > 0.25
                    || pageView.renderGraphicsScale - newScale > 0.25) {
                    render();
                } else if (inView && pageView.canvas) {
                    //ensure that current size is correct.
                    var canvas = pageView.canvas;
                    var viewport = pageView.viewport;
                    var scale = pageView.scale();
                    var height = viewport.height * (scale / pageView.renderLogicalScale) ;
                    var width = viewport.width * (scale / pageView.renderLogicalScale);
                    canvas.style.height = height + 'px';
                    canvas.style.width = width + 'px';
                    pageView.size.h = height;
                    pageView.size.w = width;

                }
            } else {
                //has changed visibility;
                pageView.inView = inView;
                if (pageView.inView) {
                    render();
                } else {
                    reset();
                }
            }
        }

        function initialise() {
            var vp = pdfPage.getViewport(1);
            pageView.baseSize.w = vp.width;
            pageView.baseSize.h = vp.height;
            pageView.div = document.createElement('div');
            pageView.div.classList.add(CLASS_DIV);
            pageView.div.classList.add(CLASS_LOADING);
        }

        function render() {
            reset(true);
            pageView.renderStatus = RENDER_RUNNING;
            var scale = pageView.scale();
            var page = pageView.pdfPage;
            var viewport = page.getViewport(scale);
            pageView.viewport = viewport;
            var canvas = document.createElement('canvas');
            var oldCanvas = pageView.canvas;
            pageView.canvas = canvas;
            var context = canvas.getContext('2d');
            pageView.context = context;

            var outputScale = getOutputScale(context);
            if (PDFJS.maxCanvasPixels > 0) {
                var pixelsInViewport = viewport.width * viewport.height;
                var maxScale = Math.sqrt(PDFJS.maxCanvasPixels / pixelsInViewport);
                if (outputScale.sx > maxScale || outputScale.sy > maxScale) {
                    outputScale.sx = maxScale;
                    outputScale.sy = maxScale;
                    outputScale.scaled = true;
                }
            }

            pageView.renderGraphicsScale = scale * outputScale.sx;
            pageView.renderLogicalScale = scale;
            canvas.height = viewport.height * outputScale.sy;
            canvas.width = viewport.width * outputScale.sx;
            canvas.style.height = viewport.height + 'px';
            canvas.style.width = viewport.width + 'px';
            pageView.size.h = viewport.height;
            pageView.size.w = viewport.width;
            canvas.setAttribute('hidden', 'hidden');

            var transform = !outputScale.scaled ? null :
                [outputScale.sx, 0, 0, outputScale.sy, 0, 0];
            var renderTask = page.render({
                canvasContext: context,
                transform: transform,
                viewport: viewport
            });
            pageView.renderTask = renderTask;
            var resolveRenderPromise, rejectRenderPromise;
            var promise = new Promise(function (resolve, reject) {
                resolveRenderPromise = resolve;
                rejectRenderPromise = reject;
            });

            function renderComplete(error) {
                while (pageView.div.firstChild) {
                    pageView.div.remove(pageView.div.firstChild);
                }
                pageView.div.appendChild(canvas);
                canvas.removeAttribute('hidden');
                if (pageView.renderTask === renderTask) {
                    pageView.renderTask = null;
                }
                if (error === 'cancelled') {
                    rejectRenderPromise(error);
                    return;
                }
                pageView.renderStatus = RENDER_COMPLETE;
                pageView.div.classList.remove(CLASS_LOADING);
                resolveRenderPromise();
            }

            renderTask.promise.then(function () {
                renderComplete(null);
            }, function (error) {
                renderComplete(error);
            });

            return promise;
        }

        function reset(leaveOldCanvas) {
            if (pageView.renderTask && (
                pageView.renderStatus === RENDER_RUNNING
                || pageView.renderStatus === RENDER_INIT
                || pageView.renderStatus === RENDER_PAUSED)
            ) {
                pageView.renderTask.cancel();
            }
            pageView.renderStatus = RENDER_INIT;

            if (pageView.div && pageView.canvas && !leaveOldCanvas) {
                if (pageView.canvas.parentElement === pageView.div) {
                    pageView.div.removeChild(pageView.canvas);
                }
                pageView.div.classList.add(CLASS_LOADING);
                delete pageView.canvas;
            }
        }

        initialise();
        return pageView;
    }

    var zoomResizeTimeout;
    /**
     * Sets up a source of resize events for when a mobile browser
     */
    function ZoomResizeEventSource() {
        if (zoomResizeTimeout) {
            return;
        }
        var scale = (document.documentElement.clientWidth / window.innerWidth) || 1;
        if (scale < 1) {
            scale = 1;
        }
        var started = false;
        function zoomResizeEventTick() {
            if (started) {
                return;
            }
            started = true;
            var newScale = (document.documentElement.clientWidth / window.innerWidth) || 1;
            if (newScale < 1) {
                newScale = 1;
            }
            if (Math.abs(scale - newScale) > 0.02) {
                var event = document.createEvent('Event');
                event.initEvent('resize', true, true);
                window.dispatchEvent(event);
            }
            scale = newScale;
            zoomResizeTimeout = window.setTimeout(150, zoomResizeEventTick); //150 ms period. Might feel a little sluggish, but prevents
        }
        return {
            start: zoomResizeEventTick,
            stop: function () {
                if (zoomResizeTimeout) {
                    window.clearTimeout(zoomResizeTimeout);
                }
                zoomResizeTimeout = undefined;
                started = false;
            }
        };
    }
} ();<|endoftext|>