<commit_before>import * as data from 'data';
import * as requester_JSON from 'json-requester';

const USERNAME_LOCAL_STORAGE_KEY = 'signed-in-user-username',
    AUTH_KEY_LOCAL_STORAGE_KEY = 'signed-in-user-auth-key',
    MAX_TICKET_PER_PAGE = 5,
    NUMBER_PER_PAGE_HEADER = 'number-per-page';

const clearLocalStorage = () => {
    localStorage.removeItem(USERNAME_LOCAL_STORAGE_KEY);
    localStorage.removeItem(AUTH_KEY_LOCAL_STORAGE_KEY);
};

describe('Data Layer Tests', () => {
    beforeEach(clearLocalStorage);
    afterEach(clearLocalStorage);
    describe('User Tests', () => {
        describe('isLoggedIn Tests', () => {
            it('Expect isLoggedIn() to return false when AUTH_KEY_LOCAL_STORAGE_KEY is not stored on localhost',
                () => {
                    expect(data.isLoggedIn()).to.be.false;
                });
            it('Expect isLoggedIn() to return true when AUTH_KEY_LOCAL_STORAGE_KEY is stored on localhost',
                () => {
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, "valid auth key");
                    expect(data.isLoggedIn()).to.be.true;
                });
        });

        describe('getLoggedInUser Tests', () => {

            it('Expect getLoggedInUser() to return unknown when non user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(false);
                    expect(data.getLoggedInUser()).to.be.equal('unknown');
                    //  isLoggedInStub.restore();
                });
            it('Expect getLoggedInUser() to return the username when user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(true);
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                    localStorage.setItem(USERNAME_LOCAL_STORAGE_KEY, 'validuser');

                    expect(data.getLoggedInUser()).to.be.equal('validuser');
                    //  isLoggedInStub.restore();
                });
        });
    });
    describe('Tickets tests', () => {
        describe('getTicket tests', () => {
            it('Expect getTicket to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request to api/ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticket');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers.ticket).to.be.equal('1');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsCount tests', () => {
            it('Expect getTicketsCount to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to make get request to api/ticketsCount', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticketsCount');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return totalTicketsLength in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.result).to.be.equal(response.totalTicketsLength);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return maxTicketsPerPage in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.maxTicketsPerPage).to.be.equal(MAX_TICKET_PER_PAGE);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsRange tests', () => {
            it('Expect getTicketsRange to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request to api/tickets', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/tickets');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers number-per-page', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicketsRange({});
                expect(jsonRequesterGetStub.args[0][1].headers[NUMBER_PER_PAGE_HEADER]).to.be.equal(MAX_TICKET_PER_PAGE);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    page: 1,
                    engineer: 1
                };
                data.getTicketsRange(queryParams);
                for (const key in queryParams) {
                    expect(jsonRequesterGetStub.args[0][1].headers[key]).to.be.equal(queryParams[key]);
                };
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers startDate when date is passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    date: 1
                };
                data.getTicketsRange(queryParams);
                    expect(jsonRequesterGetStub.args[0][1].headers['startDate']).to.be.equal(queryParams['date']);
                jsonRequesterGetStub.restore();
            });
        });
    });
    describe('Utils Tests', () => {
        describe('getPopoverValue Tests', () => {
            it('Expect getPopoverValue to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request to api/popover', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/popover');
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request with headers inputValue', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('48');
                expect(jsonRequesterGetStub.args[0][1].headers.inputValue).to.be.equal('48');
                jsonRequesterGetStub.restore();
            });
        });
        describe('splitQueryParameters Tests', () => {
            it('Expect splitQueryParameters to return empty object when no parameters are passed', () => {
                expect(data.splitQueryParameters()).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return empty object when empty string is passed', () => {
                expect(data.splitQueryParameters("")).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return splited parameters in object when valid query string is passed', () => {
                const expected = {
                    page: '1',
                    engineer: '1'
                };
                expect(data.splitQueryParameters("page=1&engineer=1")).to.be.deep.equal(expected);
            });
        });
    });
});

mocha.run();
<commit_msg>add updateTicket tests<commit_after>import * as data from 'data';
import * as requester_JSON from 'json-requester';

const USERNAME_LOCAL_STORAGE_KEY = 'signed-in-user-username',
    AUTH_KEY_LOCAL_STORAGE_KEY = 'signed-in-user-auth-key',
    MAX_TICKET_PER_PAGE = 5,
    NUMBER_PER_PAGE_HEADER = 'number-per-page';

const clearLocalStorage = () => {
    localStorage.removeItem(USERNAME_LOCAL_STORAGE_KEY);
    localStorage.removeItem(AUTH_KEY_LOCAL_STORAGE_KEY);
};

describe('Data Layer Tests', () => {
    beforeEach(clearLocalStorage);
    afterEach(clearLocalStorage);
    describe('User Tests', () => {
        describe('isLoggedIn Tests', () => {
            it('Expect isLoggedIn() to return false when AUTH_KEY_LOCAL_STORAGE_KEY is not stored on localhost',
                () => {
                    expect(data.isLoggedIn()).to.be.false;
                });
            it('Expect isLoggedIn() to return true when AUTH_KEY_LOCAL_STORAGE_KEY is stored on localhost',
                () => {
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, "valid auth key");
                    expect(data.isLoggedIn()).to.be.true;
                });
        });

        describe('getLoggedInUser Tests', () => {

            it('Expect getLoggedInUser() to return unknown when non user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(false);
                    expect(data.getLoggedInUser()).to.be.equal('unknown');
                    //  isLoggedInStub.restore();
                });
            it('Expect getLoggedInUser() to return the username when user is logged in',
                () => {
                    //  const isLoggedInStub = sinon.stub(data, 'isLoggedIn').returns(true);
                    localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                    localStorage.setItem(USERNAME_LOCAL_STORAGE_KEY, 'validuser');

                    expect(data.getLoggedInUser()).to.be.equal('validuser');
                    //  isLoggedInStub.restore();
                });
        });
    });
    describe('Tickets tests', () => {
        describe('getTicket tests', () => {
            it('Expect getTicket to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request to api/ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticket');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers.ticket).to.be.equal('1');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicket to make get request with headers ticket', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.getTicket('1');
                expect(jsonRequesterGetStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsCount tests', () => {
            it('Expect getTicketsCount to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to make get request to api/ticketsCount', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/ticketsCount');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return totalTicketsLength in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.result).to.be.equal(response.totalTicketsLength);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsCount to return maxTicketsPerPage in result property', (done) => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const response = {
                    totalTicketsLength: 10
                };
                jsonRequesterGetStub.returns(Promise.resolve(response));
                data.getTicketsCount().then((res) => {
                        expect(res.maxTicketsPerPage).to.be.equal(MAX_TICKET_PER_PAGE);
                    })
                    .then(done, done);
                jsonRequesterGetStub.restore();
            });
        });
        describe('getTicketsRange tests', () => {
            it('Expect getTicketsRange to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request to api/tickets', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                jsonRequesterGetStub.returns(Promise.resolve());
                data.getTicketsRange();
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/tickets');
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers number-per-page', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getTicketsRange({});
                expect(jsonRequesterGetStub.args[0][1].headers[NUMBER_PER_PAGE_HEADER]).to.be.equal(MAX_TICKET_PER_PAGE);
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    page: 1,
                    engineer: 1
                };
                data.getTicketsRange(queryParams);
                for (const key in queryParams) {
                    expect(jsonRequesterGetStub.args[0][1].headers[key]).to.be.equal(queryParams[key]);
                };
                jsonRequesterGetStub.restore();
            });
            it('Expect getTicketsRange to make get request with headers startDate when date is passed as parameter', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                const queryParams = {
                    date: 1
                };
                data.getTicketsRange(queryParams);
                expect(jsonRequesterGetStub.args[0][1].headers['startDate']).to.be.equal(queryParams['date']);
                jsonRequesterGetStub.restore();
            });
        });
        describe('updateTicket Tests', () => {
            it('Expect updateTicket to call json requester put', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledOnce;
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request to api/updateTicket', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                data.updateTicket();
                expect(jsonRequesterPUTStub).to.have.been.calledWith('api/updateTicket');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with headers x-auth-key', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                data.updateTicket();
                expect(jsonRequesterPUTStub.args[0][1].headers['x-auth-key']).to.be.equal('valid-auth-key');
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to make put request with data passed as parameter', () => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                jsonRequesterPUTStub.returns(Promise.resolve());
                localStorage.setItem(AUTH_KEY_LOCAL_STORAGE_KEY, 'valid-auth-key');
                const ticket = {
                    id: 10
                };
                data.updateTicket(ticket);
                expect(jsonRequesterPUTStub.args[0][1].data).to.be.equal(ticket);
                jsonRequesterPUTStub.restore();
            });
            it('Expect updateTicket to return ticket in result property', (done) => {
                const jsonRequesterPUTStub = sinon.stub(requester_JSON, 'put');
                const response = {
                    result: "put-result"
                };
                jsonRequesterPUTStub.returns(Promise.resolve(response));
                data.updateTicket().then((res) => {
                        expect(res.result).to.be.equal(response.result);
                    })
                    .then(done, done);
                jsonRequesterPUTStub.restore();
            });
        });
    });
    describe('Utils Tests', () => {
        describe('getPopoverValue Tests', () => {
            it('Expect getPopoverValue to call json requester get', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledOnce;
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request to api/popover', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('1');
                expect(jsonRequesterGetStub).to.have.been.calledWith('api/popover');
                jsonRequesterGetStub.restore();
            });
            it('Expect getPopoverValue to make get request with headers inputValue', () => {
                const jsonRequesterGetStub = sinon.stub(requester_JSON, 'get');
                data.getPopoverValue('48');
                expect(jsonRequesterGetStub.args[0][1].headers.inputValue).to.be.equal('48');
                jsonRequesterGetStub.restore();
            });
        });
        describe('splitQueryParameters Tests', () => {
            it('Expect splitQueryParameters to return empty object when no parameters are passed', () => {
                expect(data.splitQueryParameters()).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return empty object when empty string is passed', () => {
                expect(data.splitQueryParameters("")).to.be.deep.equal({});
            });
            it('Expect splitQueryParameters to return splited parameters in object when valid query string is passed', () => {
                const expected = {
                    page: '1',
                    engineer: '1'
                };
                expect(data.splitQueryParameters("page=1&engineer=1")).to.be.deep.equal(expected);
            });
        });
    });
});

