<commit_before>/*
 *
 * (c) Copyright Ascensio System Limited 2010-2017
 *
 * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
 * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
 * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
 *
 * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
 *
 * You can contact Ascensio System SIA by email at sales@onlyoffice.com
 *
 * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
 * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
 *
 * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
 * relevant author attributions when distributing the software. If the display of the logo in its graphic
 * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
 * in every copy of the program you distribute.
 * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
 *
*/

const path = require("path");
const fileSystem = require("fs");
const fileUtility = require("./fileUtility");
const documentService = require("./documentService");
const cacheManager = require("./cacheManager");
const guidManager = require("./guidManager");
const configServer = require('config').get('server');
const storageFolder = configServer.get('storageFolder');
const os = require("os");
const readline = require('readline');

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

let docManager = {};

docManager.dir = null;
docManager.req = null;
docManager.res = null;

docManager.existsSync = function(path) {
    let res = true;
    try {
        fileSystem.accessSync(path, fileSystem.F_OK);
    } catch (e) {
        res = false;
    }
    return res;
};
docManager.createDirectory = function(path) {
    if (!this.existsSync(path)) {
        fileSystem.mkdirSync(path);
    }
};

docManager.init = function (dir, req, res) {
    docManager.dir = dir;
    docManager.req = req;
    docManager.res = res;

    this.createDirectory(path.join(docManager.dir, "public", storageFolder));
};

docManager.getLang = function () {
    if (docManager.req.query.lang) {
        return docManager.req.query.lang;
    } else {
        return "en"
    }
};

docManager.getCustomParams = function () {
    let params = "";

    const userid = docManager.req.query.userid;
    params += (userid ? "&userid=" + userid : "");

    const name = docManager.req.query.name;
    params += (name ? "&name=" + name : "");

    const lang = docManager.req.query.lang;
    params += (lang ? "&lang=" + docManager.getLang() : "");

    const fileName = docManager.req.query.fileName;
    params += (fileName ? "&fileName=" + fileName : "");

    const mode = docManager.req.query.mode;
    params += (mode ? "&mode=" + mode : "");

    const type = docManager.req.query.type;
    params += (type ? "&type=" + type : "");

    return params;
};

docManager.getCorrectName = function (fileName, userAddress) {
    const baseName = fileUtility.getFileName(fileName, true);
    const ext = fileUtility.getFileExtension(fileName);
    let name = baseName + ext;
    let index = 1;

    while (this.existsSync(docManager.storagePath(name, userAddress))) {
        name = baseName + " (" + index + ")" + ext;
        index++;
    }

    return name;
};

docManager.createDemo = function (demoName, userid, username) {
    const fileName = docManager.getCorrectName(demoName);

    docManager.copyFile(path.join(docManager.dir, "public", "samples", demoName), docManager.storagePath(fileName));

    docManager.saveFileData(fileName, userid, username);

    return fileName;
};

docManager.saveFileData = function (fileName, userid, username) {
    const userAddress = docManager.curUserHostAddress();
    const date_create = fileSystem.statSync(docManager.storagePath(fileName)).mtime;
    const minutes = (date_create.getMinutes() < 10 ? '0' : '') + date_create.getMinutes().toString();
    const month = (date_create.getMonth() < 10 ? '0' : '') + (parseInt(date_create.getMonth().toString()) + 1);
    const sec = (date_create.getSeconds() < 10 ? '0' : '') + date_create.getSeconds().toString();
    const date_format = date_create.getFullYear() + "-" + month + "-" + date_create.getDate() + " " + date_create.getHours() + ":" + minutes + ":" + sec;

    const file_info = docManager.historyPath(fileName, userAddress, true);
    this.createDirectory(file_info);

    fileSystem.writeFileSync(path.join(file_info, fileName + ".txt"), date_format + "," + userid + "," + username);
};

docManager.getFileData = function (fileName, userAddress) {
    const history = path.join(docManager.historyPath(fileName, userAddress, true), fileName + ".txt");
    if (!this.existsSync(history)) {
        return ["2017-01-01", "uid-1", "John Smith"];
    }

    return ((fileSystem.readFileSync(history)).toString()).split(",");
};

docManager.getFileUri = function (fileName) {
    return docManager.getlocalFileUri(fileName);
};

docManager.getlocalFileUri = function (fileName, version) {
    const serverPath = docManager.getServerUrl();
    const storagePath = storageFolder.length ? storageFolder + "/" : "";
    const hostAddress = docManager.curUserHostAddress();
    const url = serverPath + "/" + storagePath + hostAddress + "/" + encodeURIComponent(fileName);
    if (!version) {
        return url;
    }
    return url + "-history/" + version;
};

docManager.getServerUrl = function () {
    return docManager.getProtocol() + "://" + docManager.req.get("host");
};

docManager.getCallback = function (fileName) {
    const server = docManager.getServerUrl();
    const hostAddress = docManager.curUserHostAddress();
    const handler = "/track?filename=" + encodeURIComponent(fileName) + "&useraddress=" + encodeURIComponent(hostAddress);

    return server + handler;
};

docManager.storagePath = function (fileName, userAddress) {
    fileName = fileUtility.getFileName(fileName);
    const directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    this.createDirectory(directory);
    return path.join(directory, fileName);
};

docManager.forcesavePath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    this.createDirectory(directory);
    directory = path.join(directory, fileName);
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    return directory;
};

docManager.historyPath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(path.join(directory, "1"))) {
        return "";
    }
    return directory;
};

docManager.versionPath = function (fileName, userAddress, version) {
    const historyPath = docManager.historyPath(fileName, userAddress, true);
    return path.join(historyPath, "" + version);
};

docManager.prevFilePath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "prev" + fileUtility.getFileExtension(fileName));
};

docManager.diffPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "diff.zip");
};

docManager.changesPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "changes.txt");
};

docManager.keyPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "key.txt");
};

docManager.changesUser = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "user.txt");
};

docManager.getStoredFiles = function () {
    const directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress());
    this.createDirectory(directory);
    const result = [];
    const storedFiles = fileSystem.readdirSync(directory);
    for (let i = 0; i < storedFiles.length; i++) {
        const stats = fileSystem.lstatSync(path.join(directory, storedFiles[i]));

        if (!stats.isDirectory()) {

            const time = stats.mtime.getTime();
            const item = {
                time: time,
                name: storedFiles[i],
                documentType: fileUtility.getFileType(storedFiles[i])
            };

            if (!result.length) {
                result.push(item);
            } else {
                let j = 0;
                for (; j < result.length; j++) {
                    if (time > result[j].time) {
                        break;
                    }
                }
                result.splice(j, 0, item);
            }
        }
    }
    return result;
};

docManager.getProtocol = function () {
    return docManager.req.headers["x-forwarded-proto"] || docManager.req.protocol;
};

docManager.curUserHostAddress = function (userAddress) {
    if (!userAddress)
        userAddress = docManager.req.headers["x-forwarded-for"] || docManager.req.connection.remoteAddress;

    return userAddress.replace(new RegExp("[^0-9a-zA-Z.=]", "g"), "_");
};

docManager.copyFile = function (exist, target) {
    fileSystem.writeFileSync(target, fileSystem.readFileSync(exist));
};

docManager.getInternalExtension = function (fileType) {
    if (fileType == fileUtility.fileType.text)
        return ".docx";

    if (fileType == fileUtility.fileType.spreadsheet)
        return ".xlsx";

    if (fileType == fileUtility.fileType.presentation)
        return ".pptx";

    return ".docx";
};

docManager.getKey = function (fileName) {
    const userAddress = docManager.curUserHostAddress();
    let key = userAddress + docManager.getlocalFileUri(fileName);

    let historyPath = docManager.historyPath(fileName, userAddress);
    if (historyPath != ""){
        key += docManager.countVersion(historyPath);
    }

    /*historyPath = docManager.historyPath(fileName, userAddress, true);
    const stat = fileSystem.statSync(historyPath);
    key += stat.mtime.toString();*/

    return documentService.generateRevisionId(key);
};

docManager.getDate = function (date) {
    const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes().toString();
    return date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() + " " + date.getHours() + ":" + minutes;
};

docManager.getChanges = function (fileName) {
    return JSON.parse(fileSystem.readFileSync(fileName));
};

docManager.countVersion = function(directory) {
    let i = 0;
    while (this.existsSync(path.join(directory, '' + (i + 1)))) {
        i++;
    }
    return i;
};

docManager.getHistory = function (fileName, content, keyVersion, version) {
    let oldVersion = false;
    let contentJson = null;
    if (content) {
        if (content.changes) {
            contentJson = content.changes[0];
        } else {
            contentJson = content[0];
            oldVersion = true;
        }
    }

    const userAddress = docManager.curUserHostAddress();
    const username = content ? (oldVersion ? contentJson.username : contentJson.user.name) : (docManager.getFileData(fileName, userAddress))[2];
    const userid = content ? (oldVersion ? contentJson.userid : contentJson.user.id) : (docManager.getFileData(fileName, userAddress))[1];
    const created = content ? (oldVersion ? contentJson.date : contentJson.created) : (docManager.getFileData(fileName, userAddress))[0];
    const res = (content && !oldVersion) ? content : {changes: content};
    res.key = keyVersion;
    res.version = version;
    res.created = created;
    res.user = {
        id: userid,
        name: username
    };

    return res;
};

docManager.cleanFolderRecursive = function (folder, me) {
    if (fileSystem.existsSync(folder)) {
        const files = fileSystem.readdirSync(folder);
        files.forEach((file) => {
            const curPath = path.join(folder, file);
            if (fileSystem.lstatSync(curPath).isDirectory()) {
                this.cleanFolderRecursive(curPath, true);
            } else {
                fileSystem.unlinkSync(curPath);
            }
        });
        if (me) {
            fileSystem.rmdirSync(folder);
        }
    }
};

module.exports = docManager;
<commit_msg>qBBBBBBBBBAAAAAMerge branch 'hotfix/v4.3.5'<commit_after>/*
 *
 * (c) Copyright Ascensio System Limited 2010-2017
 *
 * This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
 * In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
 * Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
 *
 * THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
 *
 * You can contact Ascensio System SIA by email at sales@onlyoffice.com
 *
 * The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
 * Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
 *
 * Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
 * relevant author attributions when distributing the software. If the display of the logo in its graphic
 * form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
 * in every copy of the program you distribute.
 * Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
 *
*/

