<commit_before>Accounts.onCreateUser(function(options, user) {
  var profile = {};
  profile.alias = "Player " +  _.random(0, 1000);
  // We still want the default hook's 'profile' behavior.
  user.profile = profile;

  return user;
});

Meteor.publish('users', function() {
  return Meteor.users.find();
});

Meteor.methods({
  joinLobby : function(lobbyId, userId){
    appRooms.update({_id: lobbyId}, {$addToSet: {playerIds: userId}});
    appRooms.update({_id: lobbyId}, {$inc: {playerSize: 1}});
    Meteor.users.update({_id: userId}, {$set: {"status.lobbyId": lobbyId}}, function(err){
      if(!err){
        console.log("user updated successfully");
      }else{
        console.log("user update failed");
      }
    });
  },
  leaveLobby : function(userId){
    console.log("leaving lobby");
    var user = Meteor.users.findOne({_id: userId});
    var lobby = appRooms.findOne({_id: user.status.lobbyId});
    if(lobby){
      if(lobby.playerSize == 1){
        console.log("Lobby only has one visitor");
        appRooms.remove({_id: lobby._id});
      }else{
        console.log("Lobby has "+lobby.playerSize+" visitors.");
        appRooms.update({_id: lobby._id}, {$pull: {playerIds: userId}});
        appRooms.update({_id: lobby._id}, {$inc: {playerSize: -1}});
      }
    }else{
      //console.log("Lobby not found");
    }
  }
});

UserStatus.events.on("connectionLogin", function(fields) {

});

UserStatus.events.on("connectionLogout", function(fields) {
  Meteor.call('leaveLobby', fields.userId, function (err, res){
    if(err){
      console.log(err);
    }
  });
});
<commit_msg>User leaving lobby now creates an exit prompt.<commit_after>Accounts.onCreateUser(function(options, user) {
  var profile = {};
  profile.alias = "Player " +  _.random(0, 1000);
  // We still want the default hook's 'profile' behavior.
  user.profile = profile;

  return user;
});

Meteor.publish('users', function() {
  return Meteor.users.find();
});

Meteor.methods({
  joinLobby : function(lobbyId, userId){
    appRooms.update({_id: lobbyId}, {$addToSet: {playerIds: userId}});
    appRooms.update({_id: lobbyId}, {$inc: {playerSize: 1}});
    Meteor.users.update({_id: userId}, {$set: {"status.lobbyId": lobbyId}}, function(err){
      if(!err){
        console.log("user updated successfully");
      }else{
        console.log("user update failed");
      }
    });
  },
  leaveLobby : function(userId){
    console.log("leaving lobby");
    var user = Meteor.users.findOne({_id: userId});
    var lobby = appRooms.findOne({_id: user.status.lobbyId});
    if(lobby){
      if(lobby.playerSize == 1){
        console.log("Lobby only has one visitor");
        appRooms.remove({_id: lobby._id});
      }else{
        console.log("Lobby has "+lobby.playerSize+" visitors.");
        appRooms.update({_id: lobby._id}, {$pull: {playerIds: userId}});
        appRooms.update({_id: lobby._id}, {$inc: {playerSize: -1}});
        Messages.insert({room: lobby._id, userAlias: user.profile.alias, userId: userId, message: "[" + user.profile.alias + " has left the room.]"});
      }
    }else{
      //console.log("Lobby not found");
    }
  }
});

UserStatus.events.on("connectionLogin", function(fields) {

});

UserStatus.events.on("connectionLogout", function(fields) {
  Meteor.call('leaveLobby', fields.userId, function (err, res){
    if(err){
      console.log(err);
    }
  });
});
<|endoftext|>


<commit_before>(function start() {
    "use strict";

    const morgan = require("morgan");
    const express = require("express");
    const login = require(`${__dirname}/routes/login`);
    const app = express();

    /** Use Morgan to log requests */
    app.use(morgan("dev"));

    /** Add static sites */
    app.use(express.static("public"));

    /** Add login Route */
    app.use("/login", login);

    app.listen(process.env.PORT || 8080);
}());
<commit_msg>Add filter to allow access control of endpoints<commit_after>(function start() {
    "use strict";

    const morgan = require("morgan");
    const express = require("express");
    const login = require(`${__dirname}/routes/login`);
    const jwt = require("jsonwebtoken");
    const app = express();

    /** Use Morgan to log requests */
    app.use(morgan("dev"));

    /** Add static sites */
    app.use(express.static("public"));

    app.get("/dashboard", function (req, res) {
        res.send("hello");
    });

    /** Add login Route */
    app.use("/login", login);

    app.use(authFilter);

    app.get("/secure", function (req, res) {
        res.send(`Hello from the secure route!`);
    });
    app.listen(process.env.PORT || 8080);
}());
<|endoftext|>


<commit_before>'use strict'

// server.js
var express = require('express');
var morgan = require('morgan');
var multer = require('multer');
var fs = require('fs');
var md5File = require('md5-file');

var Util = require('./util.js');

var app = express();

// ミドルウェア
app.use(morgan('dev'));
const upload = multer({ dest: 'schematics' });

// config
const schDirectory = './schematics';
const isDebug = true;
const accessOrigin = 'http://localhost:8001';

// rootはアクセスできましぇん
app.get('/', (req, res) => {
  res.statusCode = 404;
  res.end();
});

// GETリクエストのハンドリング
app.get('/+schematics', (req, res) => {
  fs.readdir(schDirectory, (err, files) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
    if (err) { res.end('{status: error}'); }
    else {
      const filenames = files.filter(fn => fn.endsWith('.schematic'));
      const _files = filenames.map(fn => { return {filename: fn.replace(/\.schematic$/, '') } });

      const asyncReadInfos = [];
      for (var i = 0; i < filenames.length; i++) {
        asyncReadInfos.push( Util.readSchematicJSON(`${schDirectory}/${filenames[i]}`) );
      }

      Promise.all(asyncReadInfos)
      .then((results) => {
        res.end(JSON.stringify(results));
      });
    }
  });
});

app.get('/+schematics/:sch_name', (req, res) => {
  const target = `${schDirectory}/${req.params.sch_name}.schematic`;
  if (fs.existsSync(target)) {
    Promise.resolve(Util.readSchematicJSON(target))
    .then((data) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify(data));
    }).catch((err) => {
      res.statusCode = 403;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify({ status: 'read error', error: err }));
    });
  } else {
    console.log("404 - " + req.params.sch_name);
    res.statusCode = 404;
    res.end();
  }
});

app.get('/+schematics/:sch_name/download', (req, res) => {
  const target = `${schDirectory}/${req.params.sch_name}.schematic`;
  if (fs.existsSync(target)) {
    res.download(target);
  } else {
    res.statusCode = 404;
    res.end();
  }
});

// POSTリクエストのハンドリング
app.post('/+schematics/upload', upload.single('sch_file'), function (req, res, next) {
  if (req.file && req.body.title) {
    const upload_name = `schematics/${req.file.originalname}`;

    // TODO: md5で上書きチェックを追加
    // TODO: 削除キーで上書きロックを追加
    Promise.resolve(new Promise((resolve, reject) => {
      fs.rename(req.file.path, upload_name, (err) => {
        if (err) reject(err);
        else resolve();
      });
    })).then(() => new Promise((resolve, reject) => {
      // その他情報をメモする
      fs.writeFile(`${upload_name}.json`, JSON.stringify( {
        title: req.body.title,
        description: req.body.description,
        delete_key: req.body.delete_key,
        upload_date: Date.now() } ),
        (err) => {
          if (err) reject(err);
          else {
            resolve({ status: 'success', file: upload_name });
          }
        });
    })).then((result) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify(result));
    }).catch((err) => {
      res.statusCode = 500;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify({ status: 'error', message: err.message, error: err }));
    });

  } else {
    res.statusCode = 400;
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
    res.end('{status:error,message:"Invalid API Syntax"}');
  }
});

// TODO: deleteメソッドの実装
// 削除キーが一致、もしくは未設定の場合に削除実行
app.get('/+schematics/:sch_name/download', (req, res) => {
});

app.listen(8334, () => {
  console.log("server has started.");
});

<commit_msg>コンソールに表示するアクセスログのフォーマットを変更<commit_after>'use strict'

// server.js
var express = require('express');
var morgan = require('morgan');
var multer = require('multer');
var fs = require('fs');
var md5File = require('md5-file');

var Util = require('./util.js');

var app = express();

// ミドルウェア
morgan.token('remote-addr', function (req, res) {
    var ffHeaderValue = req.headers['x-forwarded-for'];
    return ffHeaderValue || req.connection.remoteAddress;
});
app.use(morgan('[:date[clf]] :remote-addr :remote-user ":method :url HTTP/:http-version" :status - :response-time ms'));
const upload = multer({ dest: 'schematics' });

// config
const schDirectory = './schematics';
const isDebug = true;
const accessOrigin = 'http://localhost:8001';

// rootはアクセスできましぇん
app.get('/', (req, res) => {
  res.statusCode = 404;
  res.end();
});

// GETリクエストのハンドリング
app.get('/+schematics', (req, res) => {
  fs.readdir(schDirectory, (err, files) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
    if (err) { res.end('{status: error}'); }
    else {
      const filenames = files.filter(fn => fn.endsWith('.schematic'));
      const _files = filenames.map(fn => { return {filename: fn.replace(/\.schematic$/, '') } });

      const asyncReadInfos = [];
      for (var i = 0; i < filenames.length; i++) {
        asyncReadInfos.push( Util.readSchematicJSON(`${schDirectory}/${filenames[i]}`) );
      }

      Promise.all(asyncReadInfos)
      .then((results) => {
        res.end(JSON.stringify(results));
      });
    }
  });
});

app.get('/+schematics/:sch_name', (req, res) => {
  const target = `${schDirectory}/${req.params.sch_name}.schematic`;
  if (fs.existsSync(target)) {
    Promise.resolve(Util.readSchematicJSON(target))
    .then((data) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify(data));
    }).catch((err) => {
      res.statusCode = 403;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify({ status: 'read error', error: err }));
    });
  } else {
    console.log("404 - " + req.params.sch_name);
    res.statusCode = 404;
    res.end();
  }
});

app.get('/+schematics/:sch_name/download', (req, res) => {
  const target = `${schDirectory}/${req.params.sch_name}.schematic`;
  if (fs.existsSync(target)) {
    res.download(target);
  } else {
    res.statusCode = 404;
    res.end();
  }
});

// POSTリクエストのハンドリング
app.post('/+schematics/upload', upload.single('sch_file'), function (req, res, next) {
  if (req.file && req.body.title) {
    const upload_name = `schematics/${req.file.originalname}`;

    // TODO: md5で上書きチェックを追加
    // TODO: 削除キーで上書きロックを追加
    Promise.resolve(new Promise((resolve, reject) => {
      fs.rename(req.file.path, upload_name, (err) => {
        if (err) reject(err);
        else resolve();
      });
    })).then(() => new Promise((resolve, reject) => {
      // その他情報をメモする
      fs.writeFile(`${upload_name}.json`, JSON.stringify( {
        title: req.body.title,
        description: req.body.description,
        delete_key: req.body.delete_key,
        upload_date: Date.now() } ),
        (err) => {
          if (err) reject(err);
          else {
            resolve({ status: 'success', file: upload_name });
          }
        });
    })).then((result) => {
      res.statusCode = 200;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify(result));
    }).catch((err) => {
      res.statusCode = 500;
      res.setHeader('Content-Type', 'application/json; charset=utf-8');
      if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
      res.end(JSON.stringify({ status: 'error', message: err.message, error: err }));
    });

  } else {
    res.statusCode = 400;
    res.setHeader('Content-Type', 'application/json; charset=utf-8');
    if (isDebug) res.setHeader('Access-Control-Allow-Origin', accessOrigin);
    res.end('{status:error,message:"Invalid API Syntax"}');
  }
});