mocha.run();
<|endoftext|>


<commit_before>/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var fs = require('fs');
var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();

app.set('port', (process.env.PORT || 3000));

app.use('/', express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.get('/api/comments', function(req, res) {
  fs.readFile('comments.json', function(err, data) {
    res.setHeader('Cache-Control', 'no-cache');
    res.json(JSON.parse(data));
  });
});

app.post('/api/comments', function(req, res) {
  fs.readFile('comments.json', function(err, data) {
    var comments = JSON.parse(data);
    comments.push(req.body);
    fs.writeFile('comments.json', JSON.stringify(comments, null, 4), function(err) {
      res.setHeader('Cache-Control', 'no-cache');
      res.json(comments);
    });
  });
});

app.listen(app.get('port'), function() {
  console.log('Server started: http://localhost:' + app.get('port') + '/');
});
<commit_msg>JS: Make comments file reference relative to server file<commit_after>/**
 * This file provided by Facebook is for non-commercial testing and evaluation
 * purposes only. Facebook reserves all rights not expressly granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

var fs = require('fs');
var path = require('path');
var express = require('express');
var bodyParser = require('body-parser');
var app = express();

var COMMENTS_FILE = path.join(__dirname, 'comments.json');

app.set('port', (process.env.PORT || 3000));

app.use('/', express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.get('/api/comments', function(req, res) {
  fs.readFile(COMMENTS_FILE, function(err, data) {
    res.setHeader('Cache-Control', 'no-cache');
    res.json(JSON.parse(data));
  });
});

app.post('/api/comments', function(req, res) {
  fs.readFile(COMMENTS_FILE, function(err, data) {
    var comments = JSON.parse(data);
    comments.push(req.body);
    fs.writeFile(COMMENTS_FILE, JSON.stringify(comments, null, 4), function(err) {
      res.setHeader('Cache-Control', 'no-cache');
      res.json(comments);
    });
  });
});

app.listen(app.get('port'), function() {
  console.log('Server started: http://localhost:' + app.get('port') + '/');
});
<|endoftext|>


<commit_before>
'use strict'
// Template version: 1.1.3
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')
var buildMode = process.env.NODE_ENV === 'production' ? 'Release' : 'Debug'

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../../../bin/' + buildMode + '/Client/index.html'),
    assetsRoot: path.resolve(__dirname, '../../../bin/' + buildMode + '/Client/'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: process.env.PORT || 8080,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}
<commit_msg>deployment fixed<commit_after>
'use strict'
// Template version: 1.1.3
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')
var buildMode = process.env.NODE_ENV === 'production' ? 'pCI' : 'Debug'

module.exports = {
  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../../../bin/' + buildMode + '/Client/index.html'),
    assetsRoot: path.resolve(__dirname, '../../../bin/' + buildMode + '/Client/'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: process.env.PORT || 8080,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}
<|endoftext|>


<commit_before>import RasterToGcode from './lw.raster2gcode/raster-to-gcode';
import queue from 'queue'

export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages, showAlert, done, progress, jobIndex, QE_chunk, workers) {

    let ok = true;

    if (!(op.laserDiameter > 0)) {
        showAlert("LaserDiameter should be greater than 0", "danger");
        ok = false;
    }

    if (!(op.cutRate > 0)) {
        showAlert("CutRate should be greater than 0", "danger");
        ok = false;
    }

    if (settings.machineZEnabled) {
        if (op.startHeight === "" || isNaN(op.startHeight)) {
            showAlert("Start Height must be a valid number", "danger");
            ok = false;
        }
    }

    if (op.useA && !op.aAxisDiameter){
        showAlert("Axis Diameter must be > 0", "danger");
        ok = false;
    }

    if (!ok) {
        done(false);
        return [];
    }

    let gcode=[];

    let QE = new queue();
        QE.concurrency = 1;
        QE.timeout = 3600 * 1000
        QE.chunk = 100 / docsWithImages.length

    // POSTPROCESS GCODE;
    const postProcessing = (gc) => {
        let g = '';
        let raster = '';
        for (let line of gc) {
            if (op.useA) {
                line=line.replace(/Y(\s*[0-9\.]{1,})/gi,"A$1");
            }
            if (line[0] !== 'S' && line.substring(0, 4) !== 'G0 F') {
                raster += line + '\r\n';
            } else {
                raster += '; stripped: ' + line + '\r\n';
            }
        }

        raster += '\r\n\r\n';

        if (op.hookOperationStart.length) g+=op.hookOperationStart;

        for (let pass = 0; pass < op.passes; ++pass) {
            g += '\n\n; Pass ' + pass + '\r\n';

            if (op.hookPassStart.length) g+=op.hookPassStart;

            if (op.useBlower) {
                if (settings.machineBlowerGcodeOn) {
                    g += `\r\n` + settings.machineBlowerGcodeOn + '; Enable Air assist\r\n';
                }
            }

            if (settings.machineZEnabled) {
                let zHeight = Number(op.startHeight) + settings.machineZToolOffset - (op.passDepth * pass);
                g += `\r\n; Pass Z Height ${zHeight}mm (Offset: ${settings.machineZToolOffset}mm)\r\n`;
                g += 'G0 Z' + zHeight.toFixed(settings.decimal || 3) + '\r\n';
            }

            if (settings.gcodeToolOn && settings.gcodeToolOn.length)
                g+=`${settings.gcodeToolOn} \r\n`;

            g += raster;

            if (settings.gcodeToolOff && settings.gcodeToolOff.length)
                g+=`${settings.gcodeToolOff} \r\n`;

            if (op.useBlower) {
                if (settings.machineBlowerGcodeOff) {
                    g += `\r\n` + settings.machineBlowerGcodeOff + '; Disable Air assist\r\n';
                }
            }

            if (op.hookPassEnd.length) g+=op.hookPassEnd;
        }

        if (op.hookOperationEnd.length) g+=op.hookOperationEnd;

        return g;
    }

    // FRAGMENT PROGRESS
    const percentProcessing = (percent) => {
        let p = parseInt((jobIndex * QE_chunk) + (percent * (QE_chunk / 100)))
        progress(p);
    }

    for (let index = 0; index < docsWithImages.length; index++) {

        QE.push((cb) => {

            const doc = Object.assign({},docsWithImages[index])
            let feedRate = op.cutRate * (settings.toolFeedUnits === 'mm/s' ? 60 : 1);

            if (op.useA && op.aAxisDiameter){
                doc.scale[1]=Number((doc.scale[1] * 360 / op.aAxisDiameter / Math.PI).toFixed(3))

                if (op.diagonal) feedRate = feedRate/Math.SQRT2
            }

            let params = {
                ppi: { x: doc.dpi / doc.scale[0], y: doc.dpi / doc.scale[1] },
                toolDiameter: op.laserDiameter,
                beamRange: { min: 0, max: settings.gcodeSMaxValue },
                beamPower: op.laserPowerRange, //Go go power rangeR!
                rapidRate: false,
                feedRate,
                offsets: { X: doc.translate[0], Y: doc.translate[1] },
                trimLine: op.trimLine,
                joinPixel: op.joinPixel,
                burnWhite: op.burnWhite,
                verboseG: op.verboseGcode,
                diagonal: op.diagonal,
                overscan: op.overScan,
                nonBlocking: false,
                milling: false,
                filters: {
                    smoothing: op.smoothing,
                    brightness: op.brightness,
                    contrast: op.contrast,
                    gamma: op.gamma,
                    grayscale: op.grayscale,
                    shadesOfGray: op.shadesOfGray,
                    invertColor: op.invertColor,
                    dithering: op.dithering
                }
            }
            let r2g = new RasterToGcode(params)
            r2g.load(doc.image).then((rtg) => {
                let properties = {
                    cellSize: rtg.cellSize,
                    scaleRatio: rtg.scaleRatio,
                    filters: rtg.filters,
                    size: rtg.size,
                    pixels: rtg.pixels
                }

                let rasterWorker = require('worker-loader!./workers/cam-raster.js')
                let r2g = new rasterWorker();
                r2g.onmessage = function (event) {
                    if (event.data.event === 'onDone') {
                        gcode.push(postProcessing(event.data.gcode)); cb();
                    } else if (event.data.event === 'onProgress') {
                        percentProcessing((index * QE.chunk) + (event.data.percent * QE.chunk / 100))
                    }
                };

                workers.push(r2g)
                r2g.postMessage({ cmd: 'start', settings: params, properties });

            })

        })

    }

    QE.start((err)=>{
        done(gcode.join("\r\n"));
    })

}<commit_msg>#147 - WIP Raster transforms (offset bug)<commit_after>import RasterToGcode from './lw.raster2gcode/raster-to-gcode';
import queue from 'queue'

const getImageBounds=(t,w,h)=>{
    let tx = (x, y) => t[0] * x + t[2] * y;
    let ty = (x, y) => t[1] * x + t[3] * y;
    return {
        x1: Math.min(tx(0, 0), tx(w, 0), tx(w, h), tx(0, h)),
        y1: Math.min(ty(0, 0), ty(w, 0), ty(w, h), ty(0, h)),
        x2: Math.max(tx(0, 0), tx(w, 0), tx(w, h), tx(0, h)),
        y2: Math.max(ty(0, 0), ty(w, 0), ty(w, h), ty(0, h)),
    };
}

const promisedImage = (path) => {
    return new Promise(resolve => {
        let img = new Image();
        img.onload = () => { resolve(img) }
        img.src = path;
    })
}

export function getLaserRasterGcodeFromOp(settings, opIndex, op, docsWithImages, showAlert, done, progress, jobIndex, QE_chunk, workers) {

    let ok = true;

    if (!(op.laserDiameter > 0)) {
        showAlert("LaserDiameter should be greater than 0", "danger");
        ok = false;
    }

    if (!(op.cutRate > 0)) {
        showAlert("CutRate should be greater than 0", "danger");
        ok = false;
    }

    if (settings.machineZEnabled) {
        if (op.startHeight === "" || isNaN(op.startHeight)) {
            showAlert("Start Height must be a valid number", "danger");
            ok = false;
        }
    }

    if (op.useA && !op.aAxisDiameter) {
        showAlert("Axis Diameter must be > 0", "danger");
        ok = false;
    }

    if (!ok) {
        done(false);
        return [];
    }

    let gcode = [];

    let QE = new queue();
    QE.concurrency = 1;
    QE.timeout = 3600 * 1000
    QE.chunk = 100 / docsWithImages.length

    // POSTPROCESS GCODE;
    const postProcessing = (gc) => {
        let g = '';
        let raster = '';
        for (let line of gc) {
            if (op.useA) {
                line = line.replace(/Y(\s*[0-9\.]{1,})/gi, "A$1");
            }
            if (line[0] !== 'S' && line.substring(0, 4) !== 'G0 F') {
                raster += line + '\r\n';
            } else {
                raster += '; stripped: ' + line + '\r\n';
            }
        }

        raster += '\r\n\r\n';

        if (op.hookOperationStart.length) g += op.hookOperationStart;

        for (let pass = 0; pass < op.passes; ++pass) {
            g += '\n\n; Pass ' + pass + '\r\n';

            if (op.hookPassStart.length) g += op.hookPassStart;

            if (op.useBlower) {
                if (settings.machineBlowerGcodeOn) {
                    g += `\r\n` + settings.machineBlowerGcodeOn + '; Enable Air assist\r\n';
                }
            }

            if (settings.machineZEnabled) {
                let zHeight = Number(op.startHeight) + settings.machineZToolOffset - (op.passDepth * pass);
                g += `\r\n; Pass Z Height ${zHeight}mm (Offset: ${settings.machineZToolOffset}mm)\r\n`;
                g += 'G0 Z' + zHeight.toFixed(settings.decimal || 3) + '\r\n';
            }

            if (settings.gcodeToolOn && settings.gcodeToolOn.length)
                g += `${settings.gcodeToolOn} \r\n`;

            g += raster;

            if (settings.gcodeToolOff && settings.gcodeToolOff.length)
                g += `${settings.gcodeToolOff} \r\n`;

            if (op.useBlower) {
                if (settings.machineBlowerGcodeOff) {
                    g += `\r\n` + settings.machineBlowerGcodeOff + '; Disable Air assist\r\n';
                }
            }

            if (op.hookPassEnd.length) g += op.hookPassEnd;
        }

        if (op.hookOperationEnd.length) g += op.hookOperationEnd;

        return g;
    }

    // FRAGMENT PROGRESS
    const percentProcessing = (percent) => {
        let p = parseInt((jobIndex * QE_chunk) + (percent * (QE_chunk / 100)))
        progress(p);
    }

    for (let index = 0; index < docsWithImages.length; index++) {

        QE.push((cb) => {

            const doc = Object.assign({}, docsWithImages[index])
            let feedRate = op.cutRate * (settings.toolFeedUnits === 'mm/s' ? 60 : 1);

            /*
            if (op.useA && op.aAxisDiameter){
                doc.scale[1]=Number((doc.scale[1] * 360 / op.aAxisDiameter / Math.PI).toFixed(3))

                if (op.diagonal) feedRate = feedRate/Math.SQRT2
            }
            */

            promisedImage(doc.dataURL).then((img) => {

                let scale = doc.originalPixels[0]/doc.originalSize[0];
                let docBounds = getImageBounds(doc.transform2d, img.width, img.height);
                let imgBounds= getImageBounds(doc.transform2d, img.width*scale, img.height*scale);

                let w = imgBounds.x2-imgBounds.x1
                let h = imgBounds.y2-imgBounds.y1

                let canvas = document.createElement('canvas')
                    canvas.width = w
                    canvas.height = h

                let ctx = canvas.getContext('2d')
                    /* Centering Transform */
                    ctx.translate(w/2,h/2)
                    /* WCS correction */
                    ctx.transform( -doc.transform2d[0]*scale, doc.transform2d[1]*scale,
                                    doc.transform2d[2]*scale, -doc.transform2d[3]*scale,
                                    0, 0)
                    ctx.rotate((Math.PI / 180) * 180)
                    /* /WCS correction */
                    /* De-Centering Transform */
                    ctx.translate(-w/2,-h/2)
                    /* Centering Image*/
                    ctx.translate((w-img.width)/2,(h-img.height)/2)
                    ctx.drawImage(img, 0, 0)
                    ctx.save();

                let params = {
                    ppi: { x: settings.dpiBitmap, y: settings.dpiBitmap },
                    toolDiameter: op.laserDiameter,
                    beamRange: { min: 0, max: settings.gcodeSMaxValue },
                    beamPower: op.laserPowerRange, //Go go power rangeR!
                    rapidRate: false,
                    feedRate,
                    offsets: { X: doc.transform2d[4], Y: doc.transform2d[5] },
                    trimLine: op.trimLine,
                    joinPixel: op.joinPixel,
                    burnWhite: op.burnWhite,
                    verboseG: op.verboseGcode,
                    diagonal: op.diagonal,
                    overscan: op.overScan,
                    nonBlocking: false,
                    milling: false,
                    filters: {
                        smoothing: op.smoothing,
                        brightness: op.brightness,
                        contrast: op.contrast,
                        gamma: op.gamma,
                        grayscale: op.grayscale,
                        shadesOfGray: op.shadesOfGray,
                        invertColor: op.invertColor,
                        dithering: op.dithering
                    }
                }
                let r2g = new RasterToGcode(params)
                    r2g.load(canvas.toDataURL()).then((rtg) => {

                        console.log(rtg)

                        let properties = {
                            cellSize: rtg.cellSize,
                            scaleRatio: rtg.scaleRatio,
                            filters: rtg.filters,
                            size: rtg.size,
                            pixels: rtg.pixels
                        }

                        let rasterWorker = require('worker-loader!./workers/cam-raster.js')
                        let r2g = new rasterWorker();
                        r2g.onmessage = function (event) {
                            if (event.data.event === 'onDone') {
                                gcode.push(postProcessing(event.data.gcode)); cb();
                            } else if (event.data.event === 'onProgress') {
                                percentProcessing((index * QE.chunk) + (event.data.percent * QE.chunk / 100))
                            }
                        };

                        workers.push(r2g)
                        r2g.postMessage({ cmd: 'start', settings: params, properties });

                    })
            })

        })

    }

    QE.start((err) => {
        done(gcode.join("\r\n"));
    })

}<|endoftext|>