const path = require("path");
const fileSystem = require("fs");
const fileUtility = require("./fileUtility");
const documentService = require("./documentService");
const cacheManager = require("./cacheManager");
const guidManager = require("./guidManager");
const configServer = require('config').get('server');
const storageFolder = configServer.get('storageFolder');
const os = require("os");

let docManager = {};

docManager.dir = null;
docManager.req = null;
docManager.res = null;

docManager.existsSync = function(path) {
    let res = true;
    try {
        fileSystem.accessSync(path, fileSystem.F_OK);
    } catch (e) {
        res = false;
    }
    return res;
};
docManager.createDirectory = function(path) {
    if (!this.existsSync(path)) {
        fileSystem.mkdirSync(path);
    }
};

docManager.init = function (dir, req, res) {
    docManager.dir = dir;
    docManager.req = req;
    docManager.res = res;

    this.createDirectory(path.join(docManager.dir, "public", storageFolder));
};

docManager.getLang = function () {
    if (docManager.req.query.lang) {
        return docManager.req.query.lang;
    } else {
        return "en"
    }
};

docManager.getCustomParams = function () {
    let params = "";

    const userid = docManager.req.query.userid;
    params += (userid ? "&userid=" + userid : "");

    const name = docManager.req.query.name;
    params += (name ? "&name=" + name : "");

    const lang = docManager.req.query.lang;
    params += (lang ? "&lang=" + docManager.getLang() : "");

    const fileName = docManager.req.query.fileName;
    params += (fileName ? "&fileName=" + fileName : "");

    const mode = docManager.req.query.mode;
    params += (mode ? "&mode=" + mode : "");

    const type = docManager.req.query.type;
    params += (type ? "&type=" + type : "");

    return params;
};

docManager.getCorrectName = function (fileName, userAddress) {
    const baseName = fileUtility.getFileName(fileName, true);
    const ext = fileUtility.getFileExtension(fileName);
    let name = baseName + ext;
    let index = 1;

    while (this.existsSync(docManager.storagePath(name, userAddress))) {
        name = baseName + " (" + index + ")" + ext;
        index++;
    }

    return name;
};

docManager.createDemo = function (demoName, userid, username) {
    const fileName = docManager.getCorrectName(demoName);

    docManager.copyFile(path.join(docManager.dir, "public", "samples", demoName), docManager.storagePath(fileName));

    docManager.saveFileData(fileName, userid, username);

    return fileName;
};

docManager.saveFileData = function (fileName, userid, username) {
    const userAddress = docManager.curUserHostAddress();
    const date_create = fileSystem.statSync(docManager.storagePath(fileName)).mtime;
    const minutes = (date_create.getMinutes() < 10 ? '0' : '') + date_create.getMinutes().toString();
    const month = (date_create.getMonth() < 10 ? '0' : '') + (parseInt(date_create.getMonth().toString()) + 1);
    const sec = (date_create.getSeconds() < 10 ? '0' : '') + date_create.getSeconds().toString();
    const date_format = date_create.getFullYear() + "-" + month + "-" + date_create.getDate() + " " + date_create.getHours() + ":" + minutes + ":" + sec;

    const file_info = docManager.historyPath(fileName, userAddress, true);
    this.createDirectory(file_info);

    fileSystem.writeFileSync(path.join(file_info, fileName + ".txt"), date_format + "," + userid + "," + username);
};

docManager.getFileData = function (fileName, userAddress) {
    const history = path.join(docManager.historyPath(fileName, userAddress, true), fileName + ".txt");
    if (!this.existsSync(history)) {
        return ["2017-01-01", "uid-1", "John Smith"];
    }

    return ((fileSystem.readFileSync(history)).toString()).split(",");
};

docManager.getFileUri = function (fileName) {
    return docManager.getlocalFileUri(fileName);
};

docManager.getlocalFileUri = function (fileName, version) {
    const serverPath = docManager.getServerUrl();
    const storagePath = storageFolder.length ? storageFolder + "/" : "";
    const hostAddress = docManager.curUserHostAddress();
    const url = serverPath + "/" + storagePath + hostAddress + "/" + encodeURIComponent(fileName);
    if (!version) {
        return url;
    }
    return url + "-history/" + version;
};

docManager.getServerUrl = function () {
    return docManager.getProtocol() + "://" + docManager.req.get("host");
};

docManager.getCallback = function (fileName) {
    const server = docManager.getServerUrl();
    const hostAddress = docManager.curUserHostAddress();
    const handler = "/track?filename=" + encodeURIComponent(fileName) + "&useraddress=" + encodeURIComponent(hostAddress);

    return server + handler;
};

docManager.storagePath = function (fileName, userAddress) {
    fileName = fileUtility.getFileName(fileName);
    const directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    this.createDirectory(directory);
    return path.join(directory, fileName);
};

docManager.forcesavePath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    this.createDirectory(directory);
    directory = path.join(directory, fileName);
    if (!create && !this.existsSync(directory)) {
        return "";
    }
    return directory;
};

docManager.historyPath = function (fileName, userAddress, create) {
    let directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress(userAddress));
    if (!this.existsSync(directory)) {
        return "";
    }
    directory = path.join(directory, fileName + "-history");
    if (!create && !this.existsSync(path.join(directory, "1"))) {
        return "";
    }
    return directory;
};

docManager.versionPath = function (fileName, userAddress, version) {
    const historyPath = docManager.historyPath(fileName, userAddress, true);
    return path.join(historyPath, "" + version);
};

docManager.prevFilePath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "prev" + fileUtility.getFileExtension(fileName));
};

docManager.diffPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "diff.zip");
};

docManager.changesPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "changes.txt");
};

docManager.keyPath = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "key.txt");
};

docManager.changesUser = function (fileName, userAddress, version) {
    return path.join(docManager.versionPath(fileName, userAddress, version), "user.txt");
};

docManager.getStoredFiles = function () {
    const directory = path.join(docManager.dir, "public", storageFolder, docManager.curUserHostAddress());
    this.createDirectory(directory);
    const result = [];
    const storedFiles = fileSystem.readdirSync(directory);
    for (let i = 0; i < storedFiles.length; i++) {
        const stats = fileSystem.lstatSync(path.join(directory, storedFiles[i]));

        if (!stats.isDirectory()) {

            const time = stats.mtime.getTime();
            const item = {
                time: time,
                name: storedFiles[i],
                documentType: fileUtility.getFileType(storedFiles[i])
            };

            if (!result.length) {
                result.push(item);
            } else {
                let j = 0;
                for (; j < result.length; j++) {
                    if (time > result[j].time) {
                        break;
                    }
                }
                result.splice(j, 0, item);
            }
        }
    }
    return result;
};

docManager.getProtocol = function () {
    return docManager.req.headers["x-forwarded-proto"] || docManager.req.protocol;
};

docManager.curUserHostAddress = function (userAddress) {
    if (!userAddress)
        userAddress = docManager.req.headers["x-forwarded-for"] || docManager.req.connection.remoteAddress;

    return userAddress.replace(new RegExp("[^0-9a-zA-Z.=]", "g"), "_");
};

docManager.copyFile = function (exist, target) {
    fileSystem.writeFileSync(target, fileSystem.readFileSync(exist));
};

docManager.getInternalExtension = function (fileType) {
    if (fileType == fileUtility.fileType.text)
        return ".docx";

    if (fileType == fileUtility.fileType.spreadsheet)
        return ".xlsx";

    if (fileType == fileUtility.fileType.presentation)
        return ".pptx";

    return ".docx";
};

docManager.getKey = function (fileName) {
    const userAddress = docManager.curUserHostAddress();
    let key = userAddress + docManager.getlocalFileUri(fileName);

    let historyPath = docManager.historyPath(fileName, userAddress);
    if (historyPath != ""){
        key += docManager.countVersion(historyPath);
    }

    /*historyPath = docManager.historyPath(fileName, userAddress, true);
    const stat = fileSystem.statSync(historyPath);
    key += stat.mtime.toString();*/

    return documentService.generateRevisionId(key);
};

docManager.getDate = function (date) {
    const minutes = (date.getMinutes() < 10 ? '0' : '') + date.getMinutes().toString();
    return date.getMonth() + "/" + date.getDate() + "/" + date.getFullYear() + " " + date.getHours() + ":" + minutes;
};

docManager.getChanges = function (fileName) {
    return JSON.parse(fileSystem.readFileSync(fileName));
};

docManager.countVersion = function(directory) {
    let i = 0;
    while (this.existsSync(path.join(directory, '' + (i + 1)))) {
        i++;
    }
    return i;
};

docManager.getHistory = function (fileName, content, keyVersion, version) {
    let oldVersion = false;
    let contentJson = null;
    if (content) {
        if (content.changes) {
            contentJson = content.changes[0];
        } else {
            contentJson = content[0];
            oldVersion = true;
        }
    }

    const userAddress = docManager.curUserHostAddress();
    const username = content ? (oldVersion ? contentJson.username : contentJson.user.name) : (docManager.getFileData(fileName, userAddress))[2];
    const userid = content ? (oldVersion ? contentJson.userid : contentJson.user.id) : (docManager.getFileData(fileName, userAddress))[1];
    const created = content ? (oldVersion ? contentJson.date : contentJson.created) : (docManager.getFileData(fileName, userAddress))[0];
    const res = (content && !oldVersion) ? content : {changes: content};
    res.key = keyVersion;
    res.version = version;
    res.created = created;
    res.user = {
        id: userid,
        name: username
    };

    return res;
};

docManager.cleanFolderRecursive = function (folder, me) {
    if (fileSystem.existsSync(folder)) {
        const files = fileSystem.readdirSync(folder);
        files.forEach((file) => {
            const curPath = path.join(folder, file);
            if (fileSystem.lstatSync(curPath).isDirectory()) {
                this.cleanFolderRecursive(curPath, true);
            } else {
                fileSystem.unlinkSync(curPath);
            }
        });
        if (me) {
            fileSystem.rmdirSync(folder);
        }
    }
};

module.exports = docManager;
<|endoftext|>


<commit_before>/* eslint-env jest */