// TODO: deleteメソッドの実装
// 削除キーが一致、もしくは未設定の場合に削除実行
app.get('/+schematics/:sch_name/download', (req, res) => {
});

app.listen(8334, () => {
  console.log("server has started.");
});

<|endoftext|>


<commit_before>"use strict";

var util = require("substance-util");

var DefaultConfiguration = require('./default');

var ElifeConfiguration = function() {

};

ElifeConfiguration.Prototype = function() {

  // Resolves figure url
  // --------
  //

  this.enhanceFigure = function(state, node, element) {
    var graphic = element.querySelector("graphic");
    var url = graphic.getAttribute("xlink:href");

    // Example url to SVG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.svg
    url = [
      "http://cdn.elifesciences.org/elife-articles/",
      state.doc.id,
      "/svg/",
      url,
      ".svg"
    ].join('');

    node.url = url;
  };

  this.enhanceVideo = function(state, node, element) {
    var el = element.querySelector("media") || element;
    var href = element.getAttribute("xlink:href").split(".");
    var name = href[0];

    node.url = "http://static.movie-usa.glencoesoftware.com/mp4/10.7554/"+name+".mp4";
    node.url_ogv = "http://static.movie-usa.glencoesoftware.com/ogv/10.7554/"+name+".ogv";
    node.url_webm = "http://static.movie-usa.glencoesoftware.com/webm/10.7554/"+name+".webm";
    node.poster = "http://static.movie-usa.glencoesoftware.com/jpg/10.7554/"+name+".jpg";
  };

  // Add additional information to the info view
  // ---------
  //
  // Impact
  // Major datasets
  // Acknowledgements
  // Copyright

  this.enhanceInfo = function(converter, state, article) {
    var doc = state.doc;
    var articleInfo = {
      "id": "articleinfo",
      "type": "paragraph",
      "children": []
    };
    var nodes = articleInfo.children;

    // var impact = article.querySelector("custom-meta");
    // if (impact) {
    //   var h1 = {
    //     "type": "heading",
    //     "id": state.nextId("heading"),
    //     "level": 1,
    //     "content": "Impact",
    //   };

    //   var t1 = {
    //     "type": "text",
    //     "id": state.nextId("text"),
    //     "content": impact.textContent,
    //   };
    //   console.log(impact.textContent)
    //   doc.create(h1);
    //   doc.create(t1);
    //   nodes.push(h1.id);
    //   nodes.push(t1.id);
    // }
    // Using the caption node type until we have our RichParagraph ready

    var license = article.querySelector("permissions");
    if (license) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Copyright and License"
      };
      doc.create(h1);
      nodes.push(h1.id);

      var copyright = license.querySelector("copyright-statement");
      if (copyright) {
        var t1 = {
          "type" : "text",
          "id" : state.nextId("text"),
          "content" : copyright.textContent
        };
        doc.create(t1);
        nodes.push(t1.id);
      }
      var para = license.querySelector("p");
      if (para) {
        var indiv_node = this.paragraph(state, para);
        nodes.push(indiv_node.id);
      }
    }
    //nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    doc.create(articleInfo);
    console.log(JSON.stringify(articleInfo))
    doc.show("info", articleInfo.id);
  };

  // Add Decision letter and author response
  // ---------

  this.enhanceArticle = function(converter, state, article) {

    var nodes = [];

    // Decision letter (if available)
    // -----------

    var articleCommentary = article.querySelector("#SA1");
    if (articleCommentary) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 1,
        content: "Article Commentary"
      };
      doc.create(heading);
      nodes.push(heading);

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Decision letter"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = articleCommentary.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Author response
    // -----------

    var authorResponse = article.querySelector("#SA2");
    if (authorResponse) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Author response"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = authorResponse.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Show them off
    // ----------

    if (nodes.length > 0) {
      converter.show(state, nodes);
    }

    this.enhanceInfo(converter, state, article);
  };
};

ElifeConfiguration.Prototype.prototype = DefaultConfiguration.prototype;
ElifeConfiguration.prototype = new ElifeConfiguration.Prototype();
ElifeConfiguration.prototype.constructor = ElifeConfiguration;

module.exports = ElifeConfiguration;
<commit_msg>console log<commit_after>"use strict";

var util = require("substance-util");

var DefaultConfiguration = require('./default');

var ElifeConfiguration = function() {

};

ElifeConfiguration.Prototype = function() {

  // Resolves figure url
  // --------
  //

  this.enhanceFigure = function(state, node, element) {
    var graphic = element.querySelector("graphic");
    var url = graphic.getAttribute("xlink:href");

    // Example url to SVG: http://cdn.elifesciences.org/elife-articles/00768/svg/elife00768f001.svg
    url = [
      "http://cdn.elifesciences.org/elife-articles/",
      state.doc.id,
      "/svg/",
      url,
      ".svg"
    ].join('');

    node.url = url;
  };

  this.enhanceVideo = function(state, node, element) {
    var el = element.querySelector("media") || element;
    var href = element.getAttribute("xlink:href").split(".");
    var name = href[0];

    node.url = "http://static.movie-usa.glencoesoftware.com/mp4/10.7554/"+name+".mp4";
    node.url_ogv = "http://static.movie-usa.glencoesoftware.com/ogv/10.7554/"+name+".ogv";
    node.url_webm = "http://static.movie-usa.glencoesoftware.com/webm/10.7554/"+name+".webm";
    node.poster = "http://static.movie-usa.glencoesoftware.com/jpg/10.7554/"+name+".jpg";
  };

  // Add additional information to the info view
  // ---------
  //
  // Impact
  // Major datasets
  // Acknowledgements
  // Copyright

  this.enhanceInfo = function(converter, state, article) {
    var doc = state.doc;
    var articleInfo = {
      "id": "articleinfo",
      "type": "paragraph",
      "children": []
    };
    var nodes = articleInfo.children;

    // var impact = article.querySelector("custom-meta");
    // if (impact) {
    //   var h1 = {
    //     "type": "heading",
    //     "id": state.nextId("heading"),
    //     "level": 1,
    //     "content": "Impact",
    //   };

    //   var t1 = {
    //     "type": "text",
    //     "id": state.nextId("text"),
    //     "content": impact.textContent,
    //   };
    //   console.log(impact.textContent)
    //   doc.create(h1);
    //   doc.create(t1);
    //   nodes.push(h1.id);
    //   nodes.push(t1.id);
    // }
    // Using the caption node type until we have our RichParagraph ready

    var license = article.querySelector("permissions");
    if (license) {
      var h1 = {
        "type" : "heading",
        "id" : state.nextId("heading"),
        "level" : 1,
        "content" : "Copyright and License"
      };
      doc.create(h1);
      nodes.push(h1.id);

      var copyright = license.querySelector("copyright-statement");
      if (copyright) {
        var t1 = {
          "type" : "text",
          "id" : state.nextId("text"),
          "content" : copyright.textContent
        };
        doc.create(t1);
        nodes.push(t1.id);
      }
      var para = license.querySelector("p");
      if (para) {
        console.log('inside')
        console.log(para)
        var indiv_node = this.paragraph(state, para);
        nodes.push(indiv_node.id);
      }
    }
    //nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    doc.create(articleInfo);
    console.log(JSON.stringify(articleInfo))
    doc.show("info", articleInfo.id);
  };

  // Add Decision letter and author response
  // ---------

  this.enhanceArticle = function(converter, state, article) {

    var nodes = [];

    // Decision letter (if available)
    // -----------

    var articleCommentary = article.querySelector("#SA1");
    if (articleCommentary) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 1,
        content: "Article Commentary"
      };
      doc.create(heading);
      nodes.push(heading);

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Decision letter"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = articleCommentary.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Author response
    // -----------

    var authorResponse = article.querySelector("#SA2");
    if (authorResponse) {

      var heading = {
        id: state.nextId("heading"),
        type: "heading",
        level: 2,
        content: "Author response"
      };
      doc.create(heading);
      nodes.push(heading);

      var body = authorResponse.querySelector("body");
      nodes = nodes.concat(converter.bodyNodes(state, util.dom.getChildren(body)));
    }

    // Show them off
    // ----------

    if (nodes.length > 0) {
      converter.show(state, nodes);
    }

    this.enhanceInfo(converter, state, article);
  };
};

ElifeConfiguration.Prototype.prototype = DefaultConfiguration.prototype;
ElifeConfiguration.prototype = new ElifeConfiguration.Prototype();
ElifeConfiguration.prototype.constructor = ElifeConfiguration;

module.exports = ElifeConfiguration;
<|endoftext|>


<commit_before>/*********************************
* Code by Kanishka Mohan Madhuni *
**********************************/

var PreheatingView = Backbone.View.extend({
	el: "#preheat-view",
	updatedTemp: null,
	template1: null,
	template2: null,
	extruderPercentage: null,
	bedPercentage: null,
	events: {
		'click .finish-section-button': 'finishClicked'
	},

	// template: null,
	initialize: function(options) {
		// getting the temperature values from the app.socket js file
    this.listenTo(app.socketData, 'change:temps', this.tempUpdateAlert);

    // setting the templates for displaying the dynamic temperatures
    this.template1 = _.template('<%= Math.min(Math.round(tempObj.extruder.actual)) %> °C/ <%= Math.min(Math.round(tempObj.extruder.target)) %> °C');
    this.template2 = _.template('<%= Math.min(Math.round(tempObj.bed.actual)) %> °C/ <%= Math.min(Math.round(tempObj.bed.target)) %> °C');
	},
	render: function() {
		// Displaying the temperature when the real time data is available
		this.$(".nozzle-temp-progress .temp-value").html(this.template1({tempObj: this.updatedTemp}));
		this.$(".bed-temp-progress .temp-value").html(this.template2({tempObj: this.updatedTemp}));
	},
	tempUpdateAlert: function(s,value) {

		var currentView = this.$el.find('.active');

		this.updatedTemp = value; // setting the value of current object

		// display for the temperature will not show until we get the object for the current temperature
		if (this.updatedTemp !== null) {
	    this.render();
	    this.updateProgressBar();
    }

    if (this.extruderPercentage === 100 && this.bedPercentage === 100) {
    	currentView.removeClass('active').addClass('hide');;
    	this.$("#preheat-wizard__finish-section").removeClass('hide').addClass('active');
    }

	},
	finishClicked: function() {
		this.$("#preheat-wizard__finish-section").removeClass('active').addClass('hide');
		this.$("#preheat-wizard__preheating-progress").removeClass('hide').addClass('active');
	},
	updateProgressBar: function() {

		var progressBar1,
		progressBar2,
		extruderTarget,
		extruderActual,
		bedTarget,
		bedActual;

		progressBar1 = $('#extruder-progress-bar');
		progressBar2 = $('#bed-progress-bar');

		extruderActual = this.updatedTemp.extruder.actual;
		extruderTarget = this.updatedTemp.extruder.target;
		bedActual = this.updatedTemp.bed.actual;
		bedTarget = this.updatedTemp.bed.target;

		if (extruderActual > extruderTarget) {
			this.extruderPercentage = Math.min(Math.round(((extruderTarget/extruderActual)*100)));
		} else {
			this.extruderPercentage = Math.min(Math.round(((extruderActual/extruderTarget)*100)));
		}

		progressBar1.val(this.extruderPercentage);

		if (bedActual > bedTarget) {
			this.bedPercentage = Math.min(Math.round(((bedTarget/bedActual)*100)));
		} else {
			this.bedPercentage = Math.min(Math.round(((bedActual/bedTarget)*100)));
		}

		progressBar2.val(this.bedPercentage);
	}
});<commit_msg>feature: Added feature to cancel preheating process<commit_after>/*********************************
* Code by Kanishka Mohan Madhuni *
**********************************/