<commit_before>/* global window, document, location */

(() => {

	const SCRIPT_PATHS = [
		["configuration.js"],
		["bgpage/misc/netfilters.js", "bgpage/business.js", "bgpage/network.js", "bgpage/tabs.js", "bgpage/ui.js", "bgpage/welcome.js"],
		["content/misc/minhash.js", "content/misc/tokenizer.js", "content/bgpage.js", "content/business.js", "content/url.js", "content/webpage.js"]
	];
	const SELECTED_CLASS = "selected";
	const TEMPLATE_ID = "template-test-container";
	const TEMPLATE_FILE_PATH = "/tests/ui/template.html";
	const SCRIPTS_PATH = "/scripts";
	const TESTS_PATH = "/tests/scripts";
	const STYLESHEET_PATH = "/tests/vendor/qunit.css";

	let selectedTab;

	SCRIPT_PATHS.forEach(group => {
		const groupContainer = document.createElement("div");
		group.forEach(scriptPath => appendTest(groupContainer, scriptPath));
		document.body.querySelector("ul").appendChild(groupContainer);
	});
	refresh();
	window.onhashchange = refresh;

	function refresh() {
		const link = document.querySelector(`a[href=${JSON.stringify(location.hash)}]`);
		if (link) {
			const container = link.parentElement;
			if (selectedTab) {
				selectedTab.classList.remove(SELECTED_CLASS);
			}
			container.classList.add(SELECTED_CLASS);
			selectedTab = container;
		} else {
			location.hash = document.querySelector("ul li a").hash;
		}
	}

	function appendTest(groupContainer, scriptPath) {
		const template = document.getElementById(TEMPLATE_ID).cloneNode(true);
		const link = template.querySelector("a");
		template.removeAttribute("id");
		link.textContent = scriptPath;
		link.href = `#${scriptPath}`;
		appendIframe(template, scriptPath);
		groupContainer.appendChild(template);
	}

	function appendIframe(parent, scriptPath) {
		const iframe = document.createElement("iframe");
		iframe.src = TEMPLATE_FILE_PATH;
		parent.appendChild(iframe);
		iframe.onload = iframeOnload(iframe, scriptPath);
	}

	function iframeOnload(iframe, scriptPath) {
		return () => {
			const doc = iframe.contentDocument;
			doc.title = scriptPath;
			appendStylesheet(doc.head, STYLESHEET_PATH);
			const body = doc.body;
			appendScript(body, `${SCRIPTS_PATH}/${scriptPath}`);
			appendScript(body, `${TESTS_PATH}/${scriptPath}`);
		};
	}

	function appendStylesheet(parent, path) {
		const stylesheet = document.createElement("link");
		stylesheet.rel = "stylesheet";
		stylesheet.href = path;
		parent.appendChild(stylesheet);
	}

	function appendScript(parent, path) {
		const script = document.createElement("script");
		script.async = false;
		script.src = path;
		parent.appendChild(script);
	}

})();<commit_msg>renaming<commit_after>/* global window, document, location */