import environment from 'js/relay-env'
import commitMutation from 'relay-commit-mutation-promise'

jest.mock('js/relay-env')
jest.mock('react-relay')
jest.mock('relay-commit-mutation-promise')

const getMockInput = () => ({
  userId: 'abc-123',
  charityId: 'some-charity-id',
  vc: 12
})

const getMockAdditionalVars = () => ({})

describe('DonateVcMutation', () => {
  it('calls commitMutation with expected values', async () => {
    expect.assertions(1)
    const DonateVcMutation = require('../DonateVcMutation').default
    const args = getMockInput()
    DonateVcMutation(args, getMockAdditionalVars())
    expect(commitMutation).toHaveBeenCalledWith(
      environment,
      {
        mutation: expect.any(Function),
        variables: {
          input: args
        }
      }
    )
  })

  it('uses the expected mutation name', async () => {
    expect.assertions(2)
    const DonateVcMutation = require('../DonateVcMutation').default
    const args = getMockInput()
    DonateVcMutation(args, getMockAdditionalVars())
    const mutationResponse = commitMutation.mock.calls[0][1].mutation()
    expect(mutationResponse.name).toBe('DonateVcMutation')
    expect(mutationResponse.operation.selections[0].name).toBe('donateVc')
  })
})
<commit_msg>Remove broken (not-so-useful) test<commit_after>/* eslint-env jest */

import environment from 'js/relay-env'
import commitMutation from 'relay-commit-mutation-promise'

jest.mock('js/relay-env')
jest.mock('react-relay')
jest.mock('relay-commit-mutation-promise')

const getMockInput = () => ({
  userId: 'abc-123',
  charityId: 'some-charity-id',
  vc: 12
})

const getMockAdditionalVars = () => ({})

describe('DonateVcMutation', () => {
  it('calls commitMutation with expected values', async () => {
    expect.assertions(1)
    const DonateVcMutation = require('../DonateVcMutation').default
    const args = getMockInput()
    DonateVcMutation(args, getMockAdditionalVars())
    expect(commitMutation).toHaveBeenCalledWith(
      environment,
      {
        mutation: expect.any(Function),
        variables: {
          input: args
        }
      }
    )
  })
})
<|endoftext|>


<commit_before>'use strict';

var m = require('mithril');

var Fangorn = require('js/fangorn');

// Define Fangorn Button Actions
var _figshareItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        // If File and FileRead are not defined dropzone is not supported and neither is uploads
        if (window.File && window.FileReader && item.data.permissions && item.data.permissions.edit && item.kind === 'folder') {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        Fangorn.ButtonEvents._uploadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-upload',
                    className: 'text-success'
                }, 'Upload')
            );
        }
        if (item.kind === 'file' && item.data.extra && item.data.extra.status === 'public') {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        Fangorn.ButtonEvents._downloadEvent.call(tb, event, item);
                    },
                    icon: 'fa fa-download',
                    className: 'text-primary'
                }, 'Download')
            );
        }
        // Files can be deleted if private or if it is in a dataset that contains more than one file
        var privateOrSiblings = (item.data.extra && item.data.extra.status !== 'public') ||
            (!item.parent().data.isAddonRoot && item.parent().children.length > 1);
        if (item.kind === 'file' && item.data.permissions && item.data.permissions.view) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function(event) {
                        Fangorn.ButtonEvents._gotoFileEvent.call(tb, item);
                    },
                    icon: 'fa fa-file-o',
                    className : 'text-info'
                }, 'View'));
        }
        if (item.kind === 'file' && privateOrSiblings && item.data.permissions && item.data.permissions.edit) {
            buttons.push(
                m.component(Fangorn.Components.button, {
                    onclick: function (event) {
                        Fangorn.ButtonEvents._removeEvent.call(tb, event, tb.multiselected());
                    },
                    icon: 'fa fa-trash',
                    className: 'text-danger'
                }, 'Delete')
            );
        }
        if (item.kind === 'file' && item.data.permissions && item.data.permissions.view && item.data.extra.status === 'public') {
            buttons.push(
                m('a.text-info.fangorn-toolbar-icon', {href: item.data.extra.webView}, [
                    m('i.fa.fa-external-link'),
                    m('span', 'View on figshare')
                ])
            );
        }
        return m('span', buttons); // Tell fangorn this function is used.
    }
};

Fangorn.config.figshare = {
    // Fangorn options are called if functions, so return a thunk that returns the column builder
    itemButtons: _figshareItemButtons
};
<commit_msg>Only show search button in toolbar for figshare files<commit_after>'use strict';

var m = require('mithril');

var Fangorn = require('js/fangorn');

// Define Fangorn Button Actions
var _figshareItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        if (tb.options.placement !== 'fileview') {
            // If File and FileRead are not defined dropzone is not supported and neither is uploads
            if (window.File && window.FileReader && item.data.permissions && item.data.permissions.edit && item.kind === 'folder') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._uploadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-upload',
                        className: 'text-success'
                    }, 'Upload')
                );
            }
            if (item.kind === 'file' && item.data.extra && item.data.extra.status === 'public') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._downloadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-download',
                        className: 'text-primary'
                    }, 'Download')
                );
            }
            // Files can be deleted if private or if it is in a dataset that contains more than one file
            var privateOrSiblings = (item.data.extra && item.data.extra.status !== 'public') ||
                (!item.parent().data.isAddonRoot && item.parent().children.length > 1);
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._gotoFileEvent.call(tb, item);
                        },
                        icon: 'fa fa-file-o',
                        className: 'text-info'
                    }, 'View'));
            }
            if (item.kind === 'file' && privateOrSiblings && item.data.permissions && item.data.permissions.edit) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._removeEvent.call(tb, event, tb.multiselected());
                        },
                        icon: 'fa fa-trash',
                        className: 'text-danger'
                    }, 'Delete')
                );
            }
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view && item.data.extra.status === 'public') {
                buttons.push(
                    m('a.text-info.fangorn-toolbar-icon', {href: item.data.extra.webView}, [
                        m('i.fa.fa-external-link'),
                        m('span', 'View on figshare')
                    ])
                );
            }
        }
        return m('span', buttons); // Tell fangorn this function is used.
    }
};