var PreheatingView = Backbone.View.extend({
	el: "#preheat-view",
	updatedTemp: null,
	template1: null,
	template2: null,
	extruderPercentage: null,
	bedPercentage: null,
	events: {
		'click .finish-section-button': 'finishClicked',
		'click .preheat-wizard__cancel-button': 'openCancelModal',
		'click .yes-button': 'stopPreheating',
		'click .no-button': 'closeModal',
		'click .preheat-wizard__confirm-cancel-modal': 'closeModal',
		'click .preheat-wizard__confirm-cancel-modal__inner': 'noHideModal'
	},

	// template: null,
	initialize: function(options) {
		// getting the temperature values from the app.socket js file
    this.listenTo(app.socketData, 'change:temps', this.tempUpdateAlert);

    // setting the templates for displaying the dynamic temperatures
    this.template1 = _.template('<%= Math.min(Math.round(tempObj.extruder.actual)) %> °C/ <%= Math.min(Math.round(tempObj.extruder.target)) %> °C');
    this.template2 = _.template('<%= Math.min(Math.round(tempObj.bed.actual)) %> °C/ <%= Math.min(Math.round(tempObj.bed.target)) %> °C');
	},
	render: function() {
		// Displaying the temperature when the real time data is available
		this.$(".nozzle-temp-progress .temp-value").html(this.template1({tempObj: this.updatedTemp}));
		this.$(".bed-temp-progress .temp-value").html(this.template2({tempObj: this.updatedTemp}));
	},
	tempUpdateAlert: function(s,value) {

		var currentView = this.$el.find('.active');

		this.updatedTemp = value; // setting the value of current object

		// display for the temperature will not show until we get the object for the current temperature
		if (this.updatedTemp !== null) {
	    this.render();
	    this.updateProgressBar();
    }

    if (this.extruderPercentage === 100 && this.bedPercentage === 100) {
    	currentView.removeClass('active').addClass('hide');;
    	this.$("#preheat-wizard__finish-section").removeClass('hide').addClass('active');
    }

	},
	finishClicked: function() {
		this.$("#preheat-wizard__finish-section").removeClass('active').addClass('hide');
		this.$("#preheat-wizard__preheating-progress").removeClass('hide').addClass('active');
	},
	openCancelModal: function() {
		this.$(".preheat-wizard__confirm-cancel-modal").removeClass('hide');
	},
	noHideModal: function(e) {
		e.stopPropagation();
	},
	closeModal: function() {
		this.$(".preheat-wizard__confirm-cancel-modal").addClass('hide');
	},
	stopPreheating: function() {
		var data1 = {
			command: "target",
			targets: {
				tool0: 0
			}
		};

		var data2 = {
			command: "target",
			target: 0
		}

		$.ajax({
      url: API_BASEURL + "printer/" + "tool",
      type: "POST",
      dataType: "json",
      contentType: "application/json; charset=UTF-8",
      data: JSON.stringify(data1),
      success: function() {
      	// console.log("Tool: The request was successfull");
      },
      error: function() {
      	console.log("Tool: There was an error!");
      }
    });

    $.ajax({
      url: API_BASEURL + "printer/" + "bed",
      type: "POST",
      dataType: "json",
      contentType: "application/json; charset=UTF-8",
      data: JSON.stringify(data2),
      success: function() {
      	// console.log("Bed: The request was successfull");
      },
      error: function() {
      	console.log("Bed: There was an erro!");
      }
    });

    this.closeModal();
	},
	updateProgressBar: function() {

		var progressBar1,
		progressBar2,
		extruderTarget,
		extruderActual,
		bedTarget,
		bedActual;

		progressBar1 = $('#extruder-progress-bar');
		progressBar2 = $('#bed-progress-bar');

		extruderActual = this.updatedTemp.extruder.actual;
		extruderTarget = this.updatedTemp.extruder.target;
		bedActual = this.updatedTemp.bed.actual;
		bedTarget = this.updatedTemp.bed.target;

		if (extruderActual > extruderTarget) {
			this.extruderPercentage = Math.min(Math.round(((extruderTarget/extruderActual)*100)));
		} else {
			this.extruderPercentage = Math.min(Math.round(((extruderActual/extruderTarget)*100)));
		}

		progressBar1.val(this.extruderPercentage);

		if (bedActual > bedTarget) {
			this.bedPercentage = Math.min(Math.round(((bedTarget/bedActual)*100)));
		} else {
			this.bedPercentage = Math.min(Math.round(((bedActual/bedTarget)*100)));
		}

		progressBar2.val(this.bedPercentage);
	}
});<|endoftext|>