(() => {

	const SCRIPT_PATHS = [
		["configuration.js"],
		["bgpage/misc/netfilters.js", "bgpage/business.js", "bgpage/network.js", "bgpage/tabs.js", "bgpage/ui.js", "bgpage/welcome.js"],
		["content/misc/minhash.js", "content/misc/tokenizer.js", "content/bgpage.js", "content/business.js", "content/url.js", "content/webpage.js"]
	];
	const SELECTED_CLASS = "selected";
	const TEMPLATE_ID = "template-test-container";
	const TEMPLATE_FILE_PATH = "/tests/ui/template.html";
	const SCRIPTS_PATH = "/scripts";
	const TESTS_PATH = "/tests/scripts";
	const STYLESHEET_PATH = "/tests/vendor/qunit.css";

	let selectedTab;

	SCRIPT_PATHS.forEach(group => {
		const groupContainer = document.createElement("div");
		group.forEach(scriptPath => appendTest(groupContainer, scriptPath));
		document.body.querySelector("ul").appendChild(groupContainer);
	});
	refresh();
	window.onhashchange = refresh;

	function refresh() {
		const link = document.querySelector(`a[href=${JSON.stringify(location.hash)}]`);
		if (link) {
			const container = link.parentElement;
			if (selectedTab) {
				selectedTab.classList.remove(SELECTED_CLASS);
			}
			container.classList.add(SELECTED_CLASS);
			selectedTab = container;
		} else {
			location.hash = document.querySelector("ul li a").hash;
		}
	}

	function appendTest(parent, scriptPath) {
		const template = document.getElementById(TEMPLATE_ID).cloneNode(true);
		const link = template.querySelector("a");
		template.removeAttribute("id");
		link.textContent = scriptPath;
		link.href = `#${scriptPath}`;
		appendIframe(template, scriptPath);
		parent.appendChild(template);
	}

	function appendIframe(parent, scriptPath) {
		const iframe = document.createElement("iframe");
		iframe.src = TEMPLATE_FILE_PATH;
		parent.appendChild(iframe);
		iframe.onload = iframeOnload(iframe, scriptPath);
	}

	function iframeOnload(iframe, scriptPath) {
		return () => {
			const doc = iframe.contentDocument;
			doc.title = scriptPath;
			appendStylesheet(doc.head, STYLESHEET_PATH);
			const body = doc.body;
			appendScript(body, `${SCRIPTS_PATH}/${scriptPath}`);
			appendScript(body, `${TESTS_PATH}/${scriptPath}`);
		};
	}

	function appendStylesheet(parent, path) {
		const stylesheet = document.createElement("link");
		stylesheet.rel = "stylesheet";
		stylesheet.href = path;
		parent.appendChild(stylesheet);
	}

	function appendScript(parent, path) {
		const script = document.createElement("script");
		script.async = false;
		script.src = path;
		parent.appendChild(script);
	}

})();<|endoftext|>


<commit_before>$(document).ready(function () {
    $(".own-home-auth").hide();
    $(".residence-auth-pop").change(function () {
        if (this.value == 'own') {
            $(".own-home-auth").show();
        }
        else if (this.value == 'rent') {
            $(".own-home-auth").hide();
        }
    });
});
<commit_msg>and else makes more sense here<commit_after>$(document).ready(function () {
    $(".own-home-auth").hide();
    $(".residence-auth-pop").change(function () {
        if (this.value == 'own') {
            $(".own-home-auth").show();
        }
        else {
            $(".own-home-auth").hide();
        }
    });
});
<|endoftext|>


<commit_before>(function() {
  // Define filter operations
  window.shared || (window.shared = {});
  var Env = window.shared.Env;

  var MixpanelUtils = window.shared.MixpanelUtils = {
    isMixpanelEnabled: function() {
      return (window.mixpanel && Env.shouldReportAnalytics);
    },
    registerUser: function(currentEducator) {
      if (!MixpanelUtils.isMixpanelEnabled()) return;

      try {
        window.mixpanel.register({
          'deployment_key': Env.deploymentKey,
          'educator_id': currentEducator.id,
          'educator_is_admin': currentEducator.admin,
          'educator_school_id': currentEducator.school_id
        });
      }
      catch (err) {
        console.error(err);
      }
    },
    track: function(key, attrs) {
      if (!MixpanelUtils.isMixpanelEnabled()) return;
      try {
        return window.mixpanel.track(key, attrs);
      }
      catch (err) {
        console.error(err);
      }
    }
  };
})();<commit_msg>Add call to mixpanel.identify<commit_after>(function() {
  // Define filter operations
  window.shared || (window.shared = {});
  var Env = window.shared.Env;
  var mixpanel = window.mixpanel;

  var MixpanelUtils = window.shared.MixpanelUtils = {
    isMixpanelEnabled: function() {
      return (mixpanel && Env.shouldReportAnalytics);
    },
    registerUser: function(currentEducator) {
      if (!MixpanelUtils.isMixpanelEnabled()) return;

      try {
        mixpanel.identify(currentEducator.id);
        mixpanel.register({
          'deployment_key': Env.deploymentKey,
          'educator_id': currentEducator.id,
          'educator_is_admin': currentEducator.admin,
          'educator_school_id': currentEducator.school_id
        });
      }
      catch (err) {
        console.error(err);
      }
    },
    track: function(key, attrs) {
      if (!MixpanelUtils.isMixpanelEnabled()) return;
      try {
        return mixpanel.track(key, attrs);
      }
      catch (err) {
        console.error(err);
      }
    }
  };
})();<|endoftext|>


<commit_before>class TrackingTags {
  constructor(provider) {
    this.provider = provider
  }

  analytics() {
    if(this.provider === "matomo") {
      return _paq;
    }
    else {
      return _gaq
    }
  }

  pageView() {
    if(this.provider === "matomo") {
      return 'trackPageView'
    } else {
      return '_trackPageview'
    }
  }

  trackEvent() {
    if(this.provider === "matomo") {
      return 'trackEvent'
    } else {
      return '_trackEvent'
    }
  }
}

function trackPageView() {
  window.trackingTags.analytics().push([window.trackingTags.pageView()]);
}

function trackAnalyticsEvents() {
  $('span.analytics-event').each(function(){
    var eventSpan = $(this)
    window.trackingTags.analytics().push([window.trackingTags.trackEvent(), eventSpan.data('category'), eventSpan.data('action'), eventSpan.data('name')]);
  })
}

function setupTracking() {
    var provider = $('meta[name="analytics-provider"]').prop('content')
    window.trackingTags = new TrackingTags(provider)
    trackPageView()
    trackAnalyticsEvents()
}

if (typeof Turbolinks !== 'undefined') {
  $(document).on('turbolinks:load', function() {
    setupTracking()
  })
} else {
  $(document).on('ready', function() {
    setupTracking()
  })
}

$(document).on('click', '#file_download', function(e) {
  var provider = $('meta[name="analytics-provider"]').prop('content')
  window.trackingTags = new TrackingTags(provider)
  window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set', 'file-set-download', $(this).data('label')]);
  window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-work', 'file-set-in-work-download', $(this).data('work-id')]);
  $(this).data('collection-ids').forEach(function (collection) {
    window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-collection', 'file-set-in-collection-download', collection]);
    window.trackingTags.analytics().push([trackingTags.trackEvent(), 'work-in-collection', 'work-in-collection-download', collection]);
  });
});<commit_msg>Don't setup event tracking or attempt any tracking if analytics provider is not on page This change fixes a bug when the page does not have an analytics provider setup.  In this scenario TrackingTags.analytics() assumes Google analytics and then errors because _gaq is undefined.  This error keeps all subsequent JS from executing.  This causes the refreshing of CSRF tokens on turbolinks:load not to run and many forms to raise InvalidAuthenticityToken.<commit_after>class TrackingTags {
  constructor(provider) {
    this.provider = provider
  }

  analytics() {
    if(this.provider === "matomo") {
      return _paq;
    }
    else {
      return _gaq;
    }
  }

  pageView() {
    if(this.provider === "matomo") {
      return 'trackPageView'
    } else {
      return '_trackPageview'
    }
  }

  trackEvent() {
    if(this.provider === "matomo") {
      return 'trackEvent'
    } else {
      return '_trackEvent'
    }
  }
}

function trackPageView() {
  window.trackingTags.analytics().push([window.trackingTags.pageView()]);
}

function trackAnalyticsEvents() {
  $('span.analytics-event').each(function(){
    var eventSpan = $(this)
    window.trackingTags.analytics().push([window.trackingTags.trackEvent(), eventSpan.data('category'), eventSpan.data('action'), eventSpan.data('name')]);
  })
}

function setupTracking() {
    var provider = $('meta[name="analytics-provider"]').prop('content')
    if (provider === undefined) {
      return;
    }
    window.trackingTags = new TrackingTags(provider)
    trackPageView()
    trackAnalyticsEvents()
}

if (typeof Turbolinks !== 'undefined') {
  $(document).on('turbolinks:load', function() {
    setupTracking()
  })
} else {
  $(document).on('ready', function() {
    setupTracking()
  })
}

$(document).on('click', '#file_download', function(e) {
  var provider = $('meta[name="analytics-provider"]').prop('content')
  if (provider === undefined) {
    return;
  }
  window.trackingTags = new TrackingTags(provider)
  window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set', 'file-set-download', $(this).data('label')]);
  window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-work', 'file-set-in-work-download', $(this).data('work-id')]);
  $(this).data('collection-ids').forEach(function (collection) {
    window.trackingTags.analytics().push([trackingTags.trackEvent(), 'file-set-in-collection', 'file-set-in-collection-download', collection]);
    window.trackingTags.analytics().push([trackingTags.trackEvent(), 'work-in-collection', 'work-in-collection-download', collection]);
  });
});
<|endoftext|>


<commit_before>/*!
  * @preserve Qwery - A Blazing Fast query selector engine
  * https://github.com/ded/qwery
  * copyright Dustin Diaz 2012
  * MIT License
  */