Fangorn.config.figshare = {
    // Fangorn options are called if functions, so return a thunk that returns the column builder
    itemButtons: _figshareItemButtons
};
<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/DeveloperError',
        '../Core/destroyObject',
        '../Core/BoundingSphere',
        '../Core/Cartesian3',
        '../Core/Color',
        '../Core/PolylinePipeline'
    ], function(
        DeveloperError,
        destroyObject,
        BoundingSphere,
        Cartesian3,
        Color,
        PolylinePipeline) {
    "use strict";

    /**
     *
     * @alias Polyline
     * @internalConstructor
     */
    var Polyline = function(polylineTemplate, polylineCollection) {
        var p = polylineTemplate || {};

        this._positions = typeof p.positions !== 'undefined' ? p.positions : [];
        this._positionsLength = this._positions.length;
        this._show = typeof p.show === 'undefined' ? true : p.show;
        this._width = typeof p.width === 'undefined' ? 1.0 : p.width;
        this._outlineWidth = typeof p.outlineWidth === 'undefined' ? 0.0 : p.outlineWidth;
        this._color = typeof p.color === 'undefined' ? new Color(1.0, 1.0, 1.0, 1.0) : Color.clone(p.color);
        this._outlineColor = (typeof p.outlineColor === 'undefined') ? new Color(1.0, 1.0, 1.0, 1.0) : Color.clone(p.outlineColor);
        this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES);
        this._collection = polylineCollection;
        this._dirty = false;
        this._pickId = undefined;
        this._pickIdThis = p._pickIdThis;
        this._segments = undefined;
        this._actualLength = this._positions.length;

        this._boundingVolume = undefined;
        if (this._positionsLength > 0) {
            this._boundingVolume = BoundingSphere.fromPoints(this._positions);
        }
    };

    var SHOW_INDEX = Polyline.SHOW_INDEX = 0;
    var POSITION_INDEX = Polyline.POSITION_INDEX = 1;
    var COLOR_INDEX = Polyline.COLOR_INDEX = 2;
    var OUTLINE_COLOR_INDEX = Polyline.OUTLINE_COLOR_INDEX = 3;
    var WIDTH_INDEX = Polyline.WIDTH_INDEX = 4;
    var OUTLINE_WIDTH_INDEX = Polyline.OUTLINE_WIDTH_INDEX = 5;
    var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 6;
    Polyline.NUMBER_OF_PROPERTIES = 7;
    var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES;

    /**
     * Returns true if this polyline will be shown.  Call {@link Polyline#setShow}
     * to hide or show a polyline, instead of removing it and re-adding it to the collection.
     *
     * @memberof Polyline
     *
     * @return {Boolean} true if this polyline will be shown; otherwise, false.
     *
     * @see Polyline#setShow
     */
    Polyline.prototype.getShow = function() {
        return this._show;
    };

    /**
     * Determines if this polyline will be shown.  Call this to hide or show a polyline, instead
     * of removing it and re-adding it to the collection.
     *
     * @memberof Polyline
     *
     * @param {Boolean} value Indicates if this polyline will be shown.
     *
     * @see Polyline#getShow
     */
    Polyline.prototype.setShow = function(value) {
        if ((typeof value !== 'undefined') && (this._show !== value)) {
            this._show = value;
            this._makeDirty(SHOW_INDEX);
        }
    };

    /**
     * Returns the polyline's positions.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see Polyline#setPositions
     */
    Polyline.prototype.getPositions = function() {
        return this._positions;
    };

    /**
    * Defines the positions of the polyline.
    *
    * @memberof Polyline
    *
    * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
    * @see Polyline#getPositions
    *
    * @example
    * polyline.setPositions(
    *   ellipsoid.toCartesians(new Cartographic3(...),
    *                          new Cartographic3(...),
    *                          new Cartographic3(...))
    * );
     */
    Polyline.prototype.setPositions = function(positions) {
        if (typeof positions === 'undefined') {
            positions = [];
        }
        if (this._positionsLength !== positions.length) {
            this._positionsLength = positions.length;
            this._makeDirty(POSITION_SIZE_INDEX);
        }
        this._positions = positions;

        if (this._positionsLength > 0) {
            this._boundingVolume = BoundingSphere.fromPoints(this._positions);
        } else {
            this._boundingVolume = undefined;
        }
        this._makeDirty(POSITION_INDEX);
    };

    /**
     * Returns the color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @return {Color}
     *
     * @see Polyline#setColor
     */
    Polyline.prototype.getColor = function() {
        return this._color;
    };

    /**
    * Sets the color of the polyline.
    *
    * @memberof Polyline
    *
    * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
    *
    * @param {Color} value. The color of the polyline.
     *
    * @see Polyline#getColor
     */
    Polyline.prototype.setColor = function(value) {
        var c = this._color;

        if ((typeof value !== 'undefined') && ((c.red !== value.red) || (c.green !== value.green) || (c.blue !== value.blue) || (c.alpha !== value.alpha))) {
            this._color = new Color(value.red, value.green, value.blue, value.alpha);
            this._makeDirty(COLOR_INDEX);
        }
    };

    /**
    *

    * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
    * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
    * {@link Context#getMaximumAliasedLineWidth}.
    *
    * @type Number
    *
    * @see Polyline#width
    * @see Context#getMinimumAliasedLineWidth
    * @see Context#getMaximumAliasedLineWidth
    *
    * @example
    * // 3 pixel total width, 1 pixel interior width
    * polyline.width = 1.0;
    * polyline.outlineWidth = 3.0;
    */
    Polyline.prototype.getWidth = function() {
        return this._width;
    };

    /**
     *

     * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
     * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
     * {@link Context#getMaximumAliasedLineWidth}.
     *
     * @type Number
     *
     * @see Polyline#width
     * @see Context#getMinimumAliasedLineWidth
     * @see Context#getMaximumAliasedLineWidth
     *
     * @example
     * // 3 pixel total width, 1 pixel interior width
     * polyline.width = 1.0;
     * polyline.outlineWidth = 3.0;
     */
    Polyline.prototype.setWidth = function(value) {
        var width = this._width;

        if ((typeof value !== 'undefined') && (value !== width)) {
            this._width = value;
            this._makeDirty(WIDTH_INDEX);
        }
    };

    /**
    *

    * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
    * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
    * {@link Context#getMaximumAliasedLineWidth}.
    *
    * @type Number
    *
    * @see Polyline#outlineWidth
    * @see Context#getMinimumAliasedLineWidth
    * @see Context#getMaximumAliasedLineWidth
    *
    * @example
    * // 3 pixel total width, 1 pixel interior width
    * polyline.width = 1.0;
    * polyline.outlineWidth = 3.0;
     */
    Polyline.prototype.getOutlineWidth = function() {
        return this._outlineWidth;
    };

    /**
    *

    * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
    * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
    * {@link Context#getMaximumAliasedLineWidth}.
     *
    * @type Number
     *
    * @see Polyline#outlineWidth
    * @see Context#getMinimumAliasedLineWidth
    * @see Context#getMaximumAliasedLineWidth
    *
    * @example
    * // 3 pixel total width, 1 pixel interior width
    * polyline.width = 1.0;
    * polyline.outlineWidth = 3.0;
    */
    Polyline.prototype.setOutlineWidth = function(value) {
        var width = this._outlineWidth;

        if ((typeof value !== 'undefined') && (value !== width)) {
            this._outlineWidth = value;
            this._makeDirty(OUTLINE_WIDTH_INDEX);
        }
    };

    /**
    * Returns the outline color of the polyline.
    *
    * @memberof Polyline
    *
    * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
    *
    * @return {Color}
    *
    * @see Polyline#setOutlineColor
    */
    Polyline.prototype.getOutlineColor = function() {
        return this._outlineColor;
    };

    /**
     * Returns the outline color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @return {Color}
     *
     * @see Polyline#setOutlineColor
     */
    Polyline.prototype.setOutlineColor = function(value) {
        var c = this._outlineColor;

        if ((typeof value !== 'undefined') && ((c.red !== value.red) || (c.green !== value.green) || (c.blue !== value.blue) || (c.alpha !== value.alpha))) {
            this._outlineColor = new Color(value.red, value.green, value.blue, value.alpha);
            this._makeDirty(OUTLINE_COLOR_INDEX);
        }
    };

    Polyline.prototype.getPickId = function(context) {
        this._pickId = this._pickId || context.createPickId(this._pickIdThis || this);
        return this._pickId;
    };

    Polyline.prototype._clean = function() {
        this._dirty = false;
        var properties = this._propertiesChanged;
        for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) {
            properties[k] = 0;
        }
    };

    Polyline.prototype._getCollection = function() {
        return this._collection;
    };

    Polyline.prototype._getChangedProperties = function() {
        return this._propertiesChanged;
    };

    Polyline.prototype._makeDirty = function(propertyChanged) {
        ++this._propertiesChanged[propertyChanged];
        var c = this._collection;
        if (c) {
            c._updatePolyline(propertyChanged, this);
            this._dirty = true;
        }
    };

    Polyline.prototype._getPositions2D = function(){
        var segments = this._segments;
        var positions = [];
        var numberOfSegments = segments.length;

        for ( var i = 0; i < numberOfSegments; ++i) {
            var segment = segments[i];
            var segmentLength = segment.length;
            for (var n = 0; n < segmentLength; ++n) {
                positions.push( segment[n].cartesian);
            }
        }
        return positions;

    };

    Polyline.prototype._createSegments = function(ellipsoid){
        return PolylinePipeline.wrapLongitude(ellipsoid, this.getPositions());
    };

    Polyline.prototype._setSegments = function(segments){
        this._segments = segments;
        var numberOfSegments = segments.length;
        var length = 0;
        for ( var i = 0; i < numberOfSegments; ++i) {
            var segment = segments[i];
            var segmentLength = segment.length;
            length += segmentLength;
        }
        return length;
    };

    Polyline.prototype._getSegments = function(){
        return this._segments;
    };

    Polyline.prototype._segmentsLengthChanged = function(newSegments){
        var origSegments = this._segments;
        if (typeof origSegments !== 'undefined') {
            var numberOfSegments = newSegments.length;
            if (numberOfSegments !== origSegments.length) {
                return true;
            }
            for ( var i = 0; i < numberOfSegments; ++i) {
                if (newSegments[i].length !== origSegments[i].length) {
                    return true;
                }
            }
            return false;
        }
        return true;
    };

    Polyline.prototype._destroy = function() {
        this._pickId = this._pickId && this._pickId.destroy();
        this._collection = undefined;
    };

    return Polyline;
});
<commit_msg>Undo whitespace only changes to make reviewing and diffing easier.<commit_after>/*global define*/
define([
        '../Core/DeveloperError',
        '../Core/destroyObject',
        '../Core/BoundingSphere',
        '../Core/Cartesian3',
        '../Core/Color',
        '../Core/PolylinePipeline'
    ], function(
        DeveloperError,
        destroyObject,
        BoundingSphere,
        Cartesian3,
        Color,
        PolylinePipeline) {
    "use strict";

    /**
     *
     * @alias Polyline
     * @internalConstructor
     */
    var Polyline = function(polylineTemplate, polylineCollection) {
        var p = polylineTemplate || {};

        this._positions = typeof p.positions !== 'undefined' ? p.positions : [];
        this._positionsLength = this._positions.length;
        this._show = typeof p.show === 'undefined' ? true : p.show;
        this._width = typeof p.width === 'undefined' ? 1.0 : p.width;
        this._outlineWidth = typeof p.outlineWidth === 'undefined' ? 0.0 : p.outlineWidth;
        this._color = typeof p.color === 'undefined' ? new Color(1.0, 1.0, 1.0, 1.0) : Color.clone(p.color);
        this._outlineColor = (typeof p.outlineColor === 'undefined') ? new Color(1.0, 1.0, 1.0, 1.0) : Color.clone(p.outlineColor);
        this._propertiesChanged = new Uint32Array(NUMBER_OF_PROPERTIES);
        this._collection = polylineCollection;
        this._dirty = false;
        this._pickId = undefined;
        this._pickIdThis = p._pickIdThis;
        this._segments = undefined;
        this._actualLength = this._positions.length;

        this._boundingVolume = undefined;
        if (this._positionsLength > 0) {
            this._boundingVolume = BoundingSphere.fromPoints(this._positions);
        }
    };

    var SHOW_INDEX = Polyline.SHOW_INDEX = 0;
    var POSITION_INDEX = Polyline.POSITION_INDEX = 1;
    var COLOR_INDEX = Polyline.COLOR_INDEX = 2;
    var OUTLINE_COLOR_INDEX = Polyline.OUTLINE_COLOR_INDEX = 3;
    var WIDTH_INDEX = Polyline.WIDTH_INDEX = 4;
    var OUTLINE_WIDTH_INDEX = Polyline.OUTLINE_WIDTH_INDEX = 5;
    var POSITION_SIZE_INDEX = Polyline.POSITION_SIZE_INDEX = 6;
    Polyline.NUMBER_OF_PROPERTIES = 7;
    var NUMBER_OF_PROPERTIES = Polyline.NUMBER_OF_PROPERTIES;

    /**
     * Returns true if this polyline will be shown.  Call {@link Polyline#setShow}
     * to hide or show a polyline, instead of removing it and re-adding it to the collection.
     *
     * @memberof Polyline
     *
     * @return {Boolean} true if this polyline will be shown; otherwise, false.
     *
     * @see Polyline#setShow
     */
    Polyline.prototype.getShow = function() {
        return this._show;
    };

    /**
     * Determines if this polyline will be shown.  Call this to hide or show a polyline, instead
     * of removing it and re-adding it to the collection.
     *
     * @memberof Polyline
     *
     * @param {Boolean} value Indicates if this polyline will be shown.
     *
     * @see Polyline#getShow
     */
    Polyline.prototype.setShow = function(value) {
        if ((typeof value !== 'undefined') && (this._show !== value)) {
            this._show = value;
            this._makeDirty(SHOW_INDEX);
                }
    };

    /**
     * Returns the polyline's positions.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see Polyline#setPositions
     */
    Polyline.prototype.getPositions = function() {
        return this._positions;
    };

    /**
    * Defines the positions of the polyline.
    *
    * @memberof Polyline
    *
    * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
    * @see Polyline#getPositions
    *
    * @example
    * polyline.setPositions(
    *   ellipsoid.toCartesians(new Cartographic3(...),
    *                          new Cartographic3(...),
    *                          new Cartographic3(...))
    * );
     */
    Polyline.prototype.setPositions = function(positions) {
        if (typeof positions === 'undefined') {
            positions = [];
        }
        if (this._positionsLength !== positions.length) {
            this._positionsLength = positions.length;
            this._makeDirty(POSITION_SIZE_INDEX);
        }
        this._positions = positions;

        if (this._positionsLength > 0) {
            this._boundingVolume = BoundingSphere.fromPoints(this._positions);
        } else {
            this._boundingVolume = undefined;
        }
        this._makeDirty(POSITION_INDEX);
    };

    /**
     * Returns the color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @return {Color}
     *
     * @see Polyline#setColor
     */
    Polyline.prototype.getColor = function() {
        return this._color;
    };

        /**
     * Sets the color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @param {Color} value. The color of the polyline.
         *
     * @see Polyline#getColor
         */
    Polyline.prototype.setColor = function(value) {
        var c = this._color;

        if ((typeof value !== 'undefined') && ((c.red !== value.red) || (c.green !== value.green) || (c.blue !== value.blue) || (c.alpha !== value.alpha))) {
            this._color = new Color(value.red, value.green, value.blue, value.alpha);
            this._makeDirty(COLOR_INDEX);
            }
        };

        /**
         *

         * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
         * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
         * {@link Context#getMaximumAliasedLineWidth}.
         *
         * @type Number
         *
    * @see Polyline#width
         * @see Context#getMinimumAliasedLineWidth
         * @see Context#getMaximumAliasedLineWidth
         *
         * @example
         * // 3 pixel total width, 1 pixel interior width
         * polyline.width = 1.0;
         * polyline.outlineWidth = 3.0;
         */
    Polyline.prototype.getWidth = function() {
        return this._width;
    };

        /**
         *

         * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
         * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
         * {@link Context#getMaximumAliasedLineWidth}.
         *
         * @type Number
         *
         * @see Polyline#width
         * @see Context#getMinimumAliasedLineWidth
         * @see Context#getMaximumAliasedLineWidth
         *
         * @example
         * // 3 pixel total width, 1 pixel interior width
         * polyline.width = 1.0;
         * polyline.outlineWidth = 3.0;
         */
    Polyline.prototype.setWidth = function(value) {
        var width = this._width;

        if ((typeof value !== 'undefined') && (value !== width)) {
            this._width = value;
            this._makeDirty(WIDTH_INDEX);
        }
        };

        /**
    *

    * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
    * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
    * {@link Context#getMaximumAliasedLineWidth}.
         *
    * @type Number
    *
    * @see Polyline#outlineWidth
    * @see Context#getMinimumAliasedLineWidth
    * @see Context#getMaximumAliasedLineWidth
     *
    * @example
    * // 3 pixel total width, 1 pixel interior width
    * polyline.width = 1.0;
    * polyline.outlineWidth = 3.0;
         */
    Polyline.prototype.getOutlineWidth = function() {
        return this._outlineWidth;
        };

        /**
    *

    * The actual width used is clamped to the minimum and maximum width supported by the WebGL implementation.
    * These can be queried with {@link Context#getMinimumAliasedLineWidth} and
    * {@link Context#getMaximumAliasedLineWidth}.
         *
    * @type Number
         *
    * @see Polyline#outlineWidth
    * @see Context#getMinimumAliasedLineWidth
    * @see Context#getMaximumAliasedLineWidth
         *
         * @example
    * // 3 pixel total width, 1 pixel interior width
    * polyline.width = 1.0;
    * polyline.outlineWidth = 3.0;
         */
    Polyline.prototype.setOutlineWidth = function(value) {
        var width = this._outlineWidth;

        if ((typeof value !== 'undefined') && (value !== width)) {
            this._outlineWidth = value;
            this._makeDirty(OUTLINE_WIDTH_INDEX);
            }
        };

        /**
     * Returns the outline color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @return {Color}
     *
     * @see Polyline#setOutlineColor
     */
    Polyline.prototype.getOutlineColor = function() {
        return this._outlineColor;
    };

    /**
     * Returns the outline color of the polyline.
     *
     * @memberof Polyline
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @return {Color}
     *
     * @see Polyline#setOutlineColor
     */
    Polyline.prototype.setOutlineColor = function(value) {
        var c = this._outlineColor;

        if ((typeof value !== 'undefined') && ((c.red !== value.red) || (c.green !== value.green) || (c.blue !== value.blue) || (c.alpha !== value.alpha))) {
            this._outlineColor = new Color(value.red, value.green, value.blue, value.alpha);
            this._makeDirty(OUTLINE_COLOR_INDEX);
        }
    };

    Polyline.prototype.getPickId = function(context) {
        this._pickId = this._pickId || context.createPickId(this._pickIdThis || this);
        return this._pickId;
    };

    Polyline.prototype._clean = function() {
        this._dirty = false;
        var properties = this._propertiesChanged;
        for ( var k = 0; k < NUMBER_OF_PROPERTIES - 1; ++k) {
            properties[k] = 0;
        }
    };

    Polyline.prototype._getCollection = function() {
        return this._collection;
    };

    Polyline.prototype._getChangedProperties = function() {
        return this._propertiesChanged;
    };

    Polyline.prototype._makeDirty = function(propertyChanged) {
        ++this._propertiesChanged[propertyChanged];
        var c = this._collection;
        if (c) {
            c._updatePolyline(propertyChanged, this);
            this._dirty = true;
        }
    };

    Polyline.prototype._getPositions2D = function(){
        var segments = this._segments;
        var positions = [];
        var numberOfSegments = segments.length;

        for ( var i = 0; i < numberOfSegments; ++i) {
            var segment = segments[i];
            var segmentLength = segment.length;
            for (var n = 0; n < segmentLength; ++n) {
                positions.push( segment[n].cartesian);
            }
        }
        return positions;

    };

    Polyline.prototype._createSegments = function(ellipsoid){
        return PolylinePipeline.wrapLongitude(ellipsoid, this.getPositions());
    };

    Polyline.prototype._setSegments = function(segments){
        this._segments = segments;
        var numberOfSegments = segments.length;
        var length = 0;
        for ( var i = 0; i < numberOfSegments; ++i) {
            var segment = segments[i];
            var segmentLength = segment.length;
            length += segmentLength;
        }
        return length;
    };

    Polyline.prototype._getSegments = function(){
        return this._segments;
    };

    Polyline.prototype._segmentsLengthChanged = function(newSegments){
        var origSegments = this._segments;
        if (typeof origSegments !== 'undefined') {
            var numberOfSegments = newSegments.length;
            if (numberOfSegments !== origSegments.length) {
                return true;
            }
            for ( var i = 0; i < numberOfSegments; ++i) {
                if (newSegments[i].length !== origSegments[i].length) {
                    return true;
                }
            }
            return false;
        }
        return true;
    };

    Polyline.prototype._destroy = function() {
        this._pickId = this._pickId && this._pickId.destroy();
        this._collection = undefined;
    };

    return Polyline;
});
<|endoftext|>