<commit_before>module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            src: {
                files: ['modules/**/*.js', '!modules/**/server/*.js', '!modules/**/server/**/*.js', 'resources/assets/style.scss'],
                tasks: ['browserify', 'uglify', 'sass']
            }
        },
        browserify: {
            core: {
                src: 'modules/core/client/app/*.js',
                dest: 'public/dist/core/core.js'
            },
            config: {
                src: 'modules/core/client/config/*.js',
                dest: 'public/dist/config/config.js'
            },
            modules: {
                src: [
                    'modules/**/client/module/*.js',
                    'modules/shared/client/**/module/*.js'
                ],
                dest: 'public/dist/modules.js'
            },
            shared: {
                src: 'modules/shared/client/**/*.js',
                dest: 'public/dist/shared/shared.js'
            },
            client: {
                src: [
                    'modules/**/client/*.js',
                    '!modules/**/client/module/*.js'
                ],
                dest: 'public/dist/client.js'
            }
        },
        uglify: {
            core: {
                options: { mangle: false, compress: true },
                src: 'public/dist/core/core.js',
                dest: 'public/dist/core/core.min.js'
            },
            config: {
                options: { mangle: false, compress: true },
                src: 'public/dist/config/config.js',
                dest: 'public/dist/config/config.min.js'
            },
            modules: {
                options: { mangle: false, compress: true },
                src: 'public/dist/modules.js',
                dest: 'public/dist/modules.min.js'
            },
            shared: {
                options: { mangle: false, compress: true },
                src: 'public/dist/shared/shared.js',
                dest: 'public/dist/shared/shared.min.js'
            },
            client: {
                options: { mangle: false, compress: true },
                src: 'public/dist/client.js',
                dest: 'public/dist/client.min.js'
            }
        },
        sass: {
            dist: {
                files: {
                    'public/assets/css/style.css': 'resources/assets/style.scss'
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.registerTask('default', ['browserify', 'uglify', 'sass', 'watch']);
};
<commit_msg>enhance grunt file<commit_after>'use strict';

module.exports = function(grunt) {
    grunt.initConfig({
        watch: {
            livereload: {
                options: {
                    livereload: true
                },
                files: [
                    'modules/**/*',
                    '!modules/**/server/*.js',
                    '!modules/**/server/**/*.js',
                    'resources/assets/style.scss'
                ],
                tasks: ['browserify', 'uglify', 'sass']
            },
        },
        browserify: {
            core: {
                src: 'modules/core/client/app/*.js',
                dest: 'public/dist/core/core.js'
            },
            config: {
                src: 'modules/core/client/config/*.js',
                dest: 'public/dist/config/config.js'
            },
            modules: {
                src: [
                    'modules/**/client/module/*.js',
                    'modules/shared/client/**/module/*.js'
                ],
                dest: 'public/dist/modules.js'
            },
            shared: {
                src: 'modules/shared/client/**/*.js',
                dest: 'public/dist/shared/shared.js'
            },
            client: {
                src: [
                    'modules/**/client/*.js',
                    '!modules/**/client/module/*.js'
                ],
                dest: 'public/dist/client.js'
            }
        },
        uglify: {
            core: {
                options: { mangle: false, compress: true },
                src: 'public/dist/core/core.js',
                dest: 'public/dist/core/core.min.js'
            },
            config: {
                options: { mangle: false, compress: true },
                src: 'public/dist/config/config.js',
                dest: 'public/dist/config/config.min.js'
            },
            modules: {
                options: { mangle: false, compress: true },
                src: 'public/dist/modules.js',
                dest: 'public/dist/modules.min.js'
            },
            shared: {
                options: { mangle: false, compress: true },
                src: 'public/dist/shared/shared.js',
                dest: 'public/dist/shared/shared.min.js'
            },
            client: {
                options: { mangle: false, compress: true },
                src: 'public/dist/client.js',
                dest: 'public/dist/client.min.js'
            }
        },
        sass: {
            dist: {
                files: {
                    'public/assets/css/style.css': 'resources/assets/style.scss'
                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-browserify');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');
    grunt.loadNpmTasks('grunt-contrib-sass');
    grunt.registerTask('default', ['browserify', 'uglify', 'sass', 'watch']);
};
<|endoftext|>


<commit_before>// generated on <%= date %> using <%= name %> <%= version %>
'use strict';

const gulp = require('gulp');

const requireDir = require('require-dir');
const tasks = requireDir('./gulp/tasks', {recurse: true}); // eslint-disable-line

// 'gulp inject' -- injects your CSS and JS into either the header or the footer
gulp.task('inject', gulp.parallel('inject:head', 'inject:footer'));

// 'gulp build:site' -- copies, builds, and then copies it again
gulp.task('build:site', gulp.series('site:tmp', 'inject', 'site', 'copy:site'));

// 'gulp assets' -- cleans out your assets and rebuilds them
// 'gulp assets --prod' -- cleans out your assets and rebuilds them with
// production settings
gulp.task('assets', gulp.series(
  gulp.parallel('styles', 'scripts', 'fonts', 'images'),
  gulp.series('copy:assets')
));

// 'gulp clean' -- erases your assets and gzipped files
gulp.task('clean', gulp.series('clean:assets', 'clean:gzip', 'clean:dist', 'clean:site'));

// 'gulp build' -- same as 'gulp' but doesn't serve your site in your browser
// 'gulp build --prod' -- same as above but with production settings
gulp.task('build', gulp.series(
  gulp.series('clean'),
  gulp.series('assets', 'build:site'),
  gulp.series('html')
));

<% if (!noUpload) { -%>
// You can also just use 'gulp upload' but this way you can see all the main
// tasks in the gulpfile instead of having to hunt for the deploy tasks
gulp.task('deploy', gulp.series('upload'));
<% } -%>

// 'gulp rebuild' -- WARNING: Erases your assets and built site, use only when
// you need to do a complete rebuild
gulp.task('rebuild', gulp.series('clean:dist', 'clean:assets', 'clean:images'));

// 'gulp check' -- checks your site configuration for errors and lint your JS
gulp.task('check', gulp.series('site:doctor'));

// 'gulp' -- cleans your assets and gzipped files, creates your assets and
// injects them into the templates, then builds your site, copied the assets
// into their directory and serves the site
// 'gulp --prod' -- same as above but with production settings
gulp.task('default', gulp.series(
  gulp.series('build', 'serve')
));
<commit_msg>Simplify gulp tasks<commit_after>// generated on <%= date %> using <%= name %> <%= version %>
'use strict';

const gulp = require('gulp');

const requireDir = require('require-dir');
const tasks = requireDir('./gulp/tasks', {recurse: true}); // eslint-disable-line

// 'gulp inject' -- injects your CSS and JS into either the header or the footer
gulp.task('inject', gulp.parallel('inject:head', 'inject:footer'));

// 'gulp build:site' -- copies, builds, and then copies it again
gulp.task('build:site', gulp.series('site:tmp', 'inject', 'site', 'copy:site'));

// 'gulp assets' -- cleans out your assets and rebuilds them
// 'gulp assets --prod' -- cleans out your assets and rebuilds them with
// production settings
gulp.task('assets', gulp.series(
  gulp.parallel('styles', 'scripts', 'fonts', 'images'),
  gulp.series('copy:assets')
));

// 'gulp clean' -- erases your assets and gzipped files
gulp.task('clean', gulp.parallel('clean:assets', 'clean:gzip', 'clean:dist', 'clean:site'));

// 'gulp build' -- same as 'gulp' but doesn't serve your site in your browser
// 'gulp build --prod' -- same as above but with production settings
gulp.task('build', gulp.series('clean', 'assets', 'build:site', 'html'));

<% if (!noUpload) { -%>
// You can also just use 'gulp upload' but this way you can see all the main
// tasks in the gulpfile instead of having to hunt for the deploy tasks
gulp.task('deploy', gulp.series('upload'));
<% } -%>

// 'gulp rebuild' -- WARNING: Erases your assets and built site, use only when
// you need to do a complete rebuild
gulp.task('rebuild', gulp.series('clean', 'clean:images'));

// 'gulp check' -- checks your site configuration for errors and lint your JS
gulp.task('check', gulp.series('site:doctor'));

// 'gulp' -- cleans your assets and gzipped files, creates your assets and
// injects them into the templates, then builds your site, copied the assets
// into their directory and serves the site
// 'gulp --prod' -- same as above but with production settings
gulp.task('default', gulp.series('build', 'serve'));
<|endoftext|>


<commit_before>"use strict";
// Polyfills for commonly used functions for IE8-
SmartPolyfill.register('Object.create', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Safari: '1 - 4'
}, function(o, props){
  function F() {}
  F.prototype = o;
  if (typeof(props) === "object")
    for (var prop in props)
      if (props.hasOwnProperty(prop))
        F[prop] = props[prop];
  return new F();
});
SmartPolyfill.register('Object.keys', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Opera: '1 - 11',
  Safari: '1 - 4'
}, function(o) {
  if (o !== Object(o))
    throw new TypeError('Object.keys called on a non-object');
  var r = [];
  for (r[r.length] in o);
  return r
});<commit_msg>:art: Fix a comment in Object.js<commit_after>"use strict";
// Polyfills for commonly used Object functions
SmartPolyfill.register('Object.create', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Safari: '1 - 4'
}, function(o, props){
  function F() {}
  F.prototype = o;
  if (typeof(props) === "object")
    for (var prop in props)
      if (props.hasOwnProperty(prop))
        F[prop] = props[prop];
  return new F();
});
SmartPolyfill.register('Object.keys', {
  Chrome: '1 - 4',
  Firefox: '1 - 3',
  IE: '1 - 8',
  Opera: '1 - 11',
  Safari: '1 - 4'
}, function(o) {
  if (o !== Object(o))
    throw new TypeError('Object.keys called on a non-object');
  var r = [];
  for (r[r.length] in o);
  return r
});<|endoftext|>


<commit_before>define(["Tone/core/Tone"], function(Tone){

	"use strict";

	/**
	 *  @class  A single master output.
	 *          adds toMaster to Tone
	 *
	 *  @constructor
	 *  @extends {Tone}
	 */
	Tone.Master = function(){
		Tone.call(this);

		/**
		 *  put a hard limiter on the output so we don't blow any eardrums
		 *
		 *  @type {DynamicsCompressorNode}
		 */
		this.limiter = this.context.createDynamicsCompressor();
		this.limiter.threshold.value = 0;
		this.attack = 0.001;
		this.release = 0.01;
		this.limiter.ratio.value = 20;

		//connect it up
		this.input.chain(this.limiter, this.output, this.context.destination);
	};

	Tone.extend(Tone.Master);

	/**
	 *  mute the output
	 *  @param {boolean} muted
	 */
	Tone.Master.prototype.mute = function(muted){
		muted = this.defaultArg(muted, true);
		if (muted){
			this.output.gain.value = 0;
		} else {
			this.output.gain.value = 1;
		}
	};

	/**
	 *  @param {number} db volume in decibels
	 *  @param {Tone.Time=} fadeTime time it takes to reach the value
	 */
	Tone.Master.prototype.setVolume = function(db, fadeTime){
		var now = this.now();
		var gain = this.dbToGain(db);
		if (fadeTime){
			var currentVolume = this.output.gain.value;
			this.output.gain.cancelScheduledValues(now);
			this.output.gain.setValueAtTime(currentVolume, now);
			this.output.gain.linearRampToValueAtTime(gain, now + this.toSeconds(fadeTime));
		} else {
			this.output.gain.setValueAtTime(gain, now);
		}
	};

	///////////////////////////////////////////////////////////////////////////
	//	AUGMENT TONE's PROTOTYPE
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  connect 'this' to the master output
	 *  defined in "Tone/core/Master"
	 */
	Tone.prototype.toMaster = function(){
		this.connect(Tone.Master);
	};

	/**
	 *  Also augment AudioNode's prototype to include toMaster
	 *  as a convenience
	 */
	AudioNode.prototype.toMaster = function(){
		this.connect(Tone.Master);
	};

	var MasterConstructor = Tone.Master;

	/**
	 *  initialize the module and listen for new audio contexts
	 */
	Tone._initAudioContext(function(){
		//a single master output
		if (!Tone.prototype.isUndef(Tone.Master)){
			Tone.Master = new MasterConstructor();
		} else {
			MasterConstructor.call(Tone.Master);
		}
	});

	return Tone.Master;
});<commit_msg>master send/receive<commit_after>define(["Tone/core/Tone"], function(Tone){

	"use strict";

	/**
	 *  @class  A single master output.
	 *          adds toMaster to Tone
	 *
	 *  @constructor
	 *  @extends {Tone}
	 */
	Tone.Master = function(){
		Tone.call(this);

		//connections
		this.input.chain(this.output, this.context.destination);
	};

	Tone.extend(Tone.Master);

	/**
	 *  mute the output
	 *  @param {boolean} muted
	 */
	Tone.Master.prototype.mute = function(muted){
		muted = this.defaultArg(muted, true);
		if (muted){
			this.output.gain.value = 0;
		} else {
			this.output.gain.value = 1;
		}
	};

	/**
	 *  @param {number} db volume in decibels
	 *  @param {Tone.Time=} fadeTime time it takes to reach the value
	 */
	Tone.Master.prototype.setVolume = function(db, fadeTime){
		var now = this.now();
		var gain = this.dbToGain(db);
		if (fadeTime){
			var currentVolume = this.output.gain.value;
			this.output.gain.cancelScheduledValues(now);
			this.output.gain.setValueAtTime(currentVolume, now);
			this.output.gain.linearRampToValueAtTime(gain, now + this.toSeconds(fadeTime));
		} else {
			this.output.gain.setValueAtTime(gain, now);
		}
	};

	/**
	 *  route the master signal to the node's input.
	 *  NOTE: this will disconnect the previously connected node
	 *  @param {AudioNode|Tone} node the node to use as the entry
	 *                               point to the master chain
	 */
	Tone.Master.prototype.send = function(node){
		//disconnect the previous node
		this.input.disconnect();
		this.input.connect(node);
	};

	/**
	 *  the master effects chain return point
	 *  @param {AudioNode|Tone} node the node to connect
	 */
	Tone.Master.prototype.receive = function(node){
		node.connect(this.output);
	};

	///////////////////////////////////////////////////////////////////////////
	//	AUGMENT TONE's PROTOTYPE
	///////////////////////////////////////////////////////////////////////////

	/**
	 *  connect 'this' to the master output
	 *  defined in "Tone/core/Master"
	 */
	Tone.prototype.toMaster = function(){
		this.connect(Tone.Master);
	};

	/**
	 *  Also augment AudioNode's prototype to include toMaster
	 *  as a convenience
	 */
	AudioNode.prototype.toMaster = function(){
		this.connect(Tone.Master);
	};

	var MasterConstructor = Tone.Master;

	/**
	 *  initialize the module and listen for new audio contexts
	 */
	Tone._initAudioContext(function(){
		//a single master output
		if (!Tone.prototype.isUndef(Tone.Master)){
			Tone.Master = new MasterConstructor();
		} else {
			MasterConstructor.prototype.dispose.call(Tone.Master);
			MasterConstructor.call(Tone.Master);
		}
	});

	return Tone.Master;
});<|endoftext|>


<commit_before>import {Fragment, useState, useMemo, useContext} from 'react';
import {useLocation} from 'react-router-dom';
import {useResource, useURL, selectAPINull} from '@xorkevin/substation';
import {useAuthValue, useAuthResource, useLogin} from '@xorkevin/turbine';
import {
  MainContent,
  Section,
  Container,
  Grid,
  Card,
  Field,
  Form,
  useForm,
  ButtonGroup,
  FaIcon,
} from '@xorkevin/nuke';
import ButtonPrimary from '@xorkevin/nuke/src/component/button/primary';
import ButtonTertiary from '@xorkevin/nuke/src/component/button/tertiary';
import AnchorText from '@xorkevin/nuke/src/component/anchor/text';
import Img from '@xorkevin/nuke/src/component/image/rounded';
import ImgCircle from '@xorkevin/nuke/src/component/image/circle';

import {GovUICtx} from '../../middleware';
import {getSearchParams} from '../../utility';

const selectAPIApp = (api) => api.oauth.app.id;
const selectAPIImage = (api) => api.oauth.app.id.image;
const selectAPIProfile = (api) => api.profile.get;
const selectAPIProfileImage = (api) => api.profile.id.image;

const CardHeader = () => {
  const ctx = useContext(GovUICtx);
  return (
    <Container padded>

Sign in with {ctx.siteName}

    </Container>
  );
};

const CardLogo = ({app}) => {
  const imageURL = useURL(selectAPIImage, [app.client_id]);
  if (!app.logo) {
    return null;
  }
  return (

  );
};

const CardLink = ({app}) => {
  return (
    <AnchorText ext href={app.url}>
      {app.name}
    </AnchorText>
  );
};

const CardAccount = ({profile}) => {
  const {userid, username} = useAuthValue();
  const imageURL = useURL(selectAPIProfileImage, [userid]);
  return (
    <Grid justify="center" align="center">
      {profile.image && (
        <ImgCircle
          className="oauth-auth-profile-image"
          src={imageURL}
          preview={profile.image}
          ratio={1}
        />
      )}

{username}

    </Grid>
  );
};

const Login = ({app, loginPosthook, usernameHint}) => {
  const form = useForm({
    username: usernameHint || '',
    password: '',
  });

  const [login, execLogin] = useLogin(form.state.username, form.state.password);
  if (login.success) {
    loginPosthook();
  }

  return (
    <Card
      center
      width="md"
      title={<CardHeader />}
      bar={
        <Fragment>
          <ButtonGroup>
            <ButtonTertiary>
              <FaIcon icon="ellipsis-v" />
            </ButtonTertiary>
            <ButtonPrimary onClick={execLogin}>Login</ButtonPrimary>
          </ButtonGroup>
        </Fragment>
      }
    >
      <Container padded>
        <CardLogo app={app} />

          Log in to continue to <CardLink app={app} />

        <Form
          formState={form.state}
          onChange={form.update}
          onSubmit={execLogin}
        >
          <Field
            name="username"
            label="Username / Email"
            fullWidth
            autoComplete="username"
            autoFocus
          />
          <Field
            name="password"
            type="password"
            label="Password"
            fullWidth
            autoComplete="current-password"
          />
        </Form>
        {login.err &&
{login.err}
}
      </Container>
    </Card>
  );
};

const CheckConsent = ({app, profile, scopes}) => {
  const ctx = useContext(GovUICtx);
  return (
    <Card
      center
      width="md"
      title={<CardHeader />}
      bar={
        <Fragment>
          <ButtonGroup>
            <ButtonTertiary>
              <FaIcon icon="ellipsis-v" />
            </ButtonTertiary>
            <ButtonTertiary>Cancel</ButtonTertiary>
            <ButtonPrimary>Allow</ButtonPrimary>
          </ButtonGroup>
        </Fragment>
      }
    >
      <Container padded>
        <CardLogo app={app} />

          <CardLink app={app} /> wants to access your {ctx.siteName} account

        <CardAccount profile={profile} />

          This will allow <CardLink app={app} /> to:

        {scopes
          .filter((i) => ctx.openidAllScopeDesc[i])
          .map((i) => (
            <Grid key={i} align="center">
              {' '}

                {ctx.openidAllScopeDesc[i]}

            </Grid>
          ))}
      </Container>
    </Card>
  );
};

const OID_PROMPT_NONE = 'none';
const OID_PROMPT_LOGIN = 'login';
const OID_PROMPT_CONSENT = 'consent';
const OID_PROMPT_SELECT = 'select_account';

const intRegex = /^\d+$/;

const AuthFlow = ({app, params, reqParams}) => {
  const ctx = useContext(GovUICtx);
  const {loggedIn, username, timeAuth} = useAuthValue();

  const [performedRelogin, setRelogin] = useState(false);
  const reloginPosthook = useMemo(() => {
    if (performedRelogin) {
      return () => {};
    }
    return () => {
      setRelogin(true);
    };
  }, [performedRelogin, setRelogin]);

  const [profile] = useAuthResource(
    loggedIn ? selectAPIProfile : selectAPINull,
    [],
    {
      image: '',
    },
  );

  const maxAgeValid = intRegex.test(params.maxage);
  const maxAge = maxAgeValid ? parseInt(params.maxage, 10) : -1;

  const openidAllScopeSet = useMemo(() => new Set(ctx.openidAllScopes), [ctx]);
  const scopes = useMemo(
    () => reqParams.scope.split(' ').filter((i) => openidAllScopeSet.has(i)),
    [reqParams, openidAllScopeSet],
  );
  const prompts = useMemo(() => new Set(params.prompt.split(' ')), [params]);

  const showNone = prompts.has(OID_PROMPT_NONE);
  if (showNone) {
    return null;
  }
  const showLogin =
    !loggedIn ||
    (params.loginHint !== '' && params.loginHint !== username) ||
    prompts.has(OID_PROMPT_LOGIN) ||
    (maxAgeValid && Date.now() / 1000 - timeAuth > maxAge);
  if (showLogin) {
    return (
      <Login
        app={app}
        loginPosthook={reloginPosthook}
        usernameHint={
          params.loginHint !== '' ? params.loginHint : loggedIn && username
        }
      />
    );
  }
  const showConsent = prompts.has(OID_PROMPT_CONSENT);
  if (showConsent) {
    return <CheckConsent app={app} profile={profile.data} scopes={scopes} />;
  }
  const _showSelect = prompts.has(OID_PROMPT_SELECT);
  return <CheckConsent app={app} profile={profile.data} scopes={scopes} />;
};

const ErrCard = ({children}) => {
  return (
    <Card center width="md" title={<CardHeader />}>
      <Container padded>{children}</Container>
    </Card>
  );
};

const AuthContainer = () => {
  const {search} = useLocation();
  const [clientid, params, reqParams] = useMemo(() => {
    const query = getSearchParams(search);
    const clientid = query.get('client_id') || '';
    return [
      clientid,
      {
        responseMode: query.get('response_mode'),
        redirectURI: query.get('redirect_uri'),
        state: query.get('state'),
        codeChallenge: query.get('code_challenge'),
        codeChallengeMethod: query.get('code_challenge_method'),
        display: query.get('display'),
        prompt: query.get('prompt') || '',
        maxage: query.get('max_age') || '',
        idtokenHint: query.get('id_token_hint'),
        loginHint: query.get('login_hint') || '',
      },
      {
        client_id: clientid,
        responseType: query.get('response_type'),
        scope: query.get('scope') || '',
        nonce: query.get('nonce'),
      },
    ];
  }, [search]);

  const [app] = useResource(
    clientid.length > 0 ? selectAPIApp : selectAPINull,
    [clientid],
    {},
  );

  const redirectValid = params.redirectURI === app.data.redirect_uri;

  return (
    <MainContent>

        <Container padded narrow>
          {app.success &&
            (redirectValid ? (
              <AuthFlow app={app.data} params={params} reqParams={reqParams} />
            ) : (
              <ErrCard>

Invalid OAuth redirect url

              </ErrCard>
            ))}
          {clientid.length === 0 && (
            <ErrCard>

Invalid OAuth client

            </ErrCard>
          )}
          {app.err && (
            <ErrCard>

{app.err}

            </ErrCard>
          )}
        </Container>

    </MainContent>
  );
};

export default AuthContainer;
<commit_msg>Impl oauth error redirect<commit_after>import {Fragment, useState, useCallback, useMemo, useContext} from 'react';
import {useLocation} from 'react-router-dom';
import {useResource, useURL, selectAPINull} from '@xorkevin/substation';
import {useAuthValue, useAuthResource, useLogin} from '@xorkevin/turbine';
import {
  MainContent,
  Section,
  Container,
  Grid,
  Card,
  Field,
  Form,
  useForm,
  ButtonGroup,
  FaIcon,
} from '@xorkevin/nuke';
import ButtonPrimary from '@xorkevin/nuke/src/component/button/primary';
import ButtonTertiary from '@xorkevin/nuke/src/component/button/tertiary';
import AnchorText from '@xorkevin/nuke/src/component/anchor/text';
import Img from '@xorkevin/nuke/src/component/image/rounded';
import ImgCircle from '@xorkevin/nuke/src/component/image/circle';

import {GovUICtx} from '../../middleware';
import {getSearchParams} from '../../utility';

const selectAPIApp = (api) => api.oauth.app.id;
const selectAPIImage = (api) => api.oauth.app.id.image;
const selectAPIProfile = (api) => api.profile.get;
const selectAPIProfileImage = (api) => api.profile.id.image;

const CardHeader = () => {
  const ctx = useContext(GovUICtx);
  return (
    <Container padded>

Sign in with {ctx.siteName}

    </Container>
  );
};

const CardLogo = ({app}) => {
  const imageURL = useURL(selectAPIImage, [app.client_id]);
  if (!app.logo) {
    return null;
  }
  return (

  );
};

const CardLink = ({app}) => {
  return (
    <AnchorText ext href={app.url}>
      {app.name}
    </AnchorText>
  );
};

const CardAccount = ({profile}) => {
  const {userid, username} = useAuthValue();
  const imageURL = useURL(selectAPIProfileImage, [userid]);
  return (
    <Grid justify="center" align="center">
      {profile.image && (
        <ImgCircle
          className="oauth-auth-profile-image"
          src={imageURL}
          preview={profile.image}
          ratio={1}
        />
      )}

{username}

    </Grid>
  );
};

const Login = ({app, loginPosthook, usernameHint}) => {
  const form = useForm({
    username: usernameHint || '',
    password: '',
  });

  const [login, execLogin] = useLogin(form.state.username, form.state.password);
  if (login.success) {
    loginPosthook();
  }

  return (
    <Card
      center
      width="md"
      title={<CardHeader />}
      bar={
        <Fragment>
          <ButtonGroup>
            <ButtonTertiary>
              <FaIcon icon="ellipsis-v" />
            </ButtonTertiary>
            <ButtonPrimary onClick={execLogin}>Login</ButtonPrimary>
          </ButtonGroup>
        </Fragment>
      }
    >
      <Container padded>
        <CardLogo app={app} />

          Log in to continue to <CardLink app={app} />

        <Form
          formState={form.state}
          onChange={form.update}
          onSubmit={execLogin}
        >
          <Field
            name="username"
            label="Username / Email"
            fullWidth
            autoComplete="username"
            autoFocus
          />
          <Field
            name="password"
            type="password"
            label="Password"
            fullWidth
            autoComplete="current-password"
          />
        </Form>
        {login.err &&
{login.err}
}
      </Container>
    </Card>
  );
};

const CheckConsent = ({app, profile, scopes}) => {
  const ctx = useContext(GovUICtx);
  return (
    <Card
      center
      width="md"
      title={<CardHeader />}
      bar={
        <Fragment>
          <ButtonGroup>
            <ButtonTertiary>
              <FaIcon icon="ellipsis-v" />
            </ButtonTertiary>
            <ButtonTertiary>Cancel</ButtonTertiary>
            <ButtonPrimary>Allow</ButtonPrimary>
          </ButtonGroup>
        </Fragment>
      }
    >
      <Container padded>
        <CardLogo app={app} />

          <CardLink app={app} /> wants to access your {ctx.siteName} account

        <CardAccount profile={profile} />

          This will allow <CardLink app={app} /> to:

        {scopes
          .filter((i) => ctx.openidAllScopeDesc[i])
          .map((i) => (
            <Grid key={i} align="center">
              {' '}

                {ctx.openidAllScopeDesc[i]}

            </Grid>
          ))}
      </Container>
    </Card>
  );
};

const OID_ERR_INVALID_REQ = 'invalid_request';
const OID_ERR_UNSUPPORTED_RESTYPE = 'unsupported_response_type';

const OID_RESTYPE_CODE = 'code';

const OID_RESMODE_QUERY = 'query';
const OID_RESMODE_FRAGMENT = 'fragment';

const OID_RESMODE_SET = new Set([OID_RESMODE_QUERY, OID_RESMODE_FRAGMENT]);

const OID_PROMPT_NONE = 'none';
const OID_PROMPT_LOGIN = 'login';
const OID_PROMPT_CONSENT = 'consent';
const OID_PROMPT_SELECT = 'select_account';

const intRegex = /^\d+$/;

const AuthFlow = ({app, params, reqParams}) => {
  const ctx = useContext(GovUICtx);
  const {loggedIn, username, timeAuth} = useAuthValue();

  const [performedRelogin, setRelogin] = useState(false);
  const reloginPosthook = useMemo(() => {
    if (performedRelogin) {
      return () => {};
    }
    return () => {
      setRelogin(true);
    };
  }, [performedRelogin, setRelogin]);

  const [profile] = useAuthResource(
    loggedIn ? selectAPIProfile : selectAPINull,
    [],
    {
      image: '',
    },
  );

  const maxAgeValid = intRegex.test(params.maxage);
  const maxAge = maxAgeValid ? parseInt(params.maxage, 10) : -1;

  const openidAllScopeSet = useMemo(() => new Set(ctx.openidAllScopes), [ctx]);
  const scopes = useMemo(
    () => reqParams.scope.split(' ').filter((i) => openidAllScopeSet.has(i)),
    [reqParams, openidAllScopeSet],
  );
  const prompts = useMemo(() => new Set(params.prompt.split(' ')), [params]);

  const showNone = prompts.has(OID_PROMPT_NONE);
  if (showNone) {
    return null;
  }
  const showLogin =
    !loggedIn ||
    (params.loginHint !== '' && params.loginHint !== username) ||
    prompts.has(OID_PROMPT_LOGIN) ||
    (maxAgeValid && Date.now() / 1000 - timeAuth > maxAge);
  if (showLogin) {
    return (
      <Login
        app={app}
        loginPosthook={reloginPosthook}
        usernameHint={
          params.loginHint !== '' ? params.loginHint : loggedIn && username
        }
      />
    );
  }
  const showConsent = prompts.has(OID_PROMPT_CONSENT);
  if (showConsent) {
    return <CheckConsent app={app} profile={profile.data} scopes={scopes} />;
  }
  const _showSelect = prompts.has(OID_PROMPT_SELECT);
  return <CheckConsent app={app} profile={profile.data} scopes={scopes} />;
};

const ErrCard = ({children}) => {
  return (
    <Card center width="md" title={<CardHeader />}>
      <Container padded>{children}</Container>
    </Card>
  );
};

const AuthContainer = () => {
  const {search} = useLocation();
  const [
    clientid,
    redirectURI,
    responseType,
    responseMode,
    state,
    params,
    reqParams,
  ] = useMemo(() => {
    const query = getSearchParams(search);
    const clientid = query.get('client_id') || '';
    return [
      clientid,
      query.get('redirect_uri'),
      query.get('response_type'),
      query.get('response_mode') || OID_RESMODE_QUERY,
      query.get('state'),
      {
        codeChallenge: query.get('code_challenge'),
        codeChallengeMethod: query.get('code_challenge_method'),
        display: query.get('display'),
        prompt: query.get('prompt') || '',
        maxage: query.get('max_age') || '',
        idtokenHint: query.get('id_token_hint'),
        loginHint: query.get('login_hint') || '',
      },
      {
        client_id: clientid,
        scope: query.get('scope') || '',
        nonce: query.get('nonce'),
      },
    ];
  }, [search]);

  const [app] = useResource(
    clientid.length > 0 ? selectAPIApp : selectAPINull,
    [clientid],
    {},
  );

  const redirectValid = redirectURI === app.data.redirect_uri;
  const responseTypeValid = responseType === OID_RESTYPE_CODE;
  const responseModeValid = OID_RESMODE_SET.has(responseMode);

  const redirErr = useCallback(
    (errcode, msg) => {
      if (!redirectURI) {
        return;
      }
      const modeFrag =
        responseModeValid && responseMode === OID_RESMODE_FRAGMENT;
      try {
        const url = new URL(redirectURI);
        const q = modeFrag ? new URLSearchParams() : url.searchParams;
        q.set('error', errcode);
        if (msg) {
          q.set('error_description', msg);
        }
        if (state) {
          q.Add('state', state);
        }
        if (modeFrag) {
          url.hash = '#' + q.toString();
        }
        window.location.replace(url.toString());
      } catch (_e) {}
    },
    [redirectURI, responseMode, responseModeValid, state],
  );

  if (redirectValid) {
    if (!responseTypeValid) {
      redirErr(OID_ERR_UNSUPPORTED_RESTYPE, 'Invalid response type');
    }
    if (!responseModeValid) {
      redirErr(OID_ERR_INVALID_REQ, 'Invalid response mode');
    }
  }

  return (
    <MainContent>

        <Container padded narrow>
          {app.success &&
            (redirectValid ? (
              <AuthFlow
                redirErr={redirErr}
                app={app.data}
                params={params}
                reqParams={reqParams}
              />
            ) : (
              <ErrCard>
                <CardLogo app={app.data} />

                  Error logging in to <CardLink app={app.data} />

Invalid OAuth redirect url

              </ErrCard>
            ))}
          {clientid.length === 0 && (
            <ErrCard>

Invalid OAuth client

            </ErrCard>
          )}
          {app.err && (
            <ErrCard>

{app.err}

            </ErrCard>
          )}
        </Container>

    </MainContent>
  );
};

export default AuthContainer;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/actions';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import { NavLink } from '../components/NavLink';
import FontIcon from 'material-ui/FontIcon';
import { List, ListItem } from 'material-ui/List';
import Badge from 'material-ui/Badge';
import kinectsitTheme from '../assets/kinectsitTheme';
import FolderIcon from 'material-ui/svg-icons/file/folder-open';
import { Card, CardActions, CardHeader, CardMedia, CardTitle, CardText } from 'material-ui/Card';

export class DeviceRow extends React.Component {

  setFeatured() {
    this.props.actions.setFeatured(this.props.device);
  }

  render() {
    let active = 'Active';
    let buttonMessage = 'View Transactions';

    if (this.props.device.isactive === false) {
      buttonMessage = 'Purchase Usage';
      active = 'No';
    }

    let guestButton = (
      <NavLink to="/device">
        <RaisedButton className="device-button" label={buttonMessage} onClick={() => this.setFeatured()} />
      </NavLink>
    );

    if (this.props.appState.isHost) {
      return (
        <Card>
          <CardHeader
            title={this.props.device.name}
            subtitle="Subtitle"
            avatar="http://lorempixel.com/100/100/nature/"
          />

Is Active: {active}

            <NavLink to="/device-profile">
              <RaisedButton
                label="Device Options"
                onClick={() => this.setFeatured()}
              />
            </NavLink>

        </Card>
      );
    }
    return (
      <Card className={'device-card '.concat(active === 'No' ? 'inactive' : 'active')}>
        <FontIcon
          className="material-icons"
        >
        widgets
        </FontIcon>
        <CardHeader
          className="device-header"
          title={this.props.device.name}
          actAsExpander
          showExpandableButton
        />
        <CardText expandable>

            <List className="description-list">
              <ListItem primaryText={'Name: '.concat(this.props.device.name)} />
              <ListItem primaryText={'Is Active: '.concat(active)} />
            </List>

        </CardText>
        {guestButton}
      </Card>
    );
  }
}

DeviceRow.propTypes = {
  device: PropTypes.object.isRequired,
  appState: PropTypes.object.isRequired,
  actions: PropTypes.object.isRequired,
};

function mapStateToProps(state) {
  return {
    appState: state.appState,
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(actions, dispatch),
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(DeviceRow);

<commit_msg>fixed linting errors<commit_after>import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as actions from '../actions/actions';
import RaisedButton from 'material-ui/RaisedButton';
import { NavLink } from '../components/NavLink';
import FontIcon from 'material-ui/FontIcon';
import { List, ListItem } from 'material-ui/List';
// import kinectsitTheme from '../assets/kinectsitTheme';
import { Card, CardHeader, CardText } from 'material-ui/Card';

export class DeviceRow extends React.Component {

  setFeatured() {
    this.props.actions.setFeatured(this.props.device);
  }

  render() {
    let active = 'Active';
    let buttonMessage = 'View Transactions';

    if (this.props.device.isactive === false) {
      buttonMessage = 'Purchase Usage';
      active = 'No';
    }

    let guestButton = (
      <NavLink to="/device">
        <RaisedButton
          className="device-button"
          label={buttonMessage}
          onClick={() => this.setFeatured()}
        />
      </NavLink>
    );

    if (this.props.appState.isHost) {
      return (
        <Card>
          <CardHeader
            title={this.props.device.name}
            subtitle="Subtitle"
            avatar="http://lorempixel.com/100/100/nature/"
          />

Is Active: {active}

            <NavLink to="/device-profile">
              <RaisedButton
                label="Device Options"
                onClick={() => this.setFeatured()}
              />
            </NavLink>

        </Card>
      );
    }
    return (
      <Card className={'device-card '.concat(active === 'No' ? 'inactive' : 'active')}>
        <FontIcon
          className="material-icons"
        >
        widgets
        </FontIcon>
        <CardHeader
          className="device-header"
          title={this.props.device.name}
          actAsExpander
          showExpandableButton
        />
        <CardText expandable>

            <List className="description-list">
              <ListItem primaryText={'Name: '.concat(this.props.device.name)} />
              <ListItem primaryText={'Is Active: '.concat(active)} />
            </List>

        </CardText>
        {guestButton}
      </Card>
    );
  }
}

DeviceRow.propTypes = {
  device: PropTypes.object.isRequired,
  appState: PropTypes.object.isRequired,
  actions: PropTypes.object.isRequired,
};

function mapStateToProps(state) {
  return {
    appState: state.appState,
  };
}

function mapDispatchToProps(dispatch) {
  return {
    actions: bindActionCreators(actions, dispatch),
  };
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(DeviceRow);

<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react'
import { Provider } from 'react-redux'
import { Router, RouterContext } from 'react-router'
import { AppContainer } from 'react-hot-loader'
import getRoutes from '../../routes'

class Root extends Component {
  render () {
    const { store, history, renderProps } = this.props
    return (
      <AppContainer>
        <Provider store={store}>
          { __SERVER__
            ? <RouterContext {...renderProps} />
            : <Router key={Math.random()} history={history} routes={getRoutes()} />
          }
        </Provider>
      </AppContainer>
    )
  }
}

Root.propTypes = {
  store: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
  renderProps: PropTypes.object
}

export default Root
<commit_msg>refactor(containers): Root<commit_after>import React, { Component, PropTypes } from 'react'
import { Provider } from 'react-redux'
import { Router, RouterContext } from 'react-router'
import { AppContainer } from 'react-hot-loader'
import getRoutes from '../../routes'

class Root extends Component {
  render () {
    const { store, history, renderProps } = this.props
    const routes = getRoutes(store)
    return (
      <AppContainer>
        <Provider store={store}>
          { __SERVER__
            ? <RouterContext {...renderProps} />
            : <Router key={Math.random()} history={history} routes={routes} />
          }
        </Provider>
      </AppContainer>
    )
  }
}

Root.propTypes = {
  store: PropTypes.object.isRequired,
  history: PropTypes.object.isRequired,
  renderProps: PropTypes.object
}

export default Root
<|endoftext|>


<commit_before>import { connect } from 'react-redux'
import ErrorBoundary from '../components/ErrorBoundary'
import Footer from '@twreporter/react-components/lib/footer'
import Header from '@twreporter/universal-header/lib/containers/header'
import PropTypes from 'prop-types'
import React from 'react'
// comment out WebPush for live blog banners to occupy the space for the time being
// import WebPush from '../components/web-push'
import styled from 'styled-components'
import twreporterRedux from '@twreporter/redux'
import uiConst from '../constants/ui'
import uiManager from '../managers/ui-manager'

// lodash
import get from 'lodash/get'
import values from 'lodash/values'

const _ = {
  get,
  values,
}

const { reduxStateFields } = twreporterRedux

const AppBox = styled.div`
  background-color: ${props => props.backgroundColor};
`

const ContentBlock = styled.div`
  position: relative;
`

const HeaderContainer = styled.div`
  position: sticky;
  top: 0;
  z-index: 1000; // other components in twreporter-react has z-index 999
`

const TransparentHeader = styled.div`
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000; // other component has z-index 999
`

// TODO add `pink` theme to universal-header
const PinkBackgroundHeader = styled.div`
  position: relative;
  background-color: #fabcf0;
`

const renderFooter = (footerType, pathname = '', host = '', releaseBranch) => {
  switch (footerType) {
    case uiConst.footer.none: {
      return null
    }
    case uiConst.footer.default:
    default: {
      return (
        <Footer host={host} pathname={pathname} releaseBranch={releaseBranch} />
      )
    }
  }
}

const renderHeader = (headerType, releaseBranch) => {
  let headerTheme
  switch (headerType) {
    case uiConst.header.none:
      return null
    case uiConst.header.transparent:
    case uiConst.header.pink:
      headerTheme = 'transparent'
      break
    case uiConst.header.photo:
      headerTheme = 'photography'
      break
    default:
      headerTheme = 'normal'
      break
  }

  let headerElement = (
    <Header
      theme={headerTheme}
      releaseBranch={releaseBranch}
      isLinkExternal={false}
    />
  )
  if (headerType === uiConst.header.transparent) {
    headerElement = <TransparentHeader>{headerElement}</TransparentHeader>
  } else if (headerType === uiConst.header.pink) {
    headerElement = <PinkBackgroundHeader>{headerElement}</PinkBackgroundHeader>
  }

  return (
    <HeaderContainer className="hidden-print">{headerElement}</HeaderContainer>
  )
}

class AppShell extends React.PureComponent {
  static propTypes = {
    apiOrigin: PropTypes.string,
    backgroundColor: PropTypes.string,
    footerType: PropTypes.oneOf(_.values(uiConst.footer)),
    headerType: PropTypes.oneOf(_.values(uiConst.header)),
    releaseBranch: PropTypes.string.isRequired,
    userId: PropTypes.string,
    children: PropTypes.oneOfType([
      PropTypes.arrayOf(PropTypes.node),
      PropTypes.node,
    ]),
    pathname: PropTypes.string.isRequired,
    host: PropTypes.string.isRequired,
  }

  static defaultProps = {
    headerType: uiConst.header.default,
    footerType: uiConst.footer.default,
    backgroundColor: '#f1f1f1',
  }

  render() {
    const {
      // apiOrigin,
      headerType,
      footerType,
      backgroundColor,
      releaseBranch,
      children,
      // userId,
      pathname,
      host,
    } = this.props

    return (
      <ErrorBoundary>
        <AppBox backgroundColor={backgroundColor}>
          <ContentBlock>
            {/* <WebPush apiOrigin={apiOrigin} userId={userId} /> */}
            {renderHeader(headerType, releaseBranch)}
            {children}
            {renderFooter(footerType, pathname, host, releaseBranch)}
          </ContentBlock>
        </AppBox>
      </ErrorBoundary>
    )
  }
}

function mapStateToProps(state, ownProps) {
  return Object.assign(
    {
      apiOrigin: _.get(state, [reduxStateFields.origins, 'api'], ''),
      userId: _.get(state, [reduxStateFields.auth, 'userInfo.id']),
      pathname: _.get(ownProps.location, 'pathname', ''),
      host: _.get(ownProps.location, 'host', ''),
    },
    uiManager.getLayoutObj(state, ownProps.location)
  )
}

export default connect(mapStateToProps)(AppShell)
<commit_msg>fix: import header with featuer toggle applied level<commit_after>import { connect } from 'react-redux'
import ErrorBoundary from '../components/ErrorBoundary'
import Footer from '@twreporter/react-components/lib/footer'
import { Header } from '@twreporter/universal-header/lib/index'
import PropTypes from 'prop-types'
import React from 'react'
// comment out WebPush for live blog banners to occupy the space for the time being
// import WebPush from '../components/web-push'
import styled from 'styled-components'
import twreporterRedux from '@twreporter/redux'
import uiConst from '../constants/ui'
import uiManager from '../managers/ui-manager'

// lodash
import get from 'lodash/get'
import values from 'lodash/values'

const _ = {
  get,
  values,
}

const { reduxStateFields } = twreporterRedux

const AppBox = styled.div`
  background-color: ${props => props.backgroundColor};
`

const ContentBlock = styled.div`
  position: relative;
`

const HeaderContainer = styled.div`
  position: sticky;
  top: 0;
  z-index: 1000; // other components in twreporter-react has z-index 999
`

const TransparentHeader = styled.div`
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 1000; // other component has z-index 999
`

// TODO add `pink` theme to universal-header
const PinkBackgroundHeader = styled.div`
  position: relative;
  background-color: #fabcf0;
`

const renderFooter = (footerType, pathname = '', host = '', releaseBranch) => {
  switch (footerType) {
    case uiConst.footer.none: {
      return null
    }
    case uiConst.footer.default:
    default: {
      return (
        <Footer host={host} pathname={pathname} releaseBranch={releaseBranch} />
      )
    }
  }
}

const renderHeader = (headerType, releaseBranch) => {
  let headerTheme
  switch (headerType) {
    case uiConst.header.none:
      return null
    case uiConst.header.transparent:
    case uiConst.header.pink:
      headerTheme = 'transparent'
      break
    case uiConst.header.photo:
      headerTheme = 'photography'
      break
    default:
      headerTheme = 'normal'
      break
  }

  let headerElement = (
    <Header
      theme={headerTheme}
      releaseBranch={releaseBranch}
      isLinkExternal={false}
    />
  )
  if (headerType === uiConst.header.transparent) {
    headerElement = <TransparentHeader>{headerElement}</TransparentHeader>
  } else if (headerType === uiConst.header.pink) {
    headerElement = <PinkBackgroundHeader>{headerElement}</PinkBackgroundHeader>
  }

  return (
    <HeaderContainer className="hidden-print">{headerElement}</HeaderContainer>
  )
}

class AppShell extends React.PureComponent {
  static propTypes = {
    apiOrigin: PropTypes.string,
    backgroundColor: PropTypes.string,
    footerType: PropTypes.oneOf(_.values(uiConst.footer)),
    headerType: PropTypes.oneOf(_.values(uiConst.header)),
    releaseBranch: PropTypes.string.isRequired,
    userId: PropTypes.string,
    children: PropTypes.oneOfType([
      PropTypes.arrayOf(PropTypes.node),
      PropTypes.node,
    ]),
    pathname: PropTypes.string.isRequired,
    host: PropTypes.string.isRequired,
  }

  static defaultProps = {
    headerType: uiConst.header.default,
    footerType: uiConst.footer.default,
    backgroundColor: '#f1f1f1',
  }

  render() {
    const {
      // apiOrigin,
      headerType,
      footerType,
      backgroundColor,
      releaseBranch,
      children,
      // userId,
      pathname,
      host,
    } = this.props

    return (
      <ErrorBoundary>
        <AppBox backgroundColor={backgroundColor}>
          <ContentBlock>
            {/* <WebPush apiOrigin={apiOrigin} userId={userId} /> */}
            {renderHeader(headerType, releaseBranch)}
            {children}
            {renderFooter(footerType, pathname, host, releaseBranch)}
          </ContentBlock>
        </AppBox>
      </ErrorBoundary>
    )
  }
}

function mapStateToProps(state, ownProps) {
  return Object.assign(
    {
      apiOrigin: _.get(state, [reduxStateFields.origins, 'api'], ''),
      userId: _.get(state, [reduxStateFields.auth, 'userInfo.id']),
      pathname: _.get(ownProps.location, 'pathname', ''),
      host: _.get(ownProps.location, 'host', ''),
    },
    uiManager.getLayoutObj(state, ownProps.location)
  )
}

export default connect(mapStateToProps)(AppShell)
<|endoftext|>


<commit_before>var Control = require('../core/Control');

/**
 * entry point for your application, makes some assumptions, (e.g. that you
 * always want fullscreen) and shortcuts some fancy stuff like a gradient
 * background.
 *
 * @class Application
 * @extends PIXI_UI.Control
 * @memberof PIXI_UI
 * @constructor
 * @param background {Number | Array} a background color or a list of colors
 *  that will be used as vertical gradient
 * @param fullscreen {Boolean}
 * @param renderer {WebGLRenderer|CanvasRenderer}
 * @param stage {Stage}
 */
function Application(background, fullscreen, renderer, stage) {
    if (!stage || !renderer) {
        stage = new PIXI.Container();
        var width = 800;
        var height = 600;
        if (fullscreen) {
            width = window.innerWidth;
            height = window.innerHeight;
        }
        renderer = PIXI.autoDetectRenderer(
            width, height, {backgroundColor : 0xffffff});
        document.body.appendChild(renderer.view);
    }
    /* jshint ignore:start */
    this._stage = stage;
    this._renderer = renderer;
    /* jshint ignore:end */
    this._width = renderer.width;
    this._height = renderer.height;

    Control.call(this);
    stage.addChild(this);
    this.animate();

    this.background = background;
    this.fullscreen = fullscreen;
}

Application.prototype = Object.create( Control.prototype );
Application.prototype.constructor = Application;
module.exports = Application;

/* jshint ignore:start */
Application.prototype.animate = function() {
    var renderer = this._renderer;
    var stage = this._stage;
    var animate = function() {
        renderer.render(stage);
        requestAnimationFrame(animate);
    };
    requestAnimationFrame(animate);
};
/* jshint ignore:end */

/**
 * creates a gradient rect that can be used as background
 *
 * @method _createGradientRect
 * @private
 */
Application.prototype._createGradientRect = function(width, height, gradient) {
    var bgCanvas = document.createElement('canvas');
    bgCanvas.width = width;
    bgCanvas.height = height;
    var ctx = bgCanvas.getContext('2d');
    var linearGradient = ctx.createLinearGradient(0,0,0,height);
    for (var i = 0; i < gradient.length; i++) {
        linearGradient.addColorStop(i, gradient[i]);
    }
    ctx.fillStyle = linearGradient;
    ctx.fillRect(0,0,width,height);
    return PIXI.Texture.fromCanvas(bgCanvas);
};

Application.prototype.onresize = function() {
    this._width = window.innerWidth;
    this._height = window.innerHeight;
    this._renderer.resize(this._width, this._height);
    if (this.bg) {
        this.bg.width = this._width;
        this.bg.height = this._height;
    }
    for (var i = 0; i < this.children.length; i++) {
        var child = this.children[i];
        if (child.onresize) {
            child.onresize(this._width, this._height);
        }
    }
};

/**
 * set fullscreen and resize to screen size
 *
 * @property enabled
 * @type Boolean
 */
Object.defineProperty(Application.prototype, 'fullscreen', {
    get: function() {
        return this._fullscreen;
    },
    set: function(value) {
        if (this._fullscreen && !value) {
            window.removeEventListener('resize');
        } else if (!this._fullscreen && value) {
            window.addEventListener('resize', this.onresize.bind(this));
        }
        this._fullscreen = value;
    }
});

/**
 * set and draw background
 *
 * @property enabled
 * @type Boolean
 */
Object.defineProperty(Application.prototype, 'background', {
    get: function() {
        return this._background;
    },
    set: function(value) {
        if (value === this._background) {
            return;
        }
        if (this.bg) {
            this.removeChild(this.bg);
            this.bg = null;
        }
        if (value instanceof Array) {
            this.bg = new PIXI.Sprite(this._createGradientRect(256, 256, value));
            this.bg.width = this._width;
            this.bg.height = this._height;
            this.addChildAt(this.bg, 0);
        } else {
            this._renderer.backgroundColor = value;
        }
        this._background = value;
    }
});
<commit_msg>Application documentation<commit_after>var Control = require('../core/Control');

/**
 * entry point for your application, makes some assumptions, (e.g. that you
 * always want fullscreen) and shortcuts some fancy stuff like a gradient
 * background.
 *
 * @class Application
 * @extends PIXI_UI.Control
 * @memberof PIXI_UI
 * @constructor
 * @param background {Number | Array} a background color or a list of colors
 *  that will be used as vertical gradient
 * @param fullscreen {Boolean}
 * @param renderer {WebGLRenderer|CanvasRenderer}
 * @param stage {Stage}
 */
function Application(background, fullscreen, renderer, stage) {
    if (!stage || !renderer) {
        stage = new PIXI.Container();
        var width = 800;
        var height = 600;
        if (fullscreen) {
            width = window.innerWidth;
            height = window.innerHeight;
        }
        renderer = PIXI.autoDetectRenderer(
            width, height, {backgroundColor : 0xffffff});
        document.body.appendChild(renderer.view);
    }
    /* jshint ignore:start */
    this._stage = stage;
    this._renderer = renderer;
    /* jshint ignore:end */
    this._width = renderer.width;
    this._height = renderer.height;

    Control.call(this);
    stage.addChild(this);
    this.animate();

    this.background = background;
    this.fullscreen = fullscreen;
}

Application.prototype = Object.create( Control.prototype );
Application.prototype.constructor = Application;
module.exports = Application;

/**
 * call requestAnimationFrame to render the application at max. FPS
 *
 * @method animate
 */
/* jshint ignore:start */
Application.prototype.animate = function() {
    var renderer = this._renderer;
    var stage = this._stage;
    var animate = function() {
        renderer.render(stage);
        requestAnimationFrame(animate);
    };
    requestAnimationFrame(animate);
};
/* jshint ignore:end */

/**
 * creates a gradient rect that can be used as background
 *
 * @method _createGradientRect
 * @private
 */
Application.prototype._createGradientRect = function(width, height, gradient) {
    var bgCanvas = document.createElement('canvas');
    bgCanvas.width = width;
    bgCanvas.height = height;
    var ctx = bgCanvas.getContext('2d');
    var linearGradient = ctx.createLinearGradient(0,0,0,height);
    for (var i = 0; i < gradient.length; i++) {
        linearGradient.addColorStop(i, gradient[i]);
    }
    ctx.fillStyle = linearGradient;
    ctx.fillRect(0,0,width,height);
    return PIXI.Texture.fromCanvas(bgCanvas);
};

/**
 * called when the browser window / the application is resized
 *
 * @method onresize
 */
Application.prototype.onresize = function() {
    this._width = window.innerWidth;
    this._height = window.innerHeight;
    this._renderer.resize(this._width, this._height);
    if (this.bg) {
        this.bg.width = this._width;
        this.bg.height = this._height;
    }
    for (var i = 0; i < this.children.length; i++) {
        var child = this.children[i];
        if (child.onresize) {
            child.onresize(this._width, this._height);
        }
    }
};

/**
 * set fullscreen and resize to screen size
 *
 * @property enabled
 * @type Boolean
 */
Object.defineProperty(Application.prototype, 'fullscreen', {
    get: function() {
        return this._fullscreen;
    },
    set: function(value) {
        if (this._fullscreen && !value) {
            window.removeEventListener('resize');
        } else if (!this._fullscreen && value) {
            window.addEventListener('resize', this.onresize.bind(this));
        }
        this._fullscreen = value;
    }
});

/**
 * set and draw background
 *
 * @property enabled
 * @type Boolean
 */
Object.defineProperty(Application.prototype, 'background', {
    get: function() {
        return this._background;
    },
    set: function(value) {
        if (value === this._background) {
            return;
        }
        if (this.bg) {
            this.removeChild(this.bg);
            this.bg = null;
        }
        if (value instanceof Array) {
            this.bg = new PIXI.Sprite(this._createGradientRect(256, 256, value));
            this.bg.width = this._width;
            this.bg.height = this._height;
            this.addChildAt(this.bg, 0);
        } else {
            this._renderer.backgroundColor = value;
        }
        this._background = value;
    }
});
<|endoftext|>


<commit_before>'use strict';

var qs = require('qs');

var decodeFormEl = document.querySelectorAll('.decode-form')[0];
var encodedInputEl = document.querySelectorAll('.encoded')[0];
var outputEl = document.querySelectorAll('.output')[0];
var decodedEl = document.querySelectorAll('.decoded')[0];
var decodedParamsEl = document.querySelectorAll('.decoded-params')[0];
var hadSelected = false;

decodeFormEl.addEventListener('submit', function(e) {
  e.preventDefault();

  decode();
});

encodedInputEl.addEventListener('click', function() {
  var start = encodedInputEl.selectionStart;
  var end = encodedInputEl.selectionEnd;
  var length = encodedInputEl.textLength;

  if (start === 0 && end === length) {
    return;
  }

  if (end > start) {
    // assume making a selection intentionally
    hadSelected = true;
    return;
  }

  if (hadSelected) {
    hadSelected = false;
    return;
  }

  encodedInputEl.focus();
  encodedInputEl.select();
});

encodedInputEl.addEventListener('blur', function() {
  hadSelected = false;
});

encodedInputEl.addEventListener('keydown', function(e) {
  if (e.keyCode == 13 && e.metaKey) {
    decode();
  }
});

function decode() {
  var encodedInput = encodedInputEl.value || '';
  var decoded = decodeURIComponent(encodedInput);
  var querystring = encodedInput.split('?')[1];

  outputEl.classList.add('with-results');
  decodedEl.innerHTML = decoded;

  if (querystring) {
    var decodedParams = qs.parse(querystring);
    var paramsFragment = document.createDocumentFragment();
    var sortedKeys = Object.keys(decodedParams).sort();

    sortedKeys.forEach(function(key) {
      var value = decodedParams[key];
      var termLineEl = buildTermLineEl();

      termLineEl.appendChild(termEl(key));
      termLineEl.appendChild(definitionEl(value));

      paramsFragment.appendChild(termLineEl);
    });

    decodedParamsEl.innerHTML = '';
    decodedParamsEl.appendChild(paramsFragment);
  }
}

function buildTermLineEl() {
  var el = document.createElement('div');
  el.className = 'decoded-line';

  return el;
}

function termEl(key) {
  var el = document.createElement('span');
  el.className = 'decoded-key';
  el.innerHTML = key;

  return el;
}

function definitionEl(value) {
  var el = document.createElement('span');
  el.className = 'decoded-value';
  el.innerHTML = value;

  return el;
}
<commit_msg>try fix mobile chrome<commit_after>'use strict';

var qs = require('qs');

var decodeFormEl = document.querySelectorAll('.decode-form')[0];
var encodedInputEl = document.querySelectorAll('.encoded')[0];
var outputEl = document.querySelectorAll('.output')[0];
var decodedEl = document.querySelectorAll('.decoded')[0];
var decodedParamsEl = document.querySelectorAll('.decoded-params')[0];
var hadSelected = false;

decodeFormEl.addEventListener('submit', function(e) {
  e.preventDefault();

  decode();
});

if (!isMobileDevice()) {
  encodedInputEl.addEventListener('click', function() {
    var start = encodedInputEl.selectionStart;
    var end = encodedInputEl.selectionEnd;
    var length = encodedInputEl.textLength;

    if (start === 0 && end === length) {
      return;
    }

    if (end > start) {
      // assume making a selection intentionally
      hadSelected = true;
      return;
    }

    if (hadSelected) {
      hadSelected = false;
      return;
    }

    encodedInputEl.focus();
    encodedInputEl.select();
  });

  encodedInputEl.addEventListener('blur', function() {
    hadSelected = false;
  });

  encodedInputEl.addEventListener('keydown', function(e) {
    if (e.keyCode == 13 && e.metaKey) {
      decode();
    }
  });
}

function decode() {
  var encodedInput = encodedInputEl.value || '';
  var decoded = decodeURIComponent(encodedInput);
  var querystring = encodedInput.split('?')[1];

  outputEl.classList.add('with-results');
  decodedEl.innerHTML = decoded;

  if (querystring) {
    var decodedParams = qs.parse(querystring);
    var paramsFragment = document.createDocumentFragment();
    var sortedKeys = Object.keys(decodedParams).sort();

    sortedKeys.forEach(function(key) {
      var value = decodedParams[key];
      var termLineEl = buildTermLineEl();

      termLineEl.appendChild(termEl(key));
      termLineEl.appendChild(definitionEl(value));

      paramsFragment.appendChild(termLineEl);
    });

    decodedParamsEl.innerHTML = '';
    decodedParamsEl.appendChild(paramsFragment);
  }
}

function buildTermLineEl() {
  var el = document.createElement('div');
  el.className = 'decoded-line';

  return el;
}

function termEl(key) {
  var el = document.createElement('span');
  el.className = 'decoded-key';
  el.innerHTML = key;

  return el;
}

function definitionEl(value) {
  var el = document.createElement('span');
  el.className = 'decoded-value';
  el.innerHTML = value;

  return el;
}

function isMobileDevice() {
    return (typeof window.orientation !== 'undefined') || (navigator.userAgent.indexOf('IEMobile') !== -1);
}
<|endoftext|>