(function (e, t, n) { typeof module != "undefined" && module.exports ? module.exports = n() : typeof define == "function" && define.amd ? define(n) : t[e] = n() })("qwery", this, function () { function L() { this.c = {} } function D(e) { return A.g(e) || A.s(e, "(^|\\s+)" + e + "(\\s+|$)", 1) } function P(e, t) { var n = 0, r = e.length; for (; n < r; n++) t(e[n]) } function H(e) { for (var t = [], n = 0, r = e.length; n < r; ++n) $(e[n]) ? t = t.concat(e[n]) : t[t.length] = e[n]; return t } function B(e) { var t = 0, n = e.length, r = []; for (; t < n; t++) r[t] = e[t]; return r } function j(e) { while (e = e.previousSibling) if (e[u] == 1) break; return e } function F(e) { return e.match(C) } function I(e, t, n, r, i, s, a, c, h, p, d) { var v, m, g, y, b; if (this[u] !== 1) return !1; if (t && t !== "*" && this[o] && this[o].toLowerCase() !== t) return !1; if (n && (m = n.match(f)) && m[1] !== this.id) return !1; if (n && (b = n.match(l))) for (v = b.length; v--;) if (!D(b[v].slice(1)).test(this.className)) return !1; if (h && Q.pseudos[h] && !Q.pseudos[h](this, d)) return !1; if (r && !a) { y = this.attributes; for (g in y) if (Object.prototype.hasOwnProperty.call(y, g) && (y[g].name || g) == i) return this } return r && !R(s, Z(this, i) || "", a) ? !1 : this } function q(e) { return O.g(e) || O.s(e, e.replace(b, "\\$1")) } function R(e, t, n) { switch (e) { case "=": return t == n; case "^=": return t.match(M.g("^=" + n) || M.s("^=" + n, "^" + q(n), 1)); case "$=": return t.match(M.g("$=" + n) || M.s("$=" + n, q(n) + "$", 1)); case "*=": return t.match(M.g(n) || M.s(n, q(n), 1)); case "~=": return t.match(M.g("~=" + n) || M.s("~=" + n, "(?:^|\\s+)" + q(n) + "(?:\\s+|$)", 1)); case "|=": return t.match(M.g("|=" + n) || M.s("|=" + n, "^" + q(n) + "(-|$)", 1)) } return 0 } function U(e, t) { var n = [], i = [], s, a, f, l, h, p, d, v, m = t, g = _.g(e) || _.s(e, e.split(N)), y = e.match(T); if (!g.length) return n; l = (g = g.slice(0)).pop(), g.length && (f = g[g.length - 1].match(c)) && (m = K(t, f[1])); if (!m) return n; d = F(l), p = m !== t && m[u] !== 9 && y && /^[+~]$/.test(y[y.length - 1]) ? function (e) { while (m = m.nextSibling) m[u] == 1 && (d[1] ? d[1] == m[o].toLowerCase() : 1) && (e[e.length] = m); return e }([]) : m[r](d[1] || "*"); for (s = 0, a = p.length; s < a; s++) if (v = I.apply(p[s], d)) n[n.length] = v; return g.length ? (P(n, function (e) { W(e, g, y) && (i[i.length] = e) }), i) : n } function z(e, t, n) { if (X(t)) return e == t; if ($(t)) return !!~H(t).indexOf(e); var r = t.split(","), i, s; while (t = r.pop()) { i = _.g(t) || _.s(t, t.split(N)), s = t.match(T), i = i.slice(0); if (I.apply(e, F(i.pop())) && (!i.length || W(e, i, s, n))) return !0 } return !1 } function W(e, t, n, r) { function s(e, r, o) { while (o = k[n[r]](o, e)) if (X(o) && I.apply(o, F(t[r]))) { if (!r) return o; if (i = s(o, r - 1, o)) return i } } var i; return (i = s(e, t.length - 1, e)) && (!r || Y(i, r)) } function X(e, t) { return e && typeof e == "object" && (t = e[u]) && (t == 1 || t == 9) } function V(e) { var t = [], n, r; e: for (n = 0; n < e.length; ++n) { for (r = 0; r < t.length; ++r) if (t[r] == e[n]) continue e; t[t.length] = e[n] } return t } function $(e) { return typeof e == "object" && isFinite(e.length) } function J(t) { return t ? typeof t == "string" ? Q(t)[0] : !t[u] && $(t) ? t[0] : t : e } function K(e, t, n) { return e[u] === 9 ? e.getElementById(t) : e.ownerDocument && ((n = e.ownerDocument.getElementById(t)) && Y(n, e) && n || !Y(e, e.ownerDocument) && a('[id="' + t + '"]', e)[0]) } function Q(e, t) { var i, s, o = J(t); if (!o || !e) return []; if (e === window || X(e)) return !t || e !== window && X(o) && Y(e, o) ? [e] : []; if (e && $(e)) return H(e); if (i = e.match(x)) { if (i[1]) return (s = K(o, i[1])) ? [s] : []; if (i[2]) return B(o[r](i[2])); if (et && i[3]) return B(o[n](i[3])) } return a(e, o) } function G(e, t) { return function (n) { var r, i; if (v.test(n)) { e[u] !== 9 && ((i = r = e.getAttribute("id")) || e.setAttribute("id", i = "__qwerymeupscotty"), n = '[id="' + i + '"]' + n, t(e.parentNode || e, n, !0), r || e.removeAttribute("id")); return } n.length && t(e, n, !1) } } var e = document, t = e.documentElement, n = "getElementsByClassName", r = "getElementsByTagName", i = "querySelectorAll", s = "useNativeQSA", o = "tagName", u = "nodeType", a, f = /#([\w\-]+)/, l = /\.[\w\-]+/g, c = /^#([\w\-]+)$/, h = /^\.([\w\-]+)$/, p = /^([\w\-]+)$/, d = /^([\w]+)?\.([\w\-]+)$/, v = /(^|,)\s*[>~+]/, m = /^\s+|\s*([,\s\+\~>]|$)\s*/g, g = /[\s\>\+\~]/, y = /(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/, b = /([.*+?\^=!:${}()|\[\]\/\\])/g, w = /^(\*|[a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/, E = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/, S = /:([\w\-]+)(\(['"]?([^()]+)['"]?\))?/, x = new RegExp(c.source + "|" + p.source + "|" + h.source), T = new RegExp("(" + g.source + ")" + y.source, "g"), N = new RegExp(g.source + y.source), C = new RegExp(w.source + "(" + E.source + ")?" + "(" + S.source + ")?"), k = { " ": function (e) { return e && e !== t && e.parentNode }, ">": function (e, t) { return e && e.parentNode == t.parentNode && e.parentNode }, "~": function (e) { return e && e.previousSibling }, "+": function (e, t, n, r) { return e ? (n = j(e)) && (r = j(t)) && n == r && n : !1 } }; L.prototype = { g: function (e) { return this.c[e] || undefined }, s: function (e, t, n) { return t = n ? new RegExp(t) : t, this.c[e] = t } }; var A = new L, O = new L, M = new L, _ = new L, Y = "compareDocumentPosition" in t ? function (e, t) { return (t.compareDocumentPosition(e) & 16) == 16 } : "contains" in t ? function (e, n) { return n = n[u] === 9 || n == window ? t : n, n !== e && n.contains(e) } : function (e, t) { while (e = e.parentNode) if (e === t) return 1; return 0 }, Z = function () { var t = e.createElement("p"); return (t.innerHTML = 'x') && t.firstChild.getAttribute("href") != "#x" ? function (e, t) { return t === "class" ? e.className : t === "href" || t === "src" ? e.getAttribute(t, 2) : e.getAttribute(t) } : function (e, t) { return e.getAttribute(t) } }(), et = !!e[n], tt = e.querySelector && e[i], nt = function (e, t) { var n = [], r, s; try { return t[u] === 9 || !v.test(e) ? B(t[i](e)) : (P(r = e.split(","), G(t, function (e, t) { s = e[i](t), s.length == 1 ? n[n.length] = s.item(0) : s.length && (n = n.concat(B(s))) })), r.length > 1 && n.length > 1 ? V(n) : n) } catch (o) { } return rt(e, t) }, rt = function (e, t) { var n = [], i, s, o, a, f, l; e = e.replace(m, "$1"); if (s = e.match(d)) { f = D(s[2]), i = t[r](s[1] || "*"); for (o = 0, a = i.length; o < a; o++) f.test(i[o].className) && (n[n.length] = i[o]); return n } return P(l = e.split(","), G(t, function (e, r, i) { f = U(r, e); for (o = 0, a = f.length; o  1 && n.length > 1 ? V(n) : n }, it = function (e) { typeof e[s] != "undefined" && (a = e[s] ? tt ? nt : rt : rt) }; return it({ useNativeQSA: !0 }), Q.configure = it, Q.uniq = V, Q.is = z, Q.pseudos = {}, Q })
<commit_msg>Delete qwery.min.js<commit_after><|endoftext|>


<commit_before>import autosize from "autosize"

const script = String.raw`<script>
(function(){
  var handle = "@placeholder";
  var script = document.createElement("script");
  var source = document.getElementsByTagName("script")[0];

  script.async = 1;
  script.src = "https://nectar.ninja/api/v1/" + handle.replace(/^@/, "");

  source.parentNode.insertBefore(script, source);

  // Reset demo.
  document.cookie = 'sentry-close-timestamp=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;';
})();
</script>`

export default function runDemo(app) {
  const {embedCodeInput, pluginDetailsForm} = app.refs

  embedCodeInput.autofocus = false
  embedCodeInput.value = script
  autosize.update(embedCodeInput)
  app.parseInput()

  const {option_1} = app.entities

  option_1.title = "Twitter username"
  app.toggleEntityTracking(option_1.element)

  const fields = {
    "[name='email']": "demo@instantwordpressplugin.com",
    "[name='app[title]']": "Nectar Ninja",
    "[name='app[description]']": "Send website notifications via Twitter!",
    "[name='app[metadata][description]']": `Let users know of new features, deals or downtimes.
Dead-simple, no signup required. Yes, it's free.`
  }

  Object
    .keys(fields)
    .forEach(name => pluginDetailsForm.querySelector(name).value = fields[name])

  app.imageUploader.imageURL = "/external-assets/bee.png"
}
<commit_msg>Make Nectar Ninja demo experience more consistent.<commit_after>import autosize from "autosize"

const script = String.raw`<script>
(function(){
  var handle = "@NectarNinjaDemo";
  var script = document.createElement("script");
  var source = document.getElementsByTagName("script")[0];

  script.async = 1;
  script.src = "https://nectar.ninja/api/v1/" + handle.replace(/^@/, "");

  // Reset demo.
  document.cookie = 'sentry-close-timestamp=; path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;';

  source.parentNode.insertBefore(script, source);
})();
</script>`

export default function runDemo(app) {
  const {embedCodeInput, pluginDetailsForm} = app.refs

  embedCodeInput.autofocus = false
  embedCodeInput.value = script
  autosize.update(embedCodeInput)
  app.parseInput()

  const {option_1} = app.entities

  option_1.title = "Twitter username"
  app.toggleEntityTracking(option_1.element)

  const fields = {
    "[name='email']": "demo@instantwordpressplugin.com",
    "[name='app[title]']": "Nectar Ninja",
    "[name='app[description]']": "Send website notifications via Twitter!",
    "[name='app[metadata][description]']": `Let users know of new features, deals or downtimes.
Dead-simple, no signup required. Yes, it's free.`
  }

  Object
    .keys(fields)
    .forEach(name => pluginDetailsForm.querySelector(name).value = fields[name])

  app.imageUploader.imageURL = "/external-assets/bee.png"
}
<|endoftext|>


<commit_before>import Component from '@ember/component';
import Object, { computed } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';

const O = Object.create.bind(Object);

export default Component.extend({
    userAuth: service(),
    folderNavs: service(),
    store: service(),

    catalogTitle: 'WholeTale Catalog',
    catalogParentType: 'collection',
    catalogPath: '/collection/WholeTale Catalog/WholeTale Catalog',
    catalogId: '',
    catalogParentId: '',

    selectedMenuIndex: 0,
    dataSources: A([
        O({ name: 'WholeTale Catalog' }),
        O({ name: 'My Data' })
    ]),
    selectedDataSource: O({}),

    allSelectedItems: A(),

    folders: A(),
    files: A(),

    loading: true,
    loadingMessage: 'Preparing Files',
    loadError: false,
    currentFolder: null,
    rootFolderId: null,

    model: O({}),
    classNameBindings: ['injectedClassName'],

    injectedClassName: computed('modelType', 'model.{_modelType,_id}', function () {
        if (this.get('modelType')) {
            let newClass = `select-data-modal-${this.get('modelType')}`;
            return newClass;
        } else return '';
    }),

    actions: {
        selectDatasource(datasource, index) {
            this.set('selectedDataSource', datasource);
            this.set('selectedMenuIndex', index);
            this.requeryDatasets();
        },

        initData() {
            this.selectedDataSource = this.get('dataSources')[this.get('selectedMenuIndex')];

            let text = this.get('catalogTitle');
            this.get('store').query('collection', { text }).then((results) => {
                let firstResult = results.firstObject;
                this.set('catalogParentType', firstResult['_modelType']);
                this.set('catalogParentId', firstResult['_id']);

                // Only init after we've located the catalog
                this.initData.call(this);
            });
        },

        updateSessionData() {
            this.updateSessionData.call(this, this.get('allSelectedItems'));
        },

        cancel() {
            this.cancel.call(this);
        },

        dblClick(target) {
            this.dblClick.call(this, target);
        },

        onClick(target) {
            this.onClick.call(this, target);
        },

        goBack() {
            this.goBack.call(this, this.get('currentFolder'));
        },

        addSelectedData() {
            this.addSelectedData.call(this, this.get('datasets'), this.get('files'), this.get('folders'));
        },

        removeSelectedData() {
            this.removeSelectedData.call(this);
        },

        close() {
          const deselect = f => {
            if (f.selected) {
              f.set('selected', false);
            }
          }
          this.allSelectedItems.forEach(deselect);
          this.set('datasets', A());
          this.set('folders', A());
          this.set('files', A());
          this.set('currentFolder', null);
          this.set('rootFolderId', null);
        }
    },

    // -----------------------------------------------------------------------
    // BELOW ARE FUNCTIONS FOR DEFAULT BEHAVIOR:
    //    You can set custom behavior by overriding these functions.
    // -----------------------------------------------------------------------

    initData() {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        // this.set('allSelectedItems', A());
        this.set('folders', A());
        this.set('files', A());
        this.set('currentFolder', null);
        this.set('rootFolderId', null);

        return this.requeryDatasets();
    },

    requeryDatasets(adapterOptions = { queryParams: { limit: "0" } }) {
        const self = this;

        const store = this.get('store');
        let selectedDS = this.get('selectedDataSource');
        let catalogTitle = this.get('catalogTitle');
        let parentId = this.get('catalogParentId');
        let parentCollection = this.get('catalogParentType');
        let myData = selectedDS['name'] == catalogTitle ? false : true;

        return store.query('dataset', {
            myData,
            adapterOptions
        }).then(datasets => {
            self.set('rootFolderId', parentId);
            self.set('loading', false);
            self.set('datasets', A(datasets));
            self.set('folders', A([]));
            self.set('files', A([]));
            self.set('currentFolder', O({ id: parentId, _modelType: 'folder', parentCollection, parentId }));

            //return self.loadFolder.call(self, catalogId, 'folder');
        }).catch(e => {
            self.set('loadError', true);
            self.set('loadingMessage', 'Failed to load registered data. Please try again');
        })
    },

    dblClick(target) {
        if (!target || !target._modelType || (target._modelType !== 'folder' && target._modelType !== 'dataset')) {
            throw new Error('[select-data-modal] Cannot open. Not a folder or dataset.');
        }

        this.set('currentFolder', target);

        const self = this;
        return this.loadFolder.call(this, target.get('id'), target.get('_modelType')).catch(e => {
            self.set('loadError', true);
            self.set('loadingMessage', 'Failed to load registered data. Please try again');
        });
    },

    onClick(target) {
        let selected = !target.get('selected');
        target.set('selected', selected);
    },

    goBack(currentFolder, adapterOptions = { queryParams: { limit: "0" } }) {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        const store = this.get('store');

        let parentId = currentFolder.parentId;
        let parentType = currentFolder.parentCollection;

        const self = this;
        if (parentId == null || parentId == this.get('rootFolderId')) {
            return store.query('dataset', adapterOptions).then(datasets => {
                let catalogId = this.get('rootFolderId');
                self.set('loading', false);
                self.set('currentFolder', O({ id: catalogId, _modelType: 'folder', parentType, catalogId }));
                self.set('datasets', A(datasets));
                self.set('folders', A([]));
                self.set('files', A([]));
            });
        } else {
            return store.find('folder', parentId).then(parent => {
                self.set('currentFolder', parent);
                return self.loadFolder.call(self, parentId, parentType);
            }).catch(e => {
                self.set('loadError', true);
                self.set('loadingMessage', 'Failed to load registered data. Please try again');
            });
        }
    },

    loadFolder(parentId, parentType, adapterOptions = { queryParams: { limit: "0" } }) {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        const store = this.get('store');
        let fetchFolders = store.query('folder', { parentId, parentType, adapterOptions });
        let fetchFiles = store.query('item', { folderId: parentId, adapterOptions });

        const self = this;
        return Promise.all([fetchFolders, fetchFiles]).then(([folders, files]) => {
            self.set('datasets', A([]));
            self.set('folders', A(folders));
            self.set('files', A(files));
            self.set('loading', false);
        });
    },

    addSelectedData(datasets, files, folders) {
        const self = this;
        const add = f => {
          if (f.selected) {
            f.set('selected', false);
            let { id, name, _modelType } = f;
            if (!self.allSelectedItems.findBy('id', id)) {
                    self.allSelectedItems.pushObject(O({ id, name, _modelType }));
                }
            }
        }
        datasets.forEach(add);
        files.forEach(add);
        folders.forEach(add);
    },

    removeSelectedData() {
        const self = this;
        const del = f => {
            if (f.selected) {
                self.allSelectedItems.removeObject(f);
            }
        }
        let all = A(this.get('allSelectedItems').concat([]));
        all.forEach(del);
    },

    updateSessionData() {
        throw new Error('[select-data-modal] "updateSessionData" must be provided!!');
    },

    cancel() {

        // this.set('allSelectedItems', A());

        // NOTE(Adam): This causes an infinite loop where the function calls itself recursively forever.

        // if (this.get('cancel')) {
        //     this.get('cancel')();
        // } else {
        //     throw new Error('[select-data-modal] "cancel" function must be provided!!');
        // }
    }
});
<commit_msg>Fixes #401: Reordered navs on Select Data modal<commit_after>import Component from '@ember/component';
import Object, { computed } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';

const O = Object.create.bind(Object);

export default Component.extend({
    userAuth: service(),
    folderNavs: service(),
    store: service(),

    catalogTitle: 'WholeTale Catalog',
    catalogParentType: 'collection',
    catalogPath: '/collection/WholeTale Catalog/WholeTale Catalog',
    catalogId: '',
    catalogParentId: '',

    selectedMenuIndex: 0,
    dataSources: A([
        O({ name: 'My Data' }),
        O({ name: 'WholeTale Catalog' })
    ]),
    selectedDataSource: O({}),

    allSelectedItems: A(),

    folders: A(),
    files: A(),

    loading: true,
    loadingMessage: 'Preparing Files',
    loadError: false,
    currentFolder: null,
    rootFolderId: null,

    model: O({}),
    classNameBindings: ['injectedClassName'],

    injectedClassName: computed('modelType', 'model.{_modelType,_id}', function () {
        if (this.get('modelType')) {
            let newClass = `select-data-modal-${this.get('modelType')}`;
            return newClass;
        } else return '';
    }),

    actions: {
        selectDatasource(datasource, index) {
            this.set('selectedDataSource', datasource);
            this.set('selectedMenuIndex', index);
            this.requeryDatasets();
        },

        initData() {
            this.selectedDataSource = this.get('dataSources')[this.get('selectedMenuIndex')];

            let text = this.get('catalogTitle');
            this.get('store').query('collection', { text }).then((results) => {
                let firstResult = results.firstObject;
                this.set('catalogParentType', firstResult['_modelType']);
                this.set('catalogParentId', firstResult['_id']);

                // Only init after we've located the catalog
                this.initData.call(this);
            });
        },

        updateSessionData() {
            this.updateSessionData.call(this, this.get('allSelectedItems'));
        },

        cancel() {
            this.cancel.call(this);
        },

        dblClick(target) {
            this.dblClick.call(this, target);
        },

        onClick(target) {
            this.onClick.call(this, target);
        },

        goBack() {
            this.goBack.call(this, this.get('currentFolder'));
        },

        addSelectedData() {
            this.addSelectedData.call(this, this.get('datasets'), this.get('files'), this.get('folders'));
        },

        removeSelectedData() {
            this.removeSelectedData.call(this);
        },

        close() {
          const deselect = f => {
            if (f.selected) {
              f.set('selected', false);
            }
          }
          this.allSelectedItems.forEach(deselect);
          this.set('datasets', A());
          this.set('folders', A());
          this.set('files', A());
          this.set('currentFolder', null);
          this.set('rootFolderId', null);
        }
    },

    // -----------------------------------------------------------------------
    // BELOW ARE FUNCTIONS FOR DEFAULT BEHAVIOR:
    //    You can set custom behavior by overriding these functions.
    // -----------------------------------------------------------------------

    initData() {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        // this.set('allSelectedItems', A());
        this.set('folders', A());
        this.set('files', A());
        this.set('currentFolder', null);
        this.set('rootFolderId', null);

        return this.requeryDatasets();
    },

    requeryDatasets(adapterOptions = { queryParams: { limit: "0" } }) {
        const self = this;

        const store = this.get('store');
        let selectedDS = this.get('selectedDataSource');
        let catalogTitle = this.get('catalogTitle');
        let parentId = this.get('catalogParentId');
        let parentCollection = this.get('catalogParentType');
        let myData = selectedDS['name'] == catalogTitle ? false : true;

        return store.query('dataset', {
            myData,
            adapterOptions
        }).then(datasets => {
            self.set('rootFolderId', parentId);
            self.set('loading', false);
            self.set('datasets', A(datasets));
            self.set('folders', A([]));
            self.set('files', A([]));
            self.set('currentFolder', O({ id: parentId, _modelType: 'folder', parentCollection, parentId }));

            //return self.loadFolder.call(self, catalogId, 'folder');
        }).catch(e => {
            self.set('loadError', true);
            self.set('loadingMessage', 'Failed to load registered data. Please try again');
        })
    },

    dblClick(target) {
        if (!target || !target._modelType || (target._modelType !== 'folder' && target._modelType !== 'dataset')) {
            throw new Error('[select-data-modal] Cannot open. Not a folder or dataset.');
        }

        this.set('currentFolder', target);

        const self = this;
        return this.loadFolder.call(this, target.get('id'), target.get('_modelType')).catch(e => {
            self.set('loadError', true);
            self.set('loadingMessage', 'Failed to load registered data. Please try again');
        });
    },

    onClick(target) {
        let selected = !target.get('selected');
        target.set('selected', selected);
    },

    goBack(currentFolder, adapterOptions = { queryParams: { limit: "0" } }) {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        const store = this.get('store');

        let parentId = currentFolder.parentId;
        let parentType = currentFolder.parentCollection;

        const self = this;
        if (parentId == null || parentId == this.get('rootFolderId')) {
            return store.query('dataset', adapterOptions).then(datasets => {
                let catalogId = this.get('rootFolderId');
                self.set('loading', false);
                self.set('currentFolder', O({ id: catalogId, _modelType: 'folder', parentType, catalogId }));
                self.set('datasets', A(datasets));
                self.set('folders', A([]));
                self.set('files', A([]));
            });
        } else {
            return store.find('folder', parentId).then(parent => {
                self.set('currentFolder', parent);
                return self.loadFolder.call(self, parentId, parentType);
            }).catch(e => {
                self.set('loadError', true);
                self.set('loadingMessage', 'Failed to load registered data. Please try again');
            });
        }
    },

    loadFolder(parentId, parentType, adapterOptions = { queryParams: { limit: "0" } }) {
        this.set('loading', true);
        this.set('loadError', false);
        this.set('loadingMessage', 'Preparing Files');

        const store = this.get('store');
        let fetchFolders = store.query('folder', { parentId, parentType, adapterOptions });
        let fetchFiles = store.query('item', { folderId: parentId, adapterOptions });

        const self = this;
        return Promise.all([fetchFolders, fetchFiles]).then(([folders, files]) => {
            self.set('datasets', A([]));
            self.set('folders', A(folders));
            self.set('files', A(files));
            self.set('loading', false);
        });
    },

    addSelectedData(datasets, files, folders) {
        const self = this;
        const add = f => {
          if (f.selected) {
            f.set('selected', false);
            let { id, name, _modelType } = f;
            if (!self.allSelectedItems.findBy('id', id)) {
                    self.allSelectedItems.pushObject(O({ id, name, _modelType }));
                }
            }
        }
        datasets.forEach(add);
        files.forEach(add);
        folders.forEach(add);
    },

    removeSelectedData() {
        const self = this;
        const del = f => {
            if (f.selected) {
                self.allSelectedItems.removeObject(f);
            }
        }
        let all = A(this.get('allSelectedItems').concat([]));
        all.forEach(del);
    },

    updateSessionData() {
        throw new Error('[select-data-modal] "updateSessionData" must be provided!!');
    },

    cancel() {

        // this.set('allSelectedItems', A());

        // NOTE(Adam): This causes an infinite loop where the function calls itself recursively forever.

        // if (this.get('cancel')) {
        //     this.get('cancel')();
        // } else {
        //     throw new Error('[select-data-modal] "cancel" function must be provided!!');
        // }
    }
});
<|endoftext|>


<commit_before>/**
 *
 * MatchingReactions
 *
 */

import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router';

import Table, {
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  TableFooter,
  TablePagination,
} from 'material-ui/Table';
import { LinearProgress } from 'material-ui/Progress';
import Hidden from 'material-ui/Hidden';
import { withStyles } from 'material-ui/styles';
import FaCube from 'react-icons/lib/fa/cube';

import axios from 'axios';
import { graphQLRoot } from 'utils/constants';

const prettyPrintReaction = (reactants, products) => (`${Object.keys(JSON.parse(reactants)).join(' + ')}  ⇄  ${Object.keys(JSON.parse(products)).join(' + ')}`
  ).replace(/star/g, '*').replace(/gas/g, '(ℊ)');

const styles = () => ({
  tableFooter: {
    marginLeft: '-30px',
    div: {
      marginLeft: '-30px',
    },
  },

});

class MatchingReactions extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.fetchRow = this.fetchRow.bind(this);
    this.state = {
      order: 'asc',
      orderBy: 'energy',
      page: 0,
      rowsPerPage: 10,
      loading: false,
    };
  }

  fetchRow(reaction) {
    this.setState({
      loading: true,
    });
    let catappKeys;
    let catappIds;
    if (typeof reaction.aseIds !== 'undefined' && reaction.aseIds !== null) {
      catappIds = JSON.parse(reaction.aseIds);
      catappKeys = Object.keys(JSON.parse(reaction.aseIds));
    } else {
      catappIds = {};
      catappKeys = [];
      this.setState({
        loading: false,
      });
    }

    this.props.clearSystems();
    catappKeys.map((key) => {
      let aseId = catappIds[key];
      if (typeof aseId === 'object') {
        aseId = aseId[1];
      }
      const query = {
        query: `query{systems(uniqueId: "${aseId}") {
  edges {
    node {
    Formula
    energy
    Cifdata
    PublicationYear
    PublicationDoi
    PublicationAuthors
    PublicationTitle
    PublicationVolume
    PublicationUrl
    PublicationNumber
    PublicationJournal
    PublicationPages
    uniqueId
    volume
    mass
    Facet
    }
  }
}}`,
      };
      return axios.post(graphQLRoot, query).then((response) => {
        const node = response.data.data.systems.edges[0].node;
        node.DFTCode = reaction.dftCode;
        node.DFTFunctional = reaction.dftFunctional;
        node.aseId = aseId;
        node.key = key
          .replace(/.*TSstar/g, '‡')
          .replace(/(.*)gas/g, (match, p1) => `${p1}(ℊ)`)
          .replace(/(.+)star/, (match, p1) => `${p1}/${reaction.surfaceComposition}`)
          .replace(/star/, reaction.surfaceComposition);

        node.full_key = node.key;
        if (typeof node.Facet !== 'undefined' && node.Facet !== '' && node.Facet !== null) {
          node.full_key = `${node.full_key} [${node.Facet}]`;
        }
        if (node.key.indexOf('(ℊ)') > -1) {
          node.full_key = `Molecule ${node.full_key}`;
        } else {
          node.full_key = `Surface ${node.full_key}`;
        }

        this.props.saveSystem(node);
        this.setState({
          loading: false,
        });
      }).catch(() => {
        this.setState({
          loading: false,
        });
      });
    });
  }
  handlePageChange = (event, page) => {
    this.setState({ page });
  };
  handleChangeRowsPerPage = (event) => {
    this.setState({ rowsPerPage: event.target.value });
  };

  render() {
    if (this.props.matchingReactions.length === 0) {
      if (this.props.searchSubmitted) {
        return (

Ooops!

            No reaction energies found. Please remove one or more filters.
            Or <Link to={`/catKitDemo/fcc/3.91/${this.props.searchParams.surface}`}>construct</Link> your own.

        );
      }
      return null;
    }
    return (

Matching Reactions ({this.props.matchingReactions.length})

            <TableHead>
              <TableRow>
                <TableCell padding="none">Geometry</TableCell>
                <TableCell padding="none">Reaction</TableCell>
                <TableCell padding="none">Reaction Energy</TableCell>
                <Hidden smDown>
                  <TableCell>Activation Energy</TableCell>
                </Hidden>
                <TableCell padding="none">Surface</TableCell>
                <Hidden smDown>
                  <TableCell>Facet</TableCell>
                </Hidden>
              </TableRow>
            </TableHead>
            <TableBody>
              {
                /* eslint-disable arrow-body-style */
                this.props.matchingReactions
                  .slice(this.state.page * this.state.rowsPerPage, (this.state.page + 1) * this.state.rowsPerPage)
                  .map((result, i) => {
                    return (
                      <TableRow
                        hover
                        key={`row_${i}`}
                        onClick={() => {
                          this.props.selectReaction(result.node);
                          this.fetchRow(result.node);
                        }}
                      >
                        <TableCell padding="none">{result.node.aseIds !== null ? <FaCube /> : null}</TableCell>
                        <TableCell padding="dense">{prettyPrintReaction(result.node.reactants, result.node.products)}</TableCell>
                        <TableCell padding="none">{!result.node.reactionEnergy || `${result.node.reactionEnergy.toFixed(2)} eV` }</TableCell>
                        <Hidden smDown>
                          <TableCell>{!result.node.activationEnergy || `${result.node.activationEnergy.toFixed(2)} eV`}</TableCell>
                        </Hidden>
                        <TableCell padding="none">{result.node.surfaceComposition}</TableCell>
                        <Hidden smDown>
                          <TableCell>{result.node.facet}</TableCell>
                        </Hidden>
                      </TableRow>

                    );
                  })
                /* eslint-enable */
              }
            </TableBody>
            <TableFooter
              className={this.props.classes.tableFooter}
            >
              <TableRow>
                <TablePagination
                  count={this.props.matchingReactions.length}
                  rowsPerPage={this.state.rowsPerPage}
                  page={this.state.page}
                  onChangePage={this.handlePageChange}
                  onChangeRowsPerPage={this.handleChangeRowsPerPage}
                  rowsPerPageOptions={[10, 25, 100, 1000]}
                  className={this.props.classes.tableFooter}
                  labelRowsPerPage=""
                />
              </TableRow>
            </TableFooter>

        {this.state.loading ? <LinearProgress color="primary" /> : null }

    );
  }
}