<commit_before>'use strict';

var m = require('mithril');

var Fangorn = require('js/fangorn').Fangorn;

// Define Fangorn Button Actions
var _figshareItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        if (tb.options.placement !== 'fileview') {
            // If File and FileRead are not defined dropzone is not supported and neither is uploads
            if (window.File && window.FileReader && item.data.permissions && item.data.permissions.edit && item.kind === 'folder') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._uploadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-upload',
                        className: 'text-success'
                    }, 'Upload')
                );
            }
            if (item.kind === 'file' && item.data.extra && item.data.extra.status === 'public') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._downloadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-download',
                        className: 'text-primary'
                    }, 'Download')
                );
            }
            // All files are viewable on the OSF.
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._gotoFileEvent.call(tb, item);
                        },
                        icon: 'fa fa-file-o',
                        className: 'text-info'
                    }, 'View'));
            }

            // Files can be deleted if private or if it is in a dataset that contains more than one file
            var privateOrSiblings = (item.data.extra && item.data.extra.status !== 'public') ||
                (!item.parent().data.isAddonRoot && item.parent().children.length > 1);
            if (item.kind === 'file' && privateOrSiblings && item.data.permissions && item.data.permissions.edit) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._removeEvent.call(tb, event, tb.multiselected());
                        },
                        icon: 'fa fa-trash',
                        className: 'text-danger'
                    }, 'Delete')
                );
            }

            // Files are only viewable on figshare if they are public
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view && item.data.extra.status === 'public') {
                buttons.push(
                    m('a.text-info.fangorn-toolbar-icon', {href: item.data.extra.webView}, [
                        m('i.fa.fa-external-link'),
                        m('span', 'View on figshare')
                    ])
                );
            }
        }
        return m('span', buttons); // Tell fangorn this function is used.
    }
};

Fangorn.config.figshare = {
    // Fangorn options are called if functions, so return a thunk that returns the column builder
    itemButtons: _figshareItemButtons
};
<commit_msg>figshare fangorn: enable download for all files and folders<commit_after>'use strict';

var m = require('mithril');

var Fangorn = require('js/fangorn').Fangorn;