MatchingReactions.propTypes = {
  selectReaction: PropTypes.func.isRequired,
  clearSystems: PropTypes.func.isRequired,
  saveSystem: PropTypes.func.isRequired,
  matchingReactions: PropTypes.array.isRequired,
  searchSubmitted: PropTypes.bool,
  searchParams: PropTypes.object,
  classes: PropTypes.object,
};

MatchingReactions.defaultProps = {
  searchResults: [],

};

export default withStyles(styles)(MatchingReactions);
<commit_msg>removed construction link for now<commit_after>/**
 *
 * MatchingReactions
 *
 */

import React from 'react';
import PropTypes from 'prop-types';
/* import { Link } from 'react-router';*/

import Table, {
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  TableFooter,
  TablePagination,
} from 'material-ui/Table';
import { LinearProgress } from 'material-ui/Progress';
import Hidden from 'material-ui/Hidden';
import { withStyles } from 'material-ui/styles';
import FaCube from 'react-icons/lib/fa/cube';

import axios from 'axios';
import { graphQLRoot } from 'utils/constants';

const prettyPrintReaction = (reactants, products) => (`${Object.keys(JSON.parse(reactants)).join(' + ')}  ⇄  ${Object.keys(JSON.parse(products)).join(' + ')}`
  ).replace(/star/g, '*').replace(/gas/g, '(ℊ)');