// Define Fangorn Button Actions
var _figshareItemButtons = {
    view: function (ctrl, args, children) {
        var buttons = [];
        var tb = args.treebeard;
        var item = args.item;
        if (tb.options.placement !== 'fileview') {
            // If File and FileRead are not defined dropzone is not supported and neither is uploads
            if (window.File && window.FileReader && item.data.permissions && item.data.permissions.edit && item.kind === 'folder') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._uploadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-upload',
                        className: 'text-success'
                    }, 'Upload')
                );
            }

            // Download file or Download-as-zip
            if (item.kind === 'file') {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._downloadEvent.call(tb, event, item);
                        },
                        icon: 'fa fa-download',
                        className: 'text-primary'
                    }, 'Download')
                );
            }
            else {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) { Fangorn.ButtonEvents._downloadZipEvent.call(tb, event, item); },
                        icon: 'fa fa-download',
                        className: 'text-primary'
                    }, 'Download as zip')
                );
            }

            // All files are viewable on the OSF.
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._gotoFileEvent.call(tb, item);
                        },
                        icon: 'fa fa-file-o',
                        className: 'text-info'
                    }, 'View'));
            }

            // Files can be deleted if private or if it is in a dataset that contains more than one file
            var privateOrSiblings = (item.data.extra && item.data.extra.status !== 'public') ||
                (!item.parent().data.isAddonRoot && item.parent().children.length > 1);
            if (item.kind === 'file' && privateOrSiblings && item.data.permissions && item.data.permissions.edit) {
                buttons.push(
                    m.component(Fangorn.Components.button, {
                        onclick: function (event) {
                            Fangorn.ButtonEvents._removeEvent.call(tb, event, tb.multiselected());
                        },
                        icon: 'fa fa-trash',
                        className: 'text-danger'
                    }, 'Delete')
                );
            }

            // Files are only viewable on figshare if they are public
            if (item.kind === 'file' && item.data.permissions && item.data.permissions.view && item.data.extra.status === 'public') {
                buttons.push(
                    m('a.text-info.fangorn-toolbar-icon', {href: item.data.extra.webView}, [
                        m('i.fa.fa-external-link'),
                        m('span', 'View on figshare')
                    ])
                );
            }
        }
        return m('span', buttons); // Tell fangorn this function is used.
    }
};

Fangorn.config.figshare = {
    // Fangorn options are called if functions, so return a thunk that returns the column builder
    itemButtons: _figshareItemButtons
};
<|endoftext|>


<commit_before>'use strict'

const MobileUser = require('../models/mobileUser.model')
const getMobileUser = require('../services/getMobileUser.service')
const _ = require('lodash')

module.exports = {
  getAllMobileUsers: (req, res) => {
    MobileUser.find((err, mobileUsers) => {
      if (err) throw err
      console.log("MOBILE USERS", mobileUsers);
      res.send(mobileUsers)
    })
  },
  invite: (req, res) => {
    console.log("TRYING TO INVITE MOBILE USER", req.body)
    MobileUser.findById(req.body.mobileUserId)
      .populate('invitations')
      .exec((err, mobileUser) => {
        // console.log("MOBILE USER:", mobileUser)
        console.log("req.body.adminId", req.body.adminId.toString());
        // console.log("mobileUser.invitations", mobileUser.invitations);
        let pendingInvitations = mobileUser.invitations
        // console.log("pendingInvitation", pendingInvitations);
        console.log("req.body.adminId:", req.body.adminId);
        // console.log("pendingInvitations", pendingInvitations)
        let idOfInvite = req.body.adminId
        let inviteExists = _.some(pendingInvitations, {adminId: idOfInvite})
        if (inviteExists) {
          console.log("ALREADY EXISTS IN INVITE OR CLOCKS COLLECTION - NOT ADDING");
          res.send('already exists')
        } else {
          mobileUser.invitations.push(req.user)
          mobileUser.save((err) => {
            if (err) throw err
            res.send('success')
          })
        }
    })
  },
  getSingleMobileUser: (req, res) => {
    console.log("TRYING TO GET SINGLE MOBILE USER", req.user)
    getMobileUser(req, res)
    // MobileUser.findById(req.user, (err, mobileUser) => {
    //   if (err) throw err
      // console.log("MOBILE USER:", mobileUser)
      // console.log(mobileUser.invitations);
      // mobileUser.invitations.push(req.body.adminId)
      // mobileUser.save((err) => {
      // })

    // getMobileUser(req, res)

  },
  acceptInvite: (req, res) => {
    MobileUser.findByIdAndUpdate(req.user,
      {
        $pull: {
          invitations: req.body.inviteId
        }
      }, (err, data) => {
        if (err) throw err
        console.log("UPDATED DATA:", data)
        res.send(data)
      })

//     MobileUser.findById(req.user)
//     .populate('invitations')
//     .populate('clocks')
//     .exec((err, mobileUser) => {
//       if (err) throw err
//       console.log("GOT MOBILE USER DATA:", mobileUser)
//       let clockList = mobileUser.clocks
//       console.log("clockList", clockList)
//       //add clock to clockList
//       mobileUser.clocks.push(req.body.inviteId)

//       _.remove(mobileUser.invitations, ((invitation) => {
//         return invitation._id.toString() === req.body.inviteId;
// }     ))

//       // mobileUser.invitations.id(req.body.inviteId).remove()
//       mobileUser.save((err, updatedUserData) => {
//         if (err) throw err
//         console.log("UPDATED USER DATA", updatedUserData)
//         res.send(updatedUserData.invitations)
//       })

      //find and delete clock from invitations:

      // console.log("req.body.inviteId", typeof req.body.inviteId);
      // console.log("already have this one?:", _.some(clockList, {_id: req.body.inviteId}))

    // })

    // console.log("TRYING TO ACCEPT INVITE", req.user)
    // MobileUser.findOne({"_id": req.user}, (err, mobileUser) => {
    //   if (err) throw err
    //   console.log("FOUND MOBILE LOGGED IN MOBILE USER", mobileUser);
    // })

    // MobileUser.findById(req.user, (err, mobileUser) => {
    //   if (err) throw err
    //   mobileUser.clocks.push(req.body.inviteId)
    //   mobileUser.save((err, updatedUserData) => {
    //     if (err) throw err
    //     console.log("UPDATED USER DATA", updatedUserData)
    //     getMobileUser(req, res)

    //   })
    // })
  }
}
<commit_msg>fixed matching bug in invitations collection<commit_after>'use strict'

const MobileUser = require('../models/mobileUser.model')
const getMobileUser = require('../services/getMobileUser.service')
const _ = require('lodash')
const mongoose = require('mongoose')

module.exports = {
  getAllMobileUsers: (req, res) => {
    MobileUser.find((err, mobileUsers) => {
      if (err) throw err
      console.log("MOBILE USERS", mobileUsers);
      res.send(mobileUsers)
    })
  },
  invite: (req, res) => {
    console.log("TRYING TO INVITE MOBILE USER", req.body)
    console.log("REQ.USER", req.user)
    MobileUser.findById(req.body.mobileUserId)
      .populate('invitations')
      .populate('clocks')
      .exec((err, mobileUser) => {
        let pendingInvitations = mobileUser.invitations
        let clockList = mobileUser.clocks
        console.log("req.body.adminId:", req.body.adminId);
        // console.log("CLOCK LIST:", clockList);
        let idOfInvite = req.body.adminId
        let inviteExists = _.some(pendingInvitations, {_id: mongoose.Types.ObjectId(idOfInvite)})
        let clockExists = _.some(clockList, {_id: mongoose.Types.ObjectId(idOfInvite)})
        clockList.forEach((clock) => {
          console.log("clock.adminId", clock.adminId);
          console.log("clock._id", clock._id)
          console.log("idOfInvite", idOfInvite)
          console.log("equal?", clock._id == idOfInvite)
        })
        console.log("CLOCK EXISTS:", clockExists);
        if (inviteExists || clockExists) {
          console.log("ALREADY EXISTS IN INVITE OR CLOCKS COLLECTION - NOT ADDING");
          res.send('already exists')
        } else {
          "ADDING INVITATION"
          mobileUser.invitations.push(req.user)
          mobileUser.save((err) => {
            if (err) throw err
            res.send('success')
          })
        }
    })
  },
  getSingleMobileUser: (req, res) => {
    console.log("TRYING TO GET SINGLE MOBILE USER", req.user)
    getMobileUser(req, res)
  },
  acceptInvite: (req, res) => {
    MobileUser.findByIdAndUpdate(req.user,
      {
        $pull: {
          invitations: req.body.inviteId
        }
      }, (err, mobileUser) => {
        if (err) throw err
        // console.log("UPDATED DATA:", data)
        mobileUser.clocks.push(req.body.inviteId)
        mobileUser.save((err, updatedUserData) => {
          if (err) throw err
          console.log("UPDATED USER DATA", updatedUserData)
          res.send(updatedUserData)
        })
      })
  }
}
<|endoftext|>


<commit_before>module.exports = (function(){

	// GET /users/:id/media?lat=<LAT>&lng=<LNG>&time=<TIME>
	return function* collection(id) {
    var Q = require('q');
    var TwitterManager = require('../media/twitter');
    var InstagramManager = require('../media/instagram');

    // Twitter Requests
    var twitterDef = Q.defer();
    var twitterGranuals = twitterDef.promise
                          .then(TwitterManager.search);

    // Instagram Requests
    var instagramDef = Q.defer();
    var instagramGranuals = instagramDef.promise
                            .then(InstagramManager.search);

    // Flickr Requests
    // var FlickrManager = require('../media/flickr');
    // var flickrGranuals = yield FlickrManager.search(this.request.url);

    // Creating a universal capsul object
    var capsul = {
      "user_id": id,
      "latitude": require('../../helpers').paramsForUrl(this.request.url).lat,
      "longitude": require('../../helpers').paramsForUrl(this.request.url).lng,
      "timestamp": require('../../helpers').paramsForUrl(this.request.url).time,
      "data": []
    }

    twitterDef.resolve(this.request.url)
    instagramDef.resolve(this.request.url)

    capsul.data.push(twitterGranuals);
    capsul.data.push(instagramGranuals);

		this.body = yield capsul;
	}
})();<commit_msg>Create two promises per social media request. Heroku deployment.<commit_after>module.exports = (function(){

	// GET /users/:id/media?lat=<LAT>&lng=<LNG>&time=<TIME>
	return function* collection(id) {
    var Q = require('q');
    var TwitterManager = require('../media/twitter');
    var InstagramManager = require('../media/instagram');

    // Twitter Requests
    var twitterDef = Q.defer();
    var twitterGranuals = twitterDef.promise
                          .then(TwitterManager.search)
    twitterDef.resolve(this.request.url)

    // Instagram Requests
    var instagramDef = Q.defer();
    var instagramGranuals = instagramDef.promise
                            .then(InstagramManager.search)
    instagramDef.resolve(this.request.url)

    // Flickr Requests
    // var FlickrManager = require('../media/flickr');
    // var flickrGranuals = yield FlickrManager.search(this.request.url);

    // Creating a universal capsul object
    var capsul = {
      user_id: id,
      latitude: require('../../helpers').paramsForUrl(this.request.url).lat,
      longitude: require('../../helpers').paramsForUrl(this.request.url).lng,
      timestamp: require('../../helpers').paramsForUrl(this.request.url).time,
      data: []
    }

    capsul.data.push(instagramGranuals);
    capsul.data.push(twitterGranuals);

    this.body = yield capsul;
  }
})();<|endoftext|>