const styles = () => ({
  tableFooter: {
    marginLeft: '-30px',
    div: {
      marginLeft: '-30px',
    },
  },

});

class MatchingReactions extends React.Component { // eslint-disable-line react/prefer-stateless-function
  constructor(props) {
    super(props);
    this.fetchRow = this.fetchRow.bind(this);
    this.state = {
      order: 'asc',
      orderBy: 'energy',
      page: 0,
      rowsPerPage: 10,
      loading: false,
    };
  }

  fetchRow(reaction) {
    this.setState({
      loading: true,
    });
    let catappKeys;
    let catappIds;
    if (typeof reaction.aseIds !== 'undefined' && reaction.aseIds !== null) {
      catappIds = JSON.parse(reaction.aseIds);
      catappKeys = Object.keys(JSON.parse(reaction.aseIds));
    } else {
      catappIds = {};
      catappKeys = [];
      this.setState({
        loading: false,
      });
    }

    this.props.clearSystems();
    catappKeys.map((key) => {
      let aseId = catappIds[key];
      if (typeof aseId === 'object') {
        aseId = aseId[1];
      }
      const query = {
        query: `query{systems(uniqueId: "${aseId}") {
  edges {
    node {
    Formula
    energy
    Cifdata
    PublicationYear
    PublicationDoi
    PublicationAuthors
    PublicationTitle
    PublicationVolume
    PublicationUrl
    PublicationNumber
    PublicationJournal
    PublicationPages
    uniqueId
    volume
    mass
    Facet
    }
  }
}}`,
      };
      return axios.post(graphQLRoot, query).then((response) => {
        const node = response.data.data.systems.edges[0].node;
        node.DFTCode = reaction.dftCode;
        node.DFTFunctional = reaction.dftFunctional;
        node.aseId = aseId;
        node.key = key
          .replace(/.*TSstar/g, '‡')
          .replace(/(.*)gas/g, (match, p1) => `${p1}(ℊ)`)
          .replace(/(.+)star/, (match, p1) => `${p1}/${reaction.surfaceComposition}`)
          .replace(/star/, reaction.surfaceComposition);

        node.full_key = node.key;
        if (typeof node.Facet !== 'undefined' && node.Facet !== '' && node.Facet !== null) {
          node.full_key = `${node.full_key} [${node.Facet}]`;
        }
        if (node.key.indexOf('(ℊ)') > -1) {
          node.full_key = `Molecule ${node.full_key}`;
        } else {
          node.full_key = `Surface ${node.full_key}`;
        }

        this.props.saveSystem(node);
        this.setState({
          loading: false,
        });
      }).catch(() => {
        this.setState({
          loading: false,
        });
      });
    });
  }
  handlePageChange = (event, page) => {
    this.setState({ page });
  };
  handleChangeRowsPerPage = (event) => {
    this.setState({ rowsPerPage: event.target.value });
  };