<commit_before>export { ConcatGather };
export { ConcatGatherPool };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import { ShuffleInfo, ShuffleInfoPool } from "./ChannelShuffler_ShuffleInfo.js";

/**
 * Implement the channel shuffler by tf.concat() and tf.gather().
 *
 * When outputGroupCount is smaller (e.g. 2), this may be faster than concat-reshape-transpose-reshape-split and
 * split-concat because the total operations (and memory access) are smaller.
 *
 * The extra cost is a pre-built channel index look up table (with tensor1d).
 *
 *
 * @member {number[]} concatenatedShape
 *   (Please see ShuffleInfo explanation.)
 *
 * @member {number} outputGroupCount
 *   (Please see ShuffleInfo explanation.)
 *
 * @member {ShuffleInfo} shuffleInfo
 *   The information calculated from concatenatedShape and outputGroupCount.
 *
 * @member {tf.tensor1d[]} shuffledChannelIndicesTensor1dArray
 *   The look up table for tf.gather()'s channel index. This table is composed of tensor1d so should be released
 * by calling disposeResources().
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputFloat32Array and used in tensors. Not including Params, because they are not used in
 * tensors. Not including inferenced weights (even if they are used in tensors), because they are not extracted from inputFloat32Array.
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Not including Params, because they are not used in tensors. Including inferenced
 * weights, if they are used in tensors.
 *
 * @member {function} gather
 *   Permute and split the input tensor by gather. It is a function pointer to one of this.gather_XXX().
 *
 * @member {function} concatGather
 *   Concatenate, permute and split the input tensor by concat-gather. It is a function pointer to one of
 * this.concatGather_XXX().
 */
class ConcatGather extends Recyclable.Root {

  /**
   *
   * @param {number[]} concatenatedShape  Used to calculate shuffleInfo.
   * @param {number}   outputGroupCount   Used to calculate shuffleInfo.
   * @exception {Object} If failed (e.g. out of GPU memory).
   *
   * @see ShuffleInfo
   */
  constructor( concatenatedShape, outputGroupCount ) {
    ConcatGather.setAsConstructor.call( this, concatenatedShape, outputGroupCount );
  }

  /**
   *
   * @param {ShuffleInfo} this
   *   The object to be initialized.
   *
   * @param {number[]} concatenatedShape  Used to calculate shuffleInfo.
   * @param {number}   outputGroupCount   Used to calculate shuffleInfo.
   * @exception {Object} If failed (e.g. out of GPU memory).
   *
   * @return {ConcatGather}
   *   Return the this object.
   *
   * @see ShuffleInfo
   */
  static setAsConstructor( concatenatedShape, outputGroupCount ) {

    this.tensorWeightCountExtracted = 0;
    this.tensorWeightCountTotal = 0;

    this.shuffleInfo = ShuffleInfoPool.Singleton.get_or_create_by( concatenatedShape, outputGroupCount );

    // Build shuffled channel index table (as an array of tf.tensor1d).
    //
    // It can be used by algorithm ConcatGather().
    // They should be integers so that can be used as tf.gather()'s index.
    //
    // Not like SplitConcat, the channel indexes will not be sorted here. According to testing, sorted
    // channel seems slow down memory access when using them as tf.gather()'s index list.
    {
      this.shuffledChannelIndicesTensor1dArray
        = tf.tidy( "ChannelShuffler.ConcatGather.init.shuffledChannelIndicesTensor1dArray", () => {
          let channelIndices = tf.range( 0, this.shuffleInfo.totalChannelCount, 1, "int32" );
          return ShuffleInfoPool.Singleton.sessionCall( () => {
            let channelIndicesShuffleInfo = ShuffleInfoPool.Singleton.get_or_create_by( channelIndices.shape, outputGroupCount );
            return channelIndicesShuffleInfo.reshapeTransposeReshapeSplit( channelIndices );
          });
        });

      // Calculate total weight count.
      for ( let i = 0; i < this.shuffledChannelIndicesTensor1dArray.length; ++i ) {
        let shuffledChannelIndicesTensor1d = this.shuffledChannelIndicesTensor1dArray[ i ];
        if ( shuffledChannelIndicesTensor1d ) {
          this.tensorWeightCountTotal += shuffledChannelIndicesTensor1d.size;
        }
      }

    // Exception if failed (e.g. out of (GPU) memory).
    }

    this.gather = this.gather_loop;
    this.concatGather = this.concatGather_dispose_finally_call_loop;

    return this;
  }

  /**
   * Release tf.tensor.
   *
   * Sub-class should override this method (and call super.disposeResources() before return).
   */
  disposeResources() {
    this.concatGather = null;
    this.gather = null;

    this.tensorWeightCountTotal = 0;
    this.tensorWeightCountExtracted = 0;

    if ( this.shuffledChannelIndicesTensor1dArray ) {
      for ( let i = 0; i < this.shuffledChannelIndicesTensor1dArray.length; ++i ) {
        tf.dispose( this.shuffledChannelIndicesTensor1dArray[ i ] );
        this.shuffledChannelIndicesTensor1dArray[ i ] = null;
      }

//!!! (2022/06/25 Remarked) Now only Recyclable.Array could be recycled.
//      // Note: This array is generated by tensorflow.js (i.e. not by Pool.Array). Although it could be recycled by Pool.Array,
//      //       however, this could result in more and more array being cumulated (and then out of memory). So do not recycle it.
//      //
//      //Pool.Array.Singleton.recycle( this.shuffledChannelIndicesTensor1dArray );

      this.shuffledChannelIndicesTensor1dArray = null;
    }

    if ( this.shuffleInfo ) {
      this.shuffleInfo.disposeResources_and_recycleToPool();
      this.shuffleInfo = null;
    }

    //super.disposeResources();
  }

//!!! (2022/06/25 Remarked) Inherits from Recyclable.Base instead.
//   /**
//    * After calling this method, this object should be viewed as disposed and should not be operated again.
//    *
//    * Sub-class should override this method for recycling to its pool (and NEVER call super.disposeResources_and_recycleToPool()).
//    */
//   disposeResources_and_recycleToPool() {
//     this.disposeResources();
//     ConcatGatherPool.Singleton.recycle( this );
//   }

  get concatenatedShape() {
    return this.shuffleInfo.concatenatedShape;
  }

  get outputGroupCount() {
    return this.shuffleInfo.outputGroupCount;
  }

  /**
   * Permute and split the input tensor by gather.
   *
   * @param {tf.tensor} concatenatedTensor
   *   An single tensor (not array) to be processed. It should conform to this.shuffleInfo.concatenatedShape.
   *
   * @return {tf.tensor[]}
   *   An array of shuffled tensors. Their total channel count is the same as concatenated tensorArray, but their
   * last dimensions are shuffled.
   */
  gather_loop( concatenatedTensor ) {
    let shuffledSplitedTensorArray = new Array( this.shuffledChannelIndicesTensor1dArray.length );
    for ( let i = 0; i < shuffledSplitedTensorArray.length; ++i ) {
      // shuffle and split by gather (one operation achieves two operations).
      shuffledSplitedTensorArray[ i ] = concatenatedTensor.gather( this.shuffledChannelIndicesTensor1dArray[ i ], this.shuffleInfo.lastAxisId );
    }
    return shuffledSplitedTensorArray;
  }

  /**
   * Concatenate, permute and split the input tensor by concat-gather.
   *
   * @param {tf.tensor[]} tensorArray
   *   An array of tensors to be processed. It should conform to this.concatenatedShape.
   *
   * @return {tf.tensor[]}
   *   An array of shuffled tensors. Their total channel count is the same as concatenated tensorArray, but their
   * last dimensions are shuffled.
   */
  concatGather_dispose_finally_call_loop( tensorArray ) {
    let concatenatedTensor = tf.concat( tensorArray, this.shuffleInfo.lastAxisId );

    try {
      return this.gather_loop( concatenatedTensor );

    } finally {
      concatenatedTensor.dispose();
    }
  }
}

/**
 * Providing ChannelShuffler.ConcatGather
 *
 */
class ConcatGatherPool extends Pool.Root {

  constructor() {
    super( "ChannelShuffler.ConcatGatherPool", ConcatGather, ConcatGather.setAsConstructor );
  }

}

/**
 * Used as default ChannelShuffler.ConcatGather provider for conforming to Recyclable interface.
 */
ConcatGather.Pool = new ConcatGatherPool();
<commit_msg>Update ChannelShuffler_ConcatGather.js<commit_after>export { ConcatGather };
export { ConcatGatherPool };

import * as Pool from "../../util/Pool.js";
import * as Recyclable from "../../util/Recyclable.js";
import { ShuffleInfo, ShuffleInfoPool } from "./ChannelShuffler_ShuffleInfo.js";

/**
 * Implement the channel shuffler by tf.concat() and tf.gather().
 *
 * When outputGroupCount is smaller (e.g. 2), this may be faster than concat-reshape-transpose-reshape-split and
 * split-concat because the total operations (and memory access) are smaller.
 *
 * The extra cost is a pre-built channel index look up table (with tensor1d).
 *
 *
 * @member {number[]} concatenatedShape
 *   (Please see ShuffleInfo explanation.)
 *
 * @member {number} outputGroupCount
 *   (Please see ShuffleInfo explanation.)
 *
 * @member {ShuffleInfo} shuffleInfo
 *   The information calculated from concatenatedShape and outputGroupCount.
 *
 * @member {tf.tensor1d[]} shuffledChannelIndicesTensor1dArray
 *   The look up table for tf.gather()'s channel index. This table is composed of tensor1d so should be released
 * by calling disposeResources().
 *
 * @member {number} tensorWeightCountExtracted
 *   The wieght count extracted from inputFloat32Array and used in tensors. Not including Params, because they are not used in
 * tensors. Not including inferenced weights (even if they are used in tensors), because they are not extracted from inputFloat32Array.
 *
 * @member {number} tensorWeightCountTotal
 *   The total wieght count used in tensors. Not including Params, because they are not used in tensors. Including inferenced
 * weights, if they are used in tensors.
 *
 * @member {function} gather
 *   Permute and split the input tensor by gather. It is a function pointer to one of this.gather_XXX().
 *
 * @member {function} concatGather
 *   Concatenate, permute and split the input tensor by concat-gather. It is a function pointer to one of
 * this.concatGather_XXX().
 */
class ConcatGather extends Recyclable.Root {

  /**
   *
   * @param {number[]} concatenatedShape  Used to calculate shuffleInfo.
   * @param {number}   outputGroupCount   Used to calculate shuffleInfo.
   * @exception {Object} If failed (e.g. out of GPU memory).
   *
   * @see ShuffleInfo
   */
  constructor( concatenatedShape, outputGroupCount ) {
    ConcatGather.setAsConstructor.call( this, concatenatedShape, outputGroupCount );
  }

  /**
   *
   * @param {ShuffleInfo} this
   *   The object to be initialized.
   *
   * @param {number[]} concatenatedShape  Used to calculate shuffleInfo.
   * @param {number}   outputGroupCount   Used to calculate shuffleInfo.
   * @exception {Object} If failed (e.g. out of GPU memory).
   *
   * @return {ConcatGather}
   *   Return the this object.
   *
   * @see ShuffleInfo
   */
  static setAsConstructor( concatenatedShape, outputGroupCount ) {

    this.tensorWeightCountExtracted = 0;
    this.tensorWeightCountTotal = 0;

    this.shuffleInfo = ShuffleInfoPool.Singleton.get_or_create_by( concatenatedShape, outputGroupCount );

    // Build shuffled channel index table (as an array of tf.tensor1d).
    //
    // It can be used by algorithm ConcatGather().
    // They should be integers so that can be used as tf.gather()'s index.
    //
    // Not like SplitConcat, the channel indexes will not be sorted here. According to testing, sorted
    // channel seems slow down memory access when using them as tf.gather()'s index list.
    {
      this.shuffledChannelIndicesTensor1dArray
        = tf.tidy( "ChannelShuffler.ConcatGather.init.shuffledChannelIndicesTensor1dArray", () => {
          let channelIndices = tf.range( 0, this.shuffleInfo.totalChannelCount, 1, "int32" );
          return Pool.All.sessionCall( () => {
            let channelIndicesShuffleInfo = ShuffleInfoPool.Singleton.get_or_create_by( channelIndices.shape, outputGroupCount );
            return channelIndicesShuffleInfo.reshapeTransposeReshapeSplit( channelIndices );
          });
        });

      // Calculate total weight count.
      for ( let i = 0; i < this.shuffledChannelIndicesTensor1dArray.length; ++i ) {
        let shuffledChannelIndicesTensor1d = this.shuffledChannelIndicesTensor1dArray[ i ];
        if ( shuffledChannelIndicesTensor1d ) {
          this.tensorWeightCountTotal += shuffledChannelIndicesTensor1d.size;
        }
      }

    // Exception if failed (e.g. out of (GPU) memory).
    }

    this.gather = this.gather_loop;
    this.concatGather = this.concatGather_dispose_finally_call_loop;

    return this;
  }

  /**
   * Release tf.tensor.
   *
   * Sub-class should override this method (and call super.disposeResources() before return).
   */
  disposeResources() {
    this.concatGather = null;
    this.gather = null;

    this.tensorWeightCountTotal = 0;
    this.tensorWeightCountExtracted = 0;

    if ( this.shuffledChannelIndicesTensor1dArray ) {
      for ( let i = 0; i < this.shuffledChannelIndicesTensor1dArray.length; ++i ) {
        tf.dispose( this.shuffledChannelIndicesTensor1dArray[ i ] );
        this.shuffledChannelIndicesTensor1dArray[ i ] = null;
      }

//!!! (2022/06/25 Remarked) Now only Recyclable.Array could be recycled.
//      // Note: This array is generated by tensorflow.js (i.e. not by Pool.Array). Although it could be recycled by Pool.Array,
//      //       however, this could result in more and more array being cumulated (and then out of memory). So do not recycle it.
//      //
//      //Pool.Array.Singleton.recycle( this.shuffledChannelIndicesTensor1dArray );

      this.shuffledChannelIndicesTensor1dArray = null;
    }

    if ( this.shuffleInfo ) {
      this.shuffleInfo.disposeResources_and_recycleToPool();
      this.shuffleInfo = null;
    }

    //super.disposeResources();
  }

//!!! (2022/06/25 Remarked) Inherits from Recyclable.Base instead.
//   /**
//    * After calling this method, this object should be viewed as disposed and should not be operated again.
//    *
//    * Sub-class should override this method for recycling to its pool (and NEVER call super.disposeResources_and_recycleToPool()).
//    */
//   disposeResources_and_recycleToPool() {
//     this.disposeResources();
//     ConcatGatherPool.Singleton.recycle( this );
//   }

  get concatenatedShape() {
    return this.shuffleInfo.concatenatedShape;
  }

  get outputGroupCount() {
    return this.shuffleInfo.outputGroupCount;
  }

  /**
   * Permute and split the input tensor by gather.
   *
   * @param {tf.tensor} concatenatedTensor
   *   An single tensor (not array) to be processed. It should conform to this.shuffleInfo.concatenatedShape.
   *
   * @return {tf.tensor[]}
   *   An array of shuffled tensors. Their total channel count is the same as concatenated tensorArray, but their
   * last dimensions are shuffled.
   */
  gather_loop( concatenatedTensor ) {
    let shuffledSplitedTensorArray = new Array( this.shuffledChannelIndicesTensor1dArray.length );
    for ( let i = 0; i < shuffledSplitedTensorArray.length; ++i ) {
      // shuffle and split by gather (one operation achieves two operations).
      shuffledSplitedTensorArray[ i ] = concatenatedTensor.gather( this.shuffledChannelIndicesTensor1dArray[ i ], this.shuffleInfo.lastAxisId );
    }
    return shuffledSplitedTensorArray;
  }

  /**
   * Concatenate, permute and split the input tensor by concat-gather.
   *
   * @param {tf.tensor[]} tensorArray
   *   An array of tensors to be processed. It should conform to this.concatenatedShape.
   *
   * @return {tf.tensor[]}
   *   An array of shuffled tensors. Their total channel count is the same as concatenated tensorArray, but their
   * last dimensions are shuffled.
   */
  concatGather_dispose_finally_call_loop( tensorArray ) {
    let concatenatedTensor = tf.concat( tensorArray, this.shuffleInfo.lastAxisId );

    try {
      return this.gather_loop( concatenatedTensor );

    } finally {
      concatenatedTensor.dispose();
    }
  }
}

/**
 * Providing ChannelShuffler.ConcatGather
 *
 */
class ConcatGatherPool extends Pool.Root {

  constructor() {
    super( "ChannelShuffler.ConcatGatherPool", ConcatGather, ConcatGather.setAsConstructor );
  }

}

/**
 * Used as default ChannelShuffler.ConcatGather provider for conforming to Recyclable interface.
 */
ConcatGather.Pool = new ConcatGatherPool();
<|endoftext|>


<commit_before>(function (app) {
    'use strict';

    app.controller('customerEditCtrl', customerEditCtrl);

    customerEditCtrl.$inject = ['$scope', '$modalInstance','$timeout', 'apiService', 'notificationService'];

    function customerEditCtrl($scope, $modalInstance, $timeout, apiService, notificationService) {

        $scope.cancelEdit = cancelEdit;
        $scope.updateCustomer = updateCustomer;

        $scope.openDatePicker = openDatePicker;
        $scope.dateOptions = {
            formatYear: 'yy',
            startingDay: 1
        };
        $scope.datepicker = {};

        function updateCustomer()
        {
            console.log($scope.EditedCustomer);
            apiService.post('/api/customers/update/', $scope.EditedCustomer,
            updateCustomerCompleted,
            updateCustomerLoadFailed);
        }

        function updateCustomerCompleted(response)
        {
            notificationService.displaySuccess($scope.EditedCustomer.FirstName + ' ' + $scope.EditedCustomer.LastName + ' has been updated');
            $scope.EditedCustomer = {};
            $modalInstance.dismiss();
        }

        function updateCustomerLoadFailed(response)
        {
            notificationService.displayError(response.data);
        }

        function cancelEdit() {
            $scope.isEnabled = false;
            $modalInstance.dismiss();
        }

        function openDatePicker($event) {
            $event.preventDefault();
            $event.stopPropagation();

            console.log('test');
            $timeout(function () {
                $scope.datepicker.opened = true;
            });

        };

    }

})(angular.module('homeCinema'));<commit_msg>fix date picker bug in modal<commit_after>(function (app) {
    'use strict';

    app.controller('customerEditCtrl', customerEditCtrl);

    customerEditCtrl.$inject = ['$scope', '$modalInstance','$timeout', 'apiService', 'notificationService'];

    function customerEditCtrl($scope, $modalInstance, $timeout, apiService, notificationService) {

        $scope.cancelEdit = cancelEdit;
        $scope.updateCustomer = updateCustomer;

        $scope.openDatePicker = openDatePicker;
        $scope.dateOptions = {
            formatYear: 'yy',
            startingDay: 1
        };
        $scope.datepicker = {};

        function updateCustomer()
        {
            console.log($scope.EditedCustomer);
            apiService.post('/api/customers/update/', $scope.EditedCustomer,
            updateCustomerCompleted,
            updateCustomerLoadFailed);
        }

        function updateCustomerCompleted(response)
        {
            notificationService.displaySuccess($scope.EditedCustomer.FirstName + ' ' + $scope.EditedCustomer.LastName + ' has been updated');
            $scope.EditedCustomer = {};
            $modalInstance.dismiss();
        }

        function updateCustomerLoadFailed(response)
        {
            notificationService.displayError(response.data);
        }

        function cancelEdit() {
            $scope.isEnabled = false;
            $modalInstance.dismiss();
        }

        function openDatePicker($event) {
            $event.preventDefault();
            $event.stopPropagation();

            $timeout(function () {
                $scope.datepicker.opened = true;
            });

            $timeout(function () {
                $('ul[datepicker-popup-wrap]').css('z-index', '10000');
            }, 100);

        };

    }

})(angular.module('homeCinema'));<|endoftext|>