  render() {
    if (this.props.matchingReactions.length === 0) {
      if (this.props.searchSubmitted) {
        return (

Ooops!

            No reaction energies found. Please remove one or more filters.
            {/* Or <Link to={`/catKitDemo/fcc/3.91/${this.props.searchParams.surface}`}>construct</Link> your own.  */}

        );
      }
      return null;
    }
    return (

Matching Reactions ({this.props.matchingReactions.length})

            <TableHead>
              <TableRow>
                <TableCell padding="none">Geometry</TableCell>
                <TableCell padding="none">Reaction</TableCell>
                <TableCell padding="none">Reaction Energy</TableCell>
                <Hidden smDown>
                  <TableCell>Activation Energy</TableCell>
                </Hidden>
                <TableCell padding="none">Surface</TableCell>
                <Hidden smDown>
                  <TableCell>Facet</TableCell>
                </Hidden>
              </TableRow>
            </TableHead>
            <TableBody>
              {
                /* eslint-disable arrow-body-style */
                this.props.matchingReactions
                  .slice(this.state.page * this.state.rowsPerPage, (this.state.page + 1) * this.state.rowsPerPage)
                  .map((result, i) => {
                    return (
                      <TableRow
                        hover
                        key={`row_${i}`}
                        onClick={() => {
                          this.props.selectReaction(result.node);
                          this.fetchRow(result.node);
                        }}
                      >
                        <TableCell padding="none">{result.node.aseIds !== null ? <FaCube /> : null}</TableCell>
                        <TableCell padding="dense">{prettyPrintReaction(result.node.reactants, result.node.products)}</TableCell>
                        <TableCell padding="none">{!result.node.reactionEnergy || `${result.node.reactionEnergy.toFixed(2)} eV` }</TableCell>
                        <Hidden smDown>
                          <TableCell>{!result.node.activationEnergy || `${result.node.activationEnergy.toFixed(2)} eV`}</TableCell>
                        </Hidden>
                        <TableCell padding="none">{result.node.surfaceComposition}</TableCell>
                        <Hidden smDown>
                          <TableCell>{result.node.facet}</TableCell>
                        </Hidden>
                      </TableRow>

                    );
                  })
                /* eslint-enable */
              }
            </TableBody>
            <TableFooter
              className={this.props.classes.tableFooter}
            >
              <TableRow>
                <TablePagination
                  count={this.props.matchingReactions.length}
                  rowsPerPage={this.state.rowsPerPage}
                  page={this.state.page}
                  onChangePage={this.handlePageChange}
                  onChangeRowsPerPage={this.handleChangeRowsPerPage}
                  rowsPerPageOptions={[10, 25, 100, 1000]}
                  className={this.props.classes.tableFooter}
                  labelRowsPerPage=""
                />
              </TableRow>
            </TableFooter>

        {this.state.loading ? <LinearProgress color="primary" /> : null }

    );
  }
}

MatchingReactions.propTypes = {
  selectReaction: PropTypes.func.isRequired,
  clearSystems: PropTypes.func.isRequired,
  saveSystem: PropTypes.func.isRequired,
  matchingReactions: PropTypes.array.isRequired,
  searchSubmitted: PropTypes.bool,
  /* searchParams: PropTypes.object,*/
  classes: PropTypes.object,
};

MatchingReactions.defaultProps = {
  searchResults: [],

};

export default withStyles(styles)(MatchingReactions);
<|endoftext|>