<commit_before>const mongoose = require('mongoose');
const AlternativeSchema = require('./alternative');

const Schema = mongoose.Schema;

const QuestionSchema = new Schema({
  genfors: { type: Schema.Types.ObjectId, required: true },
  description: { type: String, required: true },
  date: { type: Date, required: true, default: new Date() },
  active: { type: Boolean, default: true },
  deleted: { type: Boolean, required: true, default: false },
  alternatives: [AlternativeSchema],
  secret: { type: Boolean, default: false },
  showOnlyWinner: { type: Boolean, default: true },
  countingBlankVotes: { type: Boolean, default: true },
  voteDemand: { type: String, required: true }, // Either "regular" or "qualified".
  qualifiedVoters: Number,
  currentVotes: { type: Number, default: 0 },
  result: Boolean,
});
const Question = mongoose.model('Question', QuestionSchema);

function addIssue(issue) {
  return new Question(issue).save();
}

function getConcludedIssues(genfors) {
  return Question.find({ genfors, deleted: false, active: false }).exec();
}

const getIssueById = id => (
  Question.findOne({ _id: id })
);
function getActiveQuestion(genfors) {
  return Question.findOne({ genfors, active: true, deleted: false });
}
function getClosedQuestions(genfors) {
  return Question.find({ genfors, active: false, deleted: false }).exec();
}

function endIssue(issue) {
  return Question.findByIdAndUpdate(issue, { active: false }, { new: true });
}

function deleteIssue(issue) {
  return Question.findByIdAndUpdate(issue, { active: false, deleted: true }, { new: true });
}

module.exports = {
  addIssue,
  getActiveQuestion,
  getClosedQuestions,
  getIssueById,
  getConcludedIssues,
  endIssue,
  // updateQuestionCounter,
  deleteIssue,
};
<commit_msg>Fix creation date on issue model defaulting to server start<commit_after>const mongoose = require('mongoose');
const AlternativeSchema = require('./alternative');

const Schema = mongoose.Schema;

const QuestionSchema = new Schema({
  genfors: { type: Schema.Types.ObjectId, required: true },
  description: { type: String, required: true },
  date: { type: Date, required: true, default: Date.now },
  active: { type: Boolean, default: true },
  deleted: { type: Boolean, required: true, default: false },
  alternatives: [AlternativeSchema],
  secret: { type: Boolean, default: false },
  showOnlyWinner: { type: Boolean, default: true },
  countingBlankVotes: { type: Boolean, default: true },
  voteDemand: { type: String, required: true }, // Either "regular" or "qualified".
  qualifiedVoters: Number,
  currentVotes: { type: Number, default: 0 },
  result: Boolean,
});
const Question = mongoose.model('Question', QuestionSchema);

function addIssue(issue) {
  return new Question(issue).save();
}

function getConcludedIssues(genfors) {
  return Question.find({ genfors, deleted: false, active: false }).exec();
}

const getIssueById = id => (
  Question.findOne({ _id: id })
);
function getActiveQuestion(genfors) {
  return Question.findOne({ genfors, active: true, deleted: false });
}
function getClosedQuestions(genfors) {
  return Question.find({ genfors, active: false, deleted: false }).exec();
}

function endIssue(issue) {
  return Question.findByIdAndUpdate(issue, { active: false }, { new: true });
}

function deleteIssue(issue) {
  return Question.findByIdAndUpdate(issue, { active: false, deleted: true }, { new: true });
}

module.exports = {
  addIssue,
  getActiveQuestion,
  getClosedQuestions,
  getIssueById,
  getConcludedIssues,
  endIssue,
  // updateQuestionCounter,
  deleteIssue,
};
<|endoftext|>


<commit_before>/**
 * Testcafe browser provider plugin for the nightmare browser automation library.
 */
import Nightmare from 'nightmare';
import debug from 'debug';

export default {
    // reference to Nightmare instance
    nightmare: null,

    // map with open page references
    openedPages: {},

    // multiple browsers support
    isMultiBrowser: false,

    // open new page in browser
    async openBrowser (id, pageUrl) {
        const page = await this.nightmare.goto(pageUrl);

        this.openedPages[id] = page;
    },

    // close given page in browser
    async closeBrowser (id) {
        const page = this.openedPages[id];

        delete this.openedPages[id];
        await page.end();
    },

    // init browser
    async init () {
        const conf = {
            show:         debug.enabled(),
            openDevTools: debug.enabled(),
        };

        this.nightmare = Nightmare(conf);
    },

    async dispose () {
        return;
    },

    // resize browser window to given size
    async resizeWindow (id, width, height) {
        await this.nightmare.viewport(width, height);
    },

    // take screenshot of given page in browser
    async takeScreenshot (id, screenshotPath) {
        await this.nightmare.screenshot(screenshotPath);
    }
};
<commit_msg>Support debug namespace<commit_after>/**
 * Testcafe browser provider plugin for the nightmare browser automation library.
 */
import Nightmare from 'nightmare';
import Debug from 'debug';

//Add debug namespace
var debug = Debug("testcafe-browser-provider-nightmare");

export default {
    // reference to Nightmare instance
    nightmare: null,

    // map with open page references
    openedPages: {},

    // multiple browsers support
    isMultiBrowser: false,

    // open new page in browser
    async openBrowser (id, pageUrl) {
        const page = await this.nightmare.goto(pageUrl);

        this.openedPages[id] = page;
    },

    // close given page in browser
    async closeBrowser (id) {
        const page = this.openedPages[id];

        delete this.openedPages[id];
        await page.end();
    },

    // init browser
    async init () {
        const conf = {
            show:         debug.enabled(),
            openDevTools: debug.enabled(),
        };

        this.nightmare = Nightmare(conf);
    },

    async dispose () {
        return;
    },

    // resize browser window to given size
    async resizeWindow (id, width, height) {
        await this.nightmare.viewport(width, height);
    },

    // take screenshot of given page in browser
    async takeScreenshot (id, screenshotPath) {
        await this.nightmare.screenshot(screenshotPath);
    }
};
<|endoftext|>


<commit_before>const inquirer = require("inquirer");
const path = require("path");
const isValid = require("is-valid-path");
const mkdir = require("mkdirp-promise");
const logSymbols = require("log-symbols");

const successIcon = logSymbols.success;
const errorIcon = logSymbols.error;

const fileOperations = require("./file-operations");
const { pkg, getFileNames, readAndWriteFiles } = fileOperations;

const templateNameRegex = /\w+/;
const promptConfig = [
  {
    type: "input",
    name: "templateName",
    message: "What is your bridge module called?",
    default: "ExampleBridge",
    validate: input => templateNameRegex.test(input)
  },
  {
    type: "checkbox",
    name: "bridgeType",
    message: "What type of bridge would you like to create?",
    default: ["Native Module", "Native UI Component"],
    choices: ["Native Module", "Native UI Component"]
  },
  {
    type: "checkbox",
    name: "environment",
    message: "What OS & languages would you like to support?",
    default: ["Android/Java", "iOS/Objective-C"],
    choices: ["Android/Java", "Android/Kotlin", "iOS/Swift", "iOS/Objective-C"]
  },
  {
    type: "input",
    name: "jsPath",
    message: "What directory should we deliver your JS files to?",
    default: ".",
    validate: input => isValid(input)
  }
];

const environmentMap = {
  "Android/Java": createJavaEnvironment,
  "Android/Kotlin": createKotlinEnvironment,
  "iOS/Swift": createSwiftEnvironment,
  "iOS/Objective-C": createObjCEnvironment
};

function init() {
  inquirer
    .prompt(promptConfig)
    .then(result => {
      const { environment, bridgeType, templateName, jsPath } = result;

      const templateFolder =
        bridgeType.length > 1
          ? "combined"
          : bridgeType[0] === "Native Module" ? "modules" : "ui-components";

      const promises = environment.map(env =>
        environmentMap[env](templateName, templateFolder)
      );

      promises.push(createJSEnvironment(templateName, templateFolder, jsPath));

      Promise.all(promises).then(() => {
        console.log(
          `${successIcon} Your bridge module was successfully created! 🎉`
        );
      });
    })
    .catch(e => {
      console.log(
        `${errorIcon} Oh no! 💩  Something went wrong with creating your bridge module.\nPlease report any errors here: https://github.com/peggyrayzis/react-native-create-bridge/issues\n\nError: ${e}`
      );
    });
}

function createJavaEnvironment(templateName, templateFolder) {
  const appPath = path.join(
    process.cwd(),
    "android",
    "app",
    "src",
    "main",
    "java",
    "com",
    pkg.name
  );

  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "android-java"
  );

  return mkdir(
    path.join(appPath, templateName.toLowerCase())
  ).then(writeDirPath => {
    const paths = {
      readDirPath,
      writeDirPath: writeDirPath
        ? writeDirPath
        : path.join(appPath, templateName.toLowerCase())
    };

    getFileNames(readDirPath).then(files =>
      readAndWriteFiles(
        files,
        paths,
        templateName,
        templateName.toLowerCase(),
        pkg.name.toLowerCase()
      )
    );
  });
}

function createKotlinEnvironment(templateName, templateFolder) {
  const appPath = path.join(
    process.cwd(),
    "android",
    "app",
    "src",
    "main",
    "java",
    "com",
    pkg.name
  );

  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "android-kotlin"
  );

  return mkdir(
    path.join(appPath, templateName.toLowerCase())
  ).then(writeDirPath => {
    const paths = {
      readDirPath,
      writeDirPath: writeDirPath
        ? writeDirPath
        : path.join(appPath, templateName.toLowerCase())
    };

    return getFileNames(readDirPath).then(files =>
      readAndWriteFiles(
        files,
        paths,
        templateName,
        templateName.toLowerCase(),
        pkg.name.toLowerCase()
      )
    );
  });
}

function createSwiftEnvironment(templateName, templateFolder) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "ios-swift"
  );

  const paths = {
    readDirPath,
    writeDirPath: path.join(process.cwd(), "ios")
  };

  return getFileNames(readDirPath).then(files =>
    readAndWriteFiles(files, paths, templateName)
  );
}

function createObjCEnvironment(templateName, templateFolder) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "ios-objc"
  );

  const paths = {
    readDirPath,
    writeDirPath: path.join(process.cwd(), "ios")
  };

  return getFileNames(readDirPath).then(files =>
    readAndWriteFiles(files, paths, templateName)
  );
}

function createJSEnvironment(templateName, templateFolder, jsPath) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "js"
  );

  return mkdir(jsPath).then(() => {
    const paths = {
      readDirPath,
      writeDirPath: jsPath
    };

    return getFileNames(readDirPath).then(files =>
      readAndWriteFiles(files, paths, templateName)
    );
  });
}

module.exports = {
  name: "create-bridge",
  description:
    "A CLI tool that bridges React Native modules & UI components with ease",
  func: init
};
<commit_msg>refactor(index): update plugin description<commit_after>const inquirer = require("inquirer");
const path = require("path");
const isValid = require("is-valid-path");
const mkdir = require("mkdirp-promise");
const logSymbols = require("log-symbols");

const successIcon = logSymbols.success;
const errorIcon = logSymbols.error;

const fileOperations = require("./file-operations");
const { pkg, getFileNames, readAndWriteFiles } = fileOperations;

const templateNameRegex = /\w+/;
const promptConfig = [
  {
    type: "input",
    name: "templateName",
    message: "What is your bridge module called?",
    default: "ExampleBridge",
    validate: input => templateNameRegex.test(input)
  },
  {
    type: "checkbox",
    name: "bridgeType",
    message: "What type of bridge would you like to create?",
    default: ["Native Module", "Native UI Component"],
    choices: ["Native Module", "Native UI Component"]
  },
  {
    type: "checkbox",
    name: "environment",
    message: "What OS & languages would you like to support?",
    default: ["Android/Java", "iOS/Objective-C"],
    choices: ["Android/Java", "Android/Kotlin", "iOS/Swift", "iOS/Objective-C"]
  },
  {
    type: "input",
    name: "jsPath",
    message: "What directory should we deliver your JS files to?",
    default: ".",
    validate: input => isValid(input)
  }
];

const environmentMap = {
  "Android/Java": createJavaEnvironment,
  "Android/Kotlin": createKotlinEnvironment,
  "iOS/Swift": createSwiftEnvironment,
  "iOS/Objective-C": createObjCEnvironment
};

function init() {
  inquirer
    .prompt(promptConfig)
    .then(result => {
      const { environment, bridgeType, templateName, jsPath } = result;

      const templateFolder =
        bridgeType.length > 1
          ? "combined"
          : bridgeType[0] === "Native Module" ? "modules" : "ui-components";

      const promises = environment.map(env =>
        environmentMap[env](templateName, templateFolder)
      );

      promises.push(createJSEnvironment(templateName, templateFolder, jsPath));

      Promise.all(promises).then(() => {
        console.log(
          `${successIcon} Your bridge module was successfully created! 🎉`
        );
      });
    })
    .catch(e => {
      console.log(
        `${errorIcon} Oh no! 💩  Something went wrong with creating your bridge module.\nPlease report any errors here: https://github.com/peggyrayzis/react-native-create-bridge/issues\n\nError: ${e}`
      );
    });
}

function createJavaEnvironment(templateName, templateFolder) {
  const appPath = path.join(
    process.cwd(),
    "android",
    "app",
    "src",
    "main",
    "java",
    "com",
    pkg.name
  );

  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "android-java"
  );

  return mkdir(
    path.join(appPath, templateName.toLowerCase())
  ).then(writeDirPath => {
    const paths = {
      readDirPath,
      writeDirPath: writeDirPath
        ? writeDirPath
        : path.join(appPath, templateName.toLowerCase())
    };

    getFileNames(readDirPath).then(files =>
      readAndWriteFiles(
        files,
        paths,
        templateName,
        templateName.toLowerCase(),
        pkg.name.toLowerCase()
      )
    );
  });
}

function createKotlinEnvironment(templateName, templateFolder) {
  const appPath = path.join(
    process.cwd(),
    "android",
    "app",
    "src",
    "main",
    "java",
    "com",
    pkg.name
  );

  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "android-kotlin"
  );

  return mkdir(
    path.join(appPath, templateName.toLowerCase())
  ).then(writeDirPath => {
    const paths = {
      readDirPath,
      writeDirPath: writeDirPath
        ? writeDirPath
        : path.join(appPath, templateName.toLowerCase())
    };

    return getFileNames(readDirPath).then(files =>
      readAndWriteFiles(
        files,
        paths,
        templateName,
        templateName.toLowerCase(),
        pkg.name.toLowerCase()
      )
    );
  });
}

function createSwiftEnvironment(templateName, templateFolder) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "ios-swift"
  );

  const paths = {
    readDirPath,
    writeDirPath: path.join(process.cwd(), "ios")
  };

  return getFileNames(readDirPath).then(files =>
    readAndWriteFiles(files, paths, templateName)
  );
}

function createObjCEnvironment(templateName, templateFolder) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "ios-objc"
  );

  const paths = {
    readDirPath,
    writeDirPath: path.join(process.cwd(), "ios")
  };

  return getFileNames(readDirPath).then(files =>
    readAndWriteFiles(files, paths, templateName)
  );
}

function createJSEnvironment(templateName, templateFolder, jsPath) {
  const readDirPath = path.join(
    __dirname,
    "..",
    "templates",
    templateFolder,
    "js"
  );

  return mkdir(jsPath).then(() => {
    const paths = {
      readDirPath,
      writeDirPath: jsPath
    };

    return getFileNames(readDirPath).then(files =>
      readAndWriteFiles(files, paths, templateName)
    );
  });
}

module.exports = {
  name: "create-bridge",
  description:
    "A React Native plugin that bridges React Native modules & UI components with ease",
  func: init
};
<|endoftext|>


<commit_before>var Hapi = require('Hapi');
var io = require('socket.io');
var config = require('config');
var Id = require('dht-id');

var server = new Hapi.Server(config.get('hapi.options'));

server.connection({
    port: config.get('hapi.port')
});

server.route({
    method: 'GET',
    path: '/',
    handler: function(request, reply) {
        reply('Signaling Server');
    }
});

server.route({
    method: 'GET',
    path: '/dht',
    handler: function(request, reply) {
        reply(peers);
    }
});

server.start(started);

function started() {
    io.listen(server.listener).on('connection', ioHandler);
    console.log('Signaling server has started on:', server.info.uri);
}

var peers = {};
// id : {
//     socketId:
//     fingerTable: {
//         row : {
//             ideal: <fingerId>
//             current: <fingerId>
//         }
//     }
// }

var sockets = {};
// socketId: socket

function ioHandler(socket) {

    // signalling server interactions
    socket.on('s-register', registerPeer);
    socket.on('disconnect', peerRemove); // socket.io own event
    socket.on('s-send-offer', sendOffer);
    socket.on('s-offer-accepted', offerAccepted);

    function registerPeer() {
        var peerId = new Id();
        peers[peerId.toHex()] = {
            socketId:  socket.id,
            fingerTable: {}
        };

        sockets[socket.id] = socket;

        socket.emit('c-registered', {peerId: peerId.toHex()});

        console.log('registered new peer: ', peerId.toHex());

        calculateIdealFingers(peerId);
        updateFingers();
    }

    function calculateIdealFingers(peerId) {
        var k = 1;
        while (k <= config.get('explorer.n-fingers')) {
            var ideal = (peerId.toDec() + Math.pow(2, k)) % Math.pow(2, 48);
            peers[peerId.toHex()].fingerTable[k] = {
                ideal: new Id(ideal).toHex(),
                current: undefined
            };
            k++;
        }
    }

    function updateFingers() {
        if (Object.keys(peers) < 2) {
            return;
        }

        var sortedPeersId = Object.keys(peers).sort(function(a, b) {
            var aId = new Id(a);
            var bId = new Id(b);
            if (aId.toDec() > bId.toDec()) {
                return 1;
            }
            if (aId.toDec() < bId.toDec()) {
                return -1;
            }
            if (aId.toDec() === bId.toDec()) {
                console.log('error - There should never two identical ids');
                process.exit(1);
            }
        });

        sortedPeersId.forEach(function(peerId) {
            Object.keys(peers[peerId].fingerTable).some(function(rowIndex) {
                var fingerId = sucessorTo(peers[peerId]
                                    .fingerTable[rowIndex]
                                    .ideal, sortedPeersId);

                if (peers[peerId].fingerTable[rowIndex].current !==
                    fingerId) {

                    peers[peerId].fingerTable[rowIndex].current = fingerId;

                    sockets[peers[peerId].socketId].emit('c-finger-update', {
                        rowIndex: rowIndex,
                        fingerId: fingerId
                    });
                }

                if (Object.keys(peers).length <
                        config.get('explorer.min-peers')) {
                    return true; // stops the loop, calculates only
                    // for the first position (aka sucessor of the node
                }
            });
        });

        function sucessorTo (pretendedId, sortedIdList) {
            pretendedId = new Id(pretendedId).toDec();
            sortedIdList = sortedIdList.map(function(inHex) {
                return new Id(inHex).toDec();
            });

            var sucessorId;
            sortedIdList.some(function(value, index) {
                if (pretendedId === value) {
                    sucessorId = value;
                    return true;
                }

                if (pretendedId < value) {
                    sucessorId = value;
                    return true;
                }

                if (index + 1 === sortedIdList.length) {

                    sucessorId = sortedIdList[0];
                    return true;
                }
            });

            return new Id(sucessorId).toHex();
        }
    }

    function peerRemove() {
        Object.keys(peers).map(function(peerId) {
            if (peers[peerId].socketId === socket.id) {
                delete peers[peerId];
                delete sockets[socket.id];
                console.log('peer with Id: %s has disconnected', peerId);
            }
        });
    }

    // signalling mediation between two peers

    function sendOffer(data) {
        sockets[peers[data.offer.dstId].socketId]
            .emit('c-accept-offer', data);
    }

    function offerAccepted(data) {
        sockets[peers[data.offer.srcId].socketId]
            .emit('c-offer-accepted', data);
    }

}
<commit_msg>bug fix, premature finger update<commit_after>var Hapi = require('Hapi');
var io = require('socket.io');
var config = require('config');
var Id = require('dht-id');

var server = new Hapi.Server(config.get('hapi.options'));

server.connection({
    port: config.get('hapi.port')
});

server.route({
    method: 'GET',
    path: '/',
    handler: function(request, reply) {
        reply('Signaling Server');
    }
});

server.route({
    method: 'GET',
    path: '/dht',
    handler: function(request, reply) {
        reply(peers);
    }
});

server.start(started);

function started() {
    io.listen(server.listener).on('connection', ioHandler);
    console.log('Signaling server has started on:', server.info.uri);
}

var peers = {};
// id : {
//     socketId:
//     fingerTable: {
//         row : {
//             ideal: <fingerId>
//             current: <fingerId>
//         }
//     }
// }

var sockets = {};
// socketId: socket

function ioHandler(socket) {

    // signalling server interactions
    socket.on('s-register', registerPeer);
    socket.on('disconnect', peerRemove); // socket.io own event
    socket.on('s-send-offer', sendOffer);
    socket.on('s-offer-accepted', offerAccepted);

    function registerPeer() {
        var peerId = new Id();
        peers[peerId.toHex()] = {
            socketId:  socket.id,
            fingerTable: {}
        };

        sockets[socket.id] = socket;

        socket.emit('c-registered', {peerId: peerId.toHex()});

        console.log('registered new peer: ', peerId.toHex());

        calculateIdealFingers(peerId);
        updateFingers();
    }

    function calculateIdealFingers(peerId) {
        var k = 1;
        while (k <= config.get('explorer.n-fingers')) {
            var ideal = (peerId.toDec() + Math.pow(2, k)) % Math.pow(2, 48);
            peers[peerId.toHex()].fingerTable[k] = {
                ideal: new Id(ideal).toHex(),
                current: undefined
            };
            k++;
        }
    }

    function updateFingers() {
        if (Object.keys(peers).length < 2) {
            return;
        }

        var sortedPeersId = Object.keys(peers).sort(function(a, b) {
            var aId = new Id(a);
            var bId = new Id(b);
            if (aId.toDec() > bId.toDec()) {
                return 1;
            }
            if (aId.toDec() < bId.toDec()) {
                return -1;
            }
            if (aId.toDec() === bId.toDec()) {
                console.log('error - There should never two identical ids');
                process.exit(1);
            }
        });

        sortedPeersId.forEach(function(peerId) {
            Object.keys(peers[peerId].fingerTable).some(function(rowIndex) {
                var fingerId = sucessorTo(peers[peerId]
                                    .fingerTable[rowIndex]
                                    .ideal, sortedPeersId);

                if (peers[peerId].fingerTable[rowIndex].current !==
                    fingerId) {

                    peers[peerId].fingerTable[rowIndex].current = fingerId;

                    sockets[peers[peerId].socketId].emit('c-finger-update', {
                        rowIndex: rowIndex,
                        fingerId: fingerId
                    });
                }

                if (Object.keys(peers).length <
                        config.get('explorer.min-peers')) {
                    return true; // stops the loop, calculates only
                    // for the first position (aka sucessor of the node
                }
            });
        });

        function sucessorTo (pretendedId, sortedIdList) {
            pretendedId = new Id(pretendedId).toDec();
            sortedIdList = sortedIdList.map(function(inHex) {
                return new Id(inHex).toDec();
            });

            var sucessorId;
            sortedIdList.some(function(value, index) {
                if (pretendedId === value) {
                    sucessorId = value;
                    return true;
                }

                if (pretendedId < value) {
                    sucessorId = value;
                    return true;
                }

                if (index + 1 === sortedIdList.length) {

                    sucessorId = sortedIdList[0];
                    return true;
                }
            });

            return new Id(sucessorId).toHex();
        }
    }

    function peerRemove() {
        Object.keys(peers).map(function(peerId) {
            if (peers[peerId].socketId === socket.id) {
                delete peers[peerId];
                delete sockets[socket.id];
                console.log('peer with Id: %s has disconnected', peerId);
            }
        });
    }

    // signalling mediation between two peers

    function sendOffer(data) {
        sockets[peers[data.offer.dstId].socketId]
            .emit('c-accept-offer', data);
    }

    function offerAccepted(data) {
        sockets[peers[data.offer.srcId].socketId]
            .emit('c-offer-accepted', data);
    }

}
<|endoftext|>


<commit_before>Meteor.publish('posts', function() {
  return Posts.find();
});

Meteor.publish('comments', function(postId) {
  check(postId, String);
  return Comments.find({postId: postId});
});

Meteor.publish('notifications', function() {
  return Notifications.find();
})
<commit_msg>Only sync notifications that are relevant to the user.<commit_after>Meteor.publish('posts', function() {
  return Posts.find();
});

Meteor.publish('comments', function(postId) {
  check(postId, String);
  return Comments.find({postId: postId});
});

Meteor.publish('notifications', function() {
  return Notifications.find({userId: this.userId, read: false});
});
<|endoftext|>


<commit_before>export default () => {
    const stack = [];
    const use = (...fns) => {
        let i = fns.length;
        while (i--) {
            const fn = fns[i];
            if (Array.isArray(fn)) return use(...fn);
            if ('function' === typeof fn) stack.unshift(fn);
        }
    }
    const run = (args, done) => {
        let i = stack.length;
        const next = (err=null, fin) => {
            if (err || fin || !i) {
                if ('function' === typeof done) done(err);
                return;
            }
            stack[--i].apply(null, [...args, next]);
        }
        next();
    }
    return { use, run };
};
<commit_msg>missing semicolons<commit_after>export default () => {
    const stack = [];
    const use = (...fns) => {
        let i = fns.length;
        while (i--) {
            const fn = fns[i];
            if (Array.isArray(fn)) return use(...fn);
            if ('function' === typeof fn) stack.unshift(fn);
        }
    };
    const run = (args, done) => {
        let i = stack.length;
        const next = (err=null, fin) => {
            if (err || fin || !i) {
                if ('function' === typeof done) done(err);
                return;
            }
            stack[--i].apply(null, [...args, next]);
        }
        next();
    };
    return { use, run };
};
<|endoftext|>


<commit_before>'use strict';

const emptyArray = Object.freeze([]);
const emptyObject = Object.freeze(Object.create(null));

const namedEntities = Object.freeze({
  '&': '&',
  ''': "'",
  '>': '>',
  '<': '<',
  '"': '"'
});

const NODE_TYPE_CDATA = 'cdata';
const NODE_TYPE_COMMENT = 'comment';
const NODE_TYPE_DOCUMENT = 'document';
const NODE_TYPE_ELEMENT = 'element';
const NODE_TYPE_TEXT = 'text';

let Syntax;

module.exports = function parseXml(xml, options = emptyObject) {
  if (Syntax === void 0) {
    // Lazy require to defer regex parsing until first use.
    Syntax = require('./lib/syntax');
  }

  if (xml[0] === '\uFEFF') {
    // Strip byte order mark.
    xml = xml.slice(1);
  }

  xml = xml.replace(/\r\n/g, '\n'); // Normalize CRLF to LF.

  let doc = {
    type: NODE_TYPE_DOCUMENT,
    children: [],
    parent: null,
    toJSON: nodeToJson
  };

  let state = {
    length: xml.length,
    options,
    parent: doc,
    pos: 0,
    prevPos: 0,
    slice: null,
    xml
  };

  state.replaceReference = replaceReference.bind(state);

  consumeProlog(state);

  if (!consumeElement(state)) {
    error(state, 'Root element is missing or invalid');
  }

  while (consumeMisc(state)) {}

  if (!isEof(state)) {
    error(state, `Extra content at the end of the document`);
  }

  return doc;
};

// -- Private Functions --------------------------------------------------------
function addNode(state, node) {
  node.parent = state.parent;
  node.toJSON = nodeToJson;

  state.parent.children.push(node);
}

function addText(state, text) {
  let { children } = state.parent;
  let prevNode = children[children.length - 1];

  if (prevNode !== void 0 && prevNode.type === NODE_TYPE_TEXT) {
    // The previous node is a text node, so we can append to it and avoid
    // creating another node.
    prevNode.text += text;
  } else {
    addNode(state, {
      type: NODE_TYPE_TEXT,
      text
    });
  }
}

// Each `consume*` function takes the current state as an argument and returns
// `true` if `state.pos` was advanced (meaning some XML was consumed) or `false`
// if nothing was consumed.

function consumeCDSect(state) {
  let [ match, text ] = scan(state, Syntax.Anchored.CDSect);

  if (match === void 0) {
    return false;
  }

  if (state.options.preserveCdata) {
    addNode(state, {
      type: NODE_TYPE_CDATA,
      text
    });
  } else {
    addText(state, text);
  }

  return true;
}

function consumeCharData(state) {
  let [ text ] = scan(state, Syntax.Anchored.CharData);

  if (text === void 0) {
    return false;
  }

  let cdataCloseIndex = text.indexOf(']]>');

  if (cdataCloseIndex !== -1) {
    state.pos = state.prevPos + cdataCloseIndex;
    error(state, 'Element content may not contain the CDATA section close delimiter `]]>`');
  }

  // Note: XML 1.0 5th ed. says `CharData` is "any string of characters which
  // does not contain the start-delimiter of any markup and does not include the
  // CDATA-section-close delimiter", but the conformance test suite and
  // well-established parsers like libxml seem to restrict `CharData` to
  // characters that match the `Char` symbol, so that's what I've done here.
  if (!Syntax.CharOnly.test(text)) {
    state.pos = state.prevPos + text.search(new RegExp(`(?!${Syntax.Char.source})`));
    error(state, 'Element content contains an invalid character');
  }

  addText(state, text);
  return true;
}

function consumeComment(state) {
  let [ , content ] = scan(state, Syntax.Anchored.Comment);

  if (content === void 0) {
    return false;
  }

  if (state.options.preserveComments) {
    addNode(state, {
      type: NODE_TYPE_COMMENT,
      content: content.trim()
    });
  }

  return true;
}

function consumeDoctypeDecl(state) {
  return scan(state, Syntax.Anchored.doctypedecl).length > 0;
}

function consumeElement(state) {
  let [ tag, name, attrs ] = scan(state, Syntax.Anchored.EmptyElemTag);
  let isEmpty = tag !== void 0;

  if (!isEmpty) {
    [ tag, name, attrs ] = scan(state, Syntax.Anchored.STag);

    if (tag === void 0) {
      return false;
    }
  }

  let { parent } = state;
  let parsedAttrs = parseAttrs(state, attrs);

  let node = {
    type: NODE_TYPE_ELEMENT,
    name,
    attributes: parsedAttrs,
    children: []
  };

  let xmlSpace = parsedAttrs['xml:space'];

  if (xmlSpace === 'preserve'
      || (xmlSpace !== 'default' && parent.preserveWhitespace)) {

    node.preserveWhitespace = true;
  }

  if (!isEmpty) {
    state.parent = node;

    consumeCharData(state);

    while (
      consumeElement(state)
        || consumeReference(state)
        || consumeCDSect(state)
        || consumePI(state)
        || consumeComment(state)
    ) {
      consumeCharData(state);
    }

    let [ , endName ] = scan(state, Syntax.Anchored.ETag);

    if (endName !== name) {
      state.pos = state.prevPos;
      error(state, `Missing end tag for element ${name}`);
    }

    state.parent = parent;
  }

  addNode(state, node);
  return true;
}

function consumeMisc(state) {
  return consumeComment(state)
    || consumePI(state)
    || consumeWhitespace(state);
}

function consumePI(state) {
  let [ match, target ] = scan(state, Syntax.Anchored.PI);

  if (match === void 0) {
    return false;
  }

  if (target.toLowerCase() === 'xml') {
    state.pos = state.prevPos;
    error(state, 'XML declaration is only allowed at the start of the document');
  }

  return true;
}

function consumeProlog(state) {
  let { pos } = state;

  scan(state, Syntax.Anchored.XMLDecl);

  while (consumeMisc(state)) {}

  if (consumeDoctypeDecl(state)) {
    while (consumeMisc(state)) {}
  }

  return state.pos > pos;
}

function consumeReference(state) {
  let [ ref ] = scan(state, Syntax.Anchored.Reference);

  if (ref === void 0) {
    return false;
  }

  addText(state, state.replaceReference(ref));
  return true;
}

function consumeWhitespace(state) {
  return scan(state, Syntax.Anchored.S).length > 0;
}

function error(state, message) {
  let { pos, xml } = state;
  let column = 1;
  let excerpt = '';
  let line = 1;

  // Find the line and column where the error occurred.
  for (let i = 0; i < pos; ++i) {
    let char = xml[i];

    if (char === '\n') {
      column = 1;
      excerpt = '';
      line += 1;
    } else {
      column += 1;
      excerpt += char;
    }
  }

  let eol = xml.indexOf('\n', pos);

  excerpt += eol === -1
    ? xml.slice(pos)
    : xml.slice(pos, eol);

  let excerptStart = 0;

  // Keep the excerpt below 50 chars, but always keep the error position in
  // view.
  if (excerpt.length > 50) {
    if (column < 40) {
      excerpt = excerpt.slice(0, 50);
    } else {
      excerptStart = column - 20;
      excerpt = excerpt.slice(excerptStart, column + 30);
    }
  }

  let err = new Error(
    `${message} (line ${line}, column ${column})\n`
      + `  ${excerpt}\n`
      + ' '.repeat(column - excerptStart + 1) + '^\n'
  );

  err.column = column;
  err.excerpt = excerpt;
  err.line = line;
  err.pos = pos;

  throw err;
}

function isEof(state) {
  return state.pos >= state.length - 1;
}

function nodeToJson() {
  let json = Object.assign(Object.create(null), this);
  delete json.parent;
  return json;
}

function normalizeAttrValue(state, value) {
  return value
    .replace(Syntax.Global.Reference, state.replaceReference)
    .replace(Syntax.Global.S, ' ')
    .trim();
}

function parseAttrs(state, attrs) {
  let parsedAttrs = Object.create(null);

  if (!attrs) {
    return parsedAttrs;
  }

  let attrPairs = attrs
    .match(Syntax.Global.Attribute)
    .sort();

  for (let i = 0, len = attrPairs.length; i < len; ++i) {
    let [ name, value ] = attrPairs[i].split(Syntax.Eq);

    if (name in parsedAttrs) {
      state.pos = state.prevPos;
      error(state, `Attribute \`${name}\` redefined`);
    }

    value = normalizeAttrValue(state, value.slice(1, -1));

    if (name === 'xml:space') {
      if (value !== 'default' && value !== 'preserve') {
        state.pos = state.prevPos;
        error(state, `Value of the \`xml:space\` attribute must be "default" or "preserve"`);
      }
    }

    parsedAttrs[name] = value;
  }

  return parsedAttrs;
}

function replaceReference(ref) {
  let state = this;

  if (ref[1] === '#') {
    // This is a character entity.
    let codePoint;

    if (ref[2] === 'x') {
      codePoint = parseInt(ref.slice(3, -1), 16);
    } else {
      codePoint = parseInt(ref.slice(2, -1), 10);
    }

    if (isNaN(codePoint)) {
      state.pos = state.prevPos;
      error(state, `Invalid character entity \`${ref}\``);
    }

    let char = String.fromCodePoint(codePoint);

    if (!Syntax.Char.test(char)) {
      state.pos = state.prevPos;
      error(state, `Invalid character entity \`${ref}\``);
    }

    return char;
  }

  // This is a named entity.
  let value = namedEntities[ref];
  if (value === void 0 && state.options.resolveUndefinedEntities) {
    let v = state.options.resolveUndefinedEntities(ref);
    if (v != null) { // tests both undefined and null but not other falsish values
      value = v;
    }
  }

  if (value === void 0) {
    if (state.options.ignoreUndefinedEntities) {
      return ref;
    }

    state.pos = state.prevPos;
    error(state, `Named entity isn't defined: \`${ref}\``);
  }

  return value;
}

function scan(state, regex) {
  let { pos, slice, xml } = state;

  if (slice === null) {
    if (pos > 0) {
      slice = xml.slice(pos);
      state.slice = slice;
    } else {
      slice = xml;
    }
  }

  let matches = slice.match(regex);

  if (matches === null) {
    return emptyArray;
  }

  state.prevPos = state.pos;
  state.pos += matches[0].length;
  state.slice = null;

  return matches;
}
<commit_msg>style: Avoid single-letter var and unnecessary additional value check<commit_after>'use strict';

const emptyArray = Object.freeze([]);
const emptyObject = Object.freeze(Object.create(null));

const namedEntities = Object.freeze({
  '&': '&',
  ''': "'",
  '>': '>',
  '<': '<',
  '"': '"'
});

const NODE_TYPE_CDATA = 'cdata';
const NODE_TYPE_COMMENT = 'comment';
const NODE_TYPE_DOCUMENT = 'document';
const NODE_TYPE_ELEMENT = 'element';
const NODE_TYPE_TEXT = 'text';

let Syntax;

module.exports = function parseXml(xml, options = emptyObject) {
  if (Syntax === void 0) {
    // Lazy require to defer regex parsing until first use.
    Syntax = require('./lib/syntax');
  }

  if (xml[0] === '\uFEFF') {
    // Strip byte order mark.
    xml = xml.slice(1);
  }

  xml = xml.replace(/\r\n/g, '\n'); // Normalize CRLF to LF.

  let doc = {
    type: NODE_TYPE_DOCUMENT,
    children: [],
    parent: null,
    toJSON: nodeToJson
  };

  let state = {
    length: xml.length,
    options,
    parent: doc,
    pos: 0,
    prevPos: 0,
    slice: null,
    xml
  };

  state.replaceReference = replaceReference.bind(state);

  consumeProlog(state);

  if (!consumeElement(state)) {
    error(state, 'Root element is missing or invalid');
  }

  while (consumeMisc(state)) {}

  if (!isEof(state)) {
    error(state, `Extra content at the end of the document`);
  }

  return doc;
};

// -- Private Functions --------------------------------------------------------
function addNode(state, node) {
  node.parent = state.parent;
  node.toJSON = nodeToJson;

  state.parent.children.push(node);
}

function addText(state, text) {
  let { children } = state.parent;
  let prevNode = children[children.length - 1];

  if (prevNode !== void 0 && prevNode.type === NODE_TYPE_TEXT) {
    // The previous node is a text node, so we can append to it and avoid
    // creating another node.
    prevNode.text += text;
  } else {
    addNode(state, {
      type: NODE_TYPE_TEXT,
      text
    });
  }
}

// Each `consume*` function takes the current state as an argument and returns
// `true` if `state.pos` was advanced (meaning some XML was consumed) or `false`
// if nothing was consumed.

function consumeCDSect(state) {
  let [ match, text ] = scan(state, Syntax.Anchored.CDSect);

  if (match === void 0) {
    return false;
  }

  if (state.options.preserveCdata) {
    addNode(state, {
      type: NODE_TYPE_CDATA,
      text
    });
  } else {
    addText(state, text);
  }

  return true;
}

function consumeCharData(state) {
  let [ text ] = scan(state, Syntax.Anchored.CharData);

  if (text === void 0) {
    return false;
  }

  let cdataCloseIndex = text.indexOf(']]>');

  if (cdataCloseIndex !== -1) {
    state.pos = state.prevPos + cdataCloseIndex;
    error(state, 'Element content may not contain the CDATA section close delimiter `]]>`');
  }

  // Note: XML 1.0 5th ed. says `CharData` is "any string of characters which
  // does not contain the start-delimiter of any markup and does not include the
  // CDATA-section-close delimiter", but the conformance test suite and
  // well-established parsers like libxml seem to restrict `CharData` to
  // characters that match the `Char` symbol, so that's what I've done here.
  if (!Syntax.CharOnly.test(text)) {
    state.pos = state.prevPos + text.search(new RegExp(`(?!${Syntax.Char.source})`));
    error(state, 'Element content contains an invalid character');
  }

  addText(state, text);
  return true;
}

function consumeComment(state) {
  let [ , content ] = scan(state, Syntax.Anchored.Comment);

  if (content === void 0) {
    return false;
  }

  if (state.options.preserveComments) {
    addNode(state, {
      type: NODE_TYPE_COMMENT,
      content: content.trim()
    });
  }

  return true;
}

function consumeDoctypeDecl(state) {
  return scan(state, Syntax.Anchored.doctypedecl).length > 0;
}

function consumeElement(state) {
  let [ tag, name, attrs ] = scan(state, Syntax.Anchored.EmptyElemTag);
  let isEmpty = tag !== void 0;

  if (!isEmpty) {
    [ tag, name, attrs ] = scan(state, Syntax.Anchored.STag);

    if (tag === void 0) {
      return false;
    }
  }

  let { parent } = state;
  let parsedAttrs = parseAttrs(state, attrs);

  let node = {
    type: NODE_TYPE_ELEMENT,
    name,
    attributes: parsedAttrs,
    children: []
  };

  let xmlSpace = parsedAttrs['xml:space'];

  if (xmlSpace === 'preserve'
      || (xmlSpace !== 'default' && parent.preserveWhitespace)) {

    node.preserveWhitespace = true;
  }

  if (!isEmpty) {
    state.parent = node;

    consumeCharData(state);

    while (
      consumeElement(state)
        || consumeReference(state)
        || consumeCDSect(state)
        || consumePI(state)
        || consumeComment(state)
    ) {
      consumeCharData(state);
    }

    let [ , endName ] = scan(state, Syntax.Anchored.ETag);

    if (endName !== name) {
      state.pos = state.prevPos;
      error(state, `Missing end tag for element ${name}`);
    }

    state.parent = parent;
  }

  addNode(state, node);
  return true;
}

function consumeMisc(state) {
  return consumeComment(state)
    || consumePI(state)
    || consumeWhitespace(state);
}

function consumePI(state) {
  let [ match, target ] = scan(state, Syntax.Anchored.PI);

  if (match === void 0) {
    return false;
  }

  if (target.toLowerCase() === 'xml') {
    state.pos = state.prevPos;
    error(state, 'XML declaration is only allowed at the start of the document');
  }

  return true;
}

function consumeProlog(state) {
  let { pos } = state;

  scan(state, Syntax.Anchored.XMLDecl);

  while (consumeMisc(state)) {}

  if (consumeDoctypeDecl(state)) {
    while (consumeMisc(state)) {}
  }

  return state.pos > pos;
}

function consumeReference(state) {
  let [ ref ] = scan(state, Syntax.Anchored.Reference);

  if (ref === void 0) {
    return false;
  }

  addText(state, state.replaceReference(ref));
  return true;
}

function consumeWhitespace(state) {
  return scan(state, Syntax.Anchored.S).length > 0;
}

function error(state, message) {
  let { pos, xml } = state;
  let column = 1;
  let excerpt = '';
  let line = 1;

  // Find the line and column where the error occurred.
  for (let i = 0; i < pos; ++i) {
    let char = xml[i];

    if (char === '\n') {
      column = 1;
      excerpt = '';
      line += 1;
    } else {
      column += 1;
      excerpt += char;
    }
  }

  let eol = xml.indexOf('\n', pos);

  excerpt += eol === -1
    ? xml.slice(pos)
    : xml.slice(pos, eol);

  let excerptStart = 0;

  // Keep the excerpt below 50 chars, but always keep the error position in
  // view.
  if (excerpt.length > 50) {
    if (column < 40) {
      excerpt = excerpt.slice(0, 50);
    } else {
      excerptStart = column - 20;
      excerpt = excerpt.slice(excerptStart, column + 30);
    }
  }

  let err = new Error(
    `${message} (line ${line}, column ${column})\n`
      + `  ${excerpt}\n`
      + ' '.repeat(column - excerptStart + 1) + '^\n'
  );

  err.column = column;
  err.excerpt = excerpt;
  err.line = line;
  err.pos = pos;

  throw err;
}

function isEof(state) {
  return state.pos >= state.length - 1;
}

function nodeToJson() {
  let json = Object.assign(Object.create(null), this);
  delete json.parent;
  return json;
}

function normalizeAttrValue(state, value) {
  return value
    .replace(Syntax.Global.Reference, state.replaceReference)
    .replace(Syntax.Global.S, ' ')
    .trim();
}

function parseAttrs(state, attrs) {
  let parsedAttrs = Object.create(null);

  if (!attrs) {
    return parsedAttrs;
  }

  let attrPairs = attrs
    .match(Syntax.Global.Attribute)
    .sort();

  for (let i = 0, len = attrPairs.length; i < len; ++i) {
    let [ name, value ] = attrPairs[i].split(Syntax.Eq);

    if (name in parsedAttrs) {
      state.pos = state.prevPos;
      error(state, `Attribute \`${name}\` redefined`);
    }

    value = normalizeAttrValue(state, value.slice(1, -1));

    if (name === 'xml:space') {
      if (value !== 'default' && value !== 'preserve') {
        state.pos = state.prevPos;
        error(state, `Value of the \`xml:space\` attribute must be "default" or "preserve"`);
      }
    }

    parsedAttrs[name] = value;
  }

  return parsedAttrs;
}

function replaceReference(ref) {
  let state = this;

  if (ref[1] === '#') {
    // This is a character entity.
    let codePoint;

    if (ref[2] === 'x') {
      codePoint = parseInt(ref.slice(3, -1), 16);
    } else {
      codePoint = parseInt(ref.slice(2, -1), 10);
    }

    if (isNaN(codePoint)) {
      state.pos = state.prevPos;
      error(state, `Invalid character entity \`${ref}\``);
    }

    let char = String.fromCodePoint(codePoint);

    if (!Syntax.Char.test(char)) {
      state.pos = state.prevPos;
      error(state, `Invalid character entity \`${ref}\``);
    }

    return char;
  }

  // This is a named entity.
  let value = namedEntities[ref];

  if (value !== void 0) {
    return value;
  }

  if (state.options.resolveUndefinedEntities) {
    let resolvedValue = state.options.resolveUndefinedEntities(ref);

    if (resolvedValue !== null && resolvedValue !== void 0) {
      return resolvedValue;
    }
  }

  if (state.options.ignoreUndefinedEntities) {
    return ref;
  }

  state.pos = state.prevPos;
  error(state, `Named entity isn't defined: \`${ref}\``);
}

function scan(state, regex) {
  let { pos, slice, xml } = state;

  if (slice === null) {
    if (pos > 0) {
      slice = xml.slice(pos);
      state.slice = slice;
    } else {
      slice = xml;
    }
  }

  let matches = slice.match(regex);

  if (matches === null) {
    return emptyArray;
  }

  state.prevPos = state.pos;
  state.pos += matches[0].length;
  state.slice = null;

  return matches;
}
<|endoftext|>


<commit_before>import apiCreate from './api/create';
import apiEmit from './api/emit';
import apiFragment from './api/fragment';
import apiInit from './api/init';
import apiVersion from './api/version';
import assign from './util/assign';
import assignSafe from './util/assign-safe';
import attached from './lifecycle/attached';
import attribute from './lifecycle/attribute';
import created from './lifecycle/created';
import debounce from './util/debounce';
import defaults from './defaults';
import detached from './lifecycle/detached';
import documentObserver from './global/document-observer';
import elementConstructor from './util/element-constructor';
import registry from './global/registry';
import supportsCustomElements from './support/custom-elements';
import typeElement from './type/element';
import utilWalkTree from './util/walk-tree';
import validCustomElement from './support/valid-custom-element';

function makeOptions (userOptions) {
  var options = assignSafe({}, defaults);

  // Copy over all standard options if the user has defined them.
  for (let name in defaults) {
    if (userOptions[name] !== undefined) {
      options[name] = userOptions[name];
    }
  }

  // Copy over non-standard options.
  for (let name in userOptions) {
    options[name] = userOptions[name];
  }

  return options;
}

function makeNonNewableWrapper (Ctor) {
  var CtorWrapper = function (props = {}) {
    return assign(new Ctor(), props);
  };
  CtorWrapper.prototype = Ctor.prototype;
  return CtorWrapper;
}

var HTMLElement = window.HTMLElement;
var initDocument = debounce(function () {
  utilWalkTree(document.documentElement.childNodes, function (element) {
    var components = registry.find(element);
    var componentsLength = components.length;

    for (let a = 0; a < componentsLength; a++) {
      created(components[a]).call(element);
    }

    for (let a = 0; a < componentsLength; a++) {
      attached(components[a]).call(element);
    }
  });
});

function skate (id, userOptions) {
  var Ctor, CtorParent;
  var opts = makeOptions(userOptions);

  CtorParent = opts.extends ? document.createElement(opts.extends).constructor : HTMLElement;
  opts.isNative = opts.type === typeElement && supportsCustomElements() && validCustomElement(id);

  // Inherit from parent prototype.
  if (!CtorParent.prototype.isPrototypeOf(opts.prototype)) {
    opts.prototype = assignSafe(Object.create(CtorParent.prototype), opts.prototype);
  }

  // Extend behaviour of existing callbacks.
  opts.prototype.createdCallback = created(opts);
  opts.prototype.attachedCallback = attached(opts);
  opts.prototype.detachedCallback = detached(opts);
  opts.prototype.attributeChangedCallback = attribute(opts);

  // Ensure the ID can be retrieved from the options or constructor.
  opts.id = id;

  // Make a constructor for the definition.
  if (opts.isNative) {
    Ctor = document.registerElement(id, {
      extends: opts.extends || undefined,
      prototype: opts.prototype
    });
  } else {
    Ctor = elementConstructor(opts);
    initDocument();
    documentObserver.register();
  }

  Ctor = makeNonNewableWrapper(Ctor);
  assignSafe(Ctor, opts);
  registry.set(id, Ctor);

  return Ctor;
}

skate.create = apiCreate;
skate.emit = apiEmit;
skate.fragment = apiFragment;
skate.init = apiInit;
skate.version = apiVersion;

// ES6
export default skate;
<commit_msg>Put opt defaulting closer to the top.<commit_after>import apiCreate from './api/create';
import apiEmit from './api/emit';
import apiFragment from './api/fragment';
import apiInit from './api/init';
import apiVersion from './api/version';
import assign from './util/assign';
import assignSafe from './util/assign-safe';
import attached from './lifecycle/attached';
import attribute from './lifecycle/attribute';
import created from './lifecycle/created';
import debounce from './util/debounce';
import defaults from './defaults';
import detached from './lifecycle/detached';
import documentObserver from './global/document-observer';
import elementConstructor from './util/element-constructor';
import registry from './global/registry';
import supportsCustomElements from './support/custom-elements';
import typeElement from './type/element';
import utilWalkTree from './util/walk-tree';
import validCustomElement from './support/valid-custom-element';

function makeOptions (userOptions) {
  var options = assignSafe({}, defaults);

  // Copy over all standard options if the user has defined them.
  for (let name in defaults) {
    if (userOptions[name] !== undefined) {
      options[name] = userOptions[name];
    }
  }

  // Copy over non-standard options.
  for (let name in userOptions) {
    options[name] = userOptions[name];
  }

  return options;
}

function makeNonNewableWrapper (Ctor) {
  var CtorWrapper = function (props = {}) {
    return assign(new Ctor(), props);
  };
  CtorWrapper.prototype = Ctor.prototype;
  return CtorWrapper;
}

var HTMLElement = window.HTMLElement;
var initDocument = debounce(function () {
  utilWalkTree(document.documentElement.childNodes, function (element) {
    var components = registry.find(element);
    var componentsLength = components.length;

    for (let a = 0; a < componentsLength; a++) {
      created(components[a]).call(element);
    }

    for (let a = 0; a < componentsLength; a++) {
      attached(components[a]).call(element);
    }
  });
});

function skate (id, userOptions) {
  let Ctor, CtorParent;
  let opts = makeOptions(userOptions);

  opts.id = id;
  opts.isNative = opts.type === typeElement && supportsCustomElements() && validCustomElement(id);
  CtorParent = opts.extends ? document.createElement(opts.extends).constructor : HTMLElement;

  // Inherit from parent prototype.
  if (!CtorParent.prototype.isPrototypeOf(opts.prototype)) {
    opts.prototype = assignSafe(Object.create(CtorParent.prototype), opts.prototype);
  }

  // Extend behaviour of existing callbacks.
  opts.prototype.createdCallback = created(opts);
  opts.prototype.attachedCallback = attached(opts);
  opts.prototype.detachedCallback = detached(opts);
  opts.prototype.attributeChangedCallback = attribute(opts);

  // Make a constructor for the definition.
  if (opts.isNative) {
    Ctor = document.registerElement(id, {
      extends: opts.extends || undefined,
      prototype: opts.prototype
    });
  } else {
    Ctor = elementConstructor(opts);
    initDocument();
    documentObserver.register();
  }

  Ctor = makeNonNewableWrapper(Ctor);
  assignSafe(Ctor, opts);
  registry.set(id, Ctor);

  return Ctor;
}

skate.create = apiCreate;
skate.emit = apiEmit;
skate.fragment = apiFragment;
skate.init = apiInit;
skate.version = apiVersion;

// ES6
export default skate;
<|endoftext|>


<commit_before>var http = require('http');
var EventProxy = require('eventproxy');
var us = require('underscore');

var config = require('../config');
var U = require('../util');
var ERR = require('../errorcode');
var db = require('../models/db');
var mGroup = require('../models/group');

exports.create = function(req, res){
    var params = req.body;

    params.creator = req.loginUser._id;

    if(U.hasRight(req.loginUser.auth, config.AUTH_MANAGER)){
        params.status = 0; // 管理员以上创建小组不用审核
    }else{
        delete params.status;
    }
    // console.log(req.loginUser.auth, config.AUTH_MANAGER, U.hasRight(req.loginUser.auth, config.AUTH_MANAGER));

    var members = params.members || [];
    var managers = params.managers || [];
    managers.push(params.creator);

    members = members.concat(managers);
    members = us.uniq(members); // 唯一化, 防止出现两个相同的用户

    var ep = new EventProxy();

    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mGroup.create(params, ep.doneLater('create'));

    ep.on('create', function(group){
        var groupId = group._id.toString();

        ep.after('applyMember', members.length, function(list){
            res.json({
                err: ERR.SUCCESS,
                result: {
                    data: group
                }
            });
        });
        members.forEach(function(member){
            // 创建者默认为小组管理员

            var auth = config.AUTH_USER;
            if(managers.indexOf(member) > -1){
                auth = config.AUTH_GROUP_MANAGER;
            }

            mGroup.addUserToGroup({
                userId: member,
                groupId: groupId,
                auth: auth
            }, ep.group('applyMember'));
        });

    });
}

exports.list = function(req, res){
    var params = req.query;

    var userId = req.loginUser._id;

    mGroup.getGroupByUser(userId, function(err, docs){
        if(err){
            res.json({ err: docs || ERR.SERVER_ERROR, msg: err});
        }else{
            res.json({
                err: ERR.SUCCESS,
                result: {
                    list: docs
                }
            });
        }

    });
}

exports.modify = function(req, res){
    var params = req.body;
    var loginUser = req.loginUser;
    var groupId = params.groupId;

    var doc = {};

    if(params.name){ // 要检查重名
        doc.name = params.name;
    }
    if(params.content){
        doc.content = params.content;
    }

    var members = params.members || [];
    var managers = params.managers || [];

    // 修改成员
    members = members.concat(managers);
    members = us.uniq(members); // 唯一化

    var ep = new EventProxy();

    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mGroup.getGroup(groupId, ep.doneLater('getGroup'));

    ep.on('getGroup', function(group){
        if(!group){
            ep.emit('error', 'no such group', ERR.NOT_FOUND);
            return;
        }
        if(U.hasRight(loginUser.auth, config.AUTH_MANAGER)){
            // 当前用户是管理员或者系统管理员
            ep.emit('ready');
        }else{
            mGroup.isGroupMember(groupId, loginUser._id, ep.done('checkAuth'));
        }
    });

    ep.on('checkAuth', function(result, doc){
        if(result && U.hasRight(doc.auth, config.AUTH_GROUP_MANAGER)){
            ep.emit('ready')
        }else{
            ep.emit('error', 'not auth to modify this group', ERR.NOT_AUTH);
        }
    });

    ep.on('ready', function(){

        mGroup.modify(params, doc, ep.done('modifySuccess'));

        mGroup.getGroupMemberIds(groupId, ep.done('getMemberIds'));

    });// ready

    ep.all('getGroup', 'getMemberIds', function(group, docs){
        var creator = group.creator.oid.toString();
        if(!docs.length){// 没有的话所有 memebers都是新增的
            if(!members.length){
                ep.emit('modifyMemberSuccess');
                return;
            }

            ep.after('applyMember', members.length, function(list){
                ep.emit('modifyMemberSuccess');
            });
            members.forEach(function(userId){

                var auth = config.AUTH_USER;
                if(managers.indexOf(userId) > -1){
                    auth = config.AUTH_GROUP_MANAGER;
                }
                mGroup.addUserToGroup({
                    userId: userId,
                    groupId: groupId,
                    auth: auth
                }, ep.group('applyMember'));

                console.log('>>>modify group add member[all]', userId);
            });

        }else{
            ep.after('modifyMember', docs.length, function(list){
                if(members.length){// 如果 members 还有数据, 说明有新增用户
                    ep.after('applyMember', members.length, function(list){
                        ep.emit('modifyMemberSuccess');
                    });
                    members.forEach(function(userId){

                        var auth = config.AUTH_USER;
                        if(managers.indexOf(userId) > -1){
                            auth = config.AUTH_GROUP_MANAGER;
                        }
                        mGroup.addUserToGroup({
                            userId: userId,
                            groupId: groupId,
                            auth: auth
                        }, ep.group('applyMember'));

                        console.log('>>>modify group add member', userId);
                    });
                }else{ //没有的话就处理完了
                    ep.emit('modifyMemberSuccess');
                }
            });

            docs.forEach(function(doc){
                var userId = doc.user.oid.toString();
                var mIndex = members.indexOf(userId);
                if(mIndex === -1){
                    //防止创建者被删掉
                    if(creator === userId){
                        ep.emit('modifyMember');
                        console.log('>>>modify group can not remove creator', userId);
                    }else{
                        // 这个用户被删了
                        mGroup.removeUserFromGroup({
                            userId: userId,
                            groupId: groupId
                        }, ep.group('modifyMember'));
                        console.log('>>>modify group remove member', userId);
                    }

                }else{
                    // 这次可能被修改了权限的用户
                    var auth = config.AUTH_USER;
                    if(managers.indexOf(member) > -1){
                        auth = config.AUTH_GROUP_MANAGER;
                    }
                    mGroup.modifyUserAuth({
                        userId: member,
                        groupId: groupId,
                        auth: auth
                    }, ep.group('modifyMember'));
                    // 从 members 里删除
                    members.splice(mIndex, 1);
                    console.log('>>>modify group change member auth', userId, auth);
                }
            });
        }
    });

    ep.all('modifySuccess', 'modifyMemberSuccess', function(doc){

        db.dereference(doc, { rootFolder: null }, function(){
            res.json({ err: ERR.SUCCESS , result: { data: doc }});
        });
    });
}

exports.get = function(req, res){
    var params = req.query;

    mGroup.getGroup(params.groupId, function(err, doc){
        if(err){
            res.json({ err: ERR.SERVER_ERROR, msg: err});
        }else if(!doc){
            res.json({ err: ERR.NOT_FOUND, msg: 'no such group'});
        }else{
            mGroup.getGroupMembers(params.groupId, true, function(err, members){
                doc.members = members;
                res.json({ err: ERR.SUCCESS , result: { data: doc }});
            });
        }
    });
}<commit_msg>bugfix<commit_after>var http = require('http');
var EventProxy = require('eventproxy');
var us = require('underscore');

var config = require('../config');
var U = require('../util');
var ERR = require('../errorcode');
var db = require('../models/db');
var mGroup = require('../models/group');

exports.create = function(req, res){
    var params = req.body;

    params.creator = req.loginUser._id;

    if(U.hasRight(req.loginUser.auth, config.AUTH_MANAGER)){
        params.status = 0; // 管理员以上创建小组不用审核
    }else{
        delete params.status;
    }
    // console.log(req.loginUser.auth, config.AUTH_MANAGER, U.hasRight(req.loginUser.auth, config.AUTH_MANAGER));

    var members = params.members || [];
    var managers = params.managers || [];
    managers.push(params.creator);

    members = members.concat(managers);
    members = us.uniq(members); // 唯一化, 防止出现两个相同的用户

    var ep = new EventProxy();

    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mGroup.create(params, ep.doneLater('create'));

    ep.on('create', function(group){
        var groupId = group._id.toString();

        ep.after('applyMember', members.length, function(list){
            res.json({
                err: ERR.SUCCESS,
                result: {
                    data: group
                }
            });
        });
        members.forEach(function(member){
            // 创建者默认为小组管理员

            var auth = config.AUTH_USER;
            if(managers.indexOf(member) > -1){
                auth = config.AUTH_GROUP_MANAGER;
            }

            mGroup.addUserToGroup({
                userId: member,
                groupId: groupId,
                auth: auth
            }, ep.group('applyMember'));
        });

    });
}

exports.list = function(req, res){
    var params = req.query;

    var userId = req.loginUser._id;

    mGroup.getGroupByUser(userId, function(err, docs){
        if(err){
            res.json({ err: docs || ERR.SERVER_ERROR, msg: err});
        }else{
            res.json({
                err: ERR.SUCCESS,
                result: {
                    list: docs
                }
            });
        }

    });
}

exports.modify = function(req, res){
    var params = req.body;
    var loginUser = req.loginUser;
    var groupId = params.groupId;

    var doc = {};

    if(params.name){ // 要检查重名
        doc.name = params.name;
    }
    if(params.content){
        doc.content = params.content;
    }

    var members = params.members || [];
    var managers = params.managers || [];

    // 修改成员
    members = members.concat(managers);
    members = us.uniq(members); // 唯一化

    var ep = new EventProxy();

    ep.fail(function(err, errCode){
        res.json({ err: errCode || ERR.SERVER_ERROR, msg: err});
    });

    mGroup.getGroup(groupId, ep.doneLater('getGroup'));

    ep.on('getGroup', function(group){
        if(!group){
            ep.emit('error', 'no such group', ERR.NOT_FOUND);
            return;
        }
        if(U.hasRight(loginUser.auth, config.AUTH_MANAGER)){
            // 当前用户是管理员或者系统管理员
            ep.emit('ready');
        }else{
            mGroup.isGroupMember(groupId, loginUser._id, ep.done('checkAuth'));
        }
    });

    ep.on('checkAuth', function(result, doc){
        if(result && U.hasRight(doc.auth, config.AUTH_GROUP_MANAGER)){
            ep.emit('ready')
        }else{
            ep.emit('error', 'not auth to modify this group', ERR.NOT_AUTH);
        }
    });

    ep.on('ready', function(){

        mGroup.modify(params, doc, ep.done('modifySuccess'));

        mGroup.getGroupMemberIds(groupId, ep.done('getMemberIds'));

    });// ready

    ep.all('getGroup', 'getMemberIds', function(group, docs){
        var creator = group.creator.oid.toString();
        if(!docs.length){// 没有的话所有 memebers都是新增的
            if(!members.length){
                ep.emit('modifyMemberSuccess');
                return;
            }

            ep.after('applyMember', members.length, function(list){
                ep.emit('modifyMemberSuccess');
            });
            members.forEach(function(userId){

                var auth = config.AUTH_USER;
                if(managers.indexOf(userId) > -1){
                    auth = config.AUTH_GROUP_MANAGER;
                }
                mGroup.addUserToGroup({
                    userId: userId,
                    groupId: groupId,
                    auth: auth
                }, ep.group('applyMember'));

                console.log('>>>modify group add member[all]', userId);
            });

        }else{
            ep.after('modifyMember', docs.length, function(list){
                if(members.length){// 如果 members 还有数据, 说明有新增用户
                    ep.after('applyMember', members.length, function(list){
                        ep.emit('modifyMemberSuccess');
                    });
                    members.forEach(function(userId){

                        var auth = config.AUTH_USER;
                        if(managers.indexOf(userId) > -1){
                            auth = config.AUTH_GROUP_MANAGER;
                        }
                        mGroup.addUserToGroup({
                            userId: userId,
                            groupId: groupId,
                            auth: auth
                        }, ep.group('applyMember'));

                        console.log('>>>modify group add member', userId);
                    });
                }else{ //没有的话就处理完了
                    ep.emit('modifyMemberSuccess');
                }
            });

            docs.forEach(function(doc){
                var userId = doc.user.oid.toString();
                var mIndex = members.indexOf(userId);
                if(mIndex === -1){
                    //防止创建者被删掉
                    if(creator === userId){
                        ep.emit('modifyMember');
                        console.log('>>>modify group can not remove creator', userId);
                    }else{
                        // 这个用户被删了
                        mGroup.removeUserFromGroup({
                            userId: userId,
                            groupId: groupId
                        }, ep.group('modifyMember'));
                        console.log('>>>modify group remove member', userId);
                    }

                }else{
                    // 这次可能被修改了权限的用户
                    var auth = config.AUTH_USER;
                    if(managers.indexOf(userId) > -1){
                        auth = config.AUTH_GROUP_MANAGER;
                    }
                    mGroup.modifyUserAuth({
                        userId: userId,
                        groupId: groupId,
                        auth: auth
                    }, ep.group('modifyMember'));
                    // 从 members 里删除
                    members.splice(mIndex, 1);
                    console.log('>>>modify group change member auth', userId, auth);
                }
            });
        }
    });

    ep.all('modifySuccess', 'modifyMemberSuccess', function(doc){

        db.dereference(doc, { rootFolder: null }, function(){
            res.json({ err: ERR.SUCCESS , result: { data: doc }});
        });
    });
}

exports.get = function(req, res){
    var params = req.query;

    mGroup.getGroup(params.groupId, function(err, doc){
        if(err){
            res.json({ err: ERR.SERVER_ERROR, msg: err});
        }else if(!doc){
            res.json({ err: ERR.NOT_FOUND, msg: 'no such group'});
        }else{
            mGroup.getGroupMembers(params.groupId, true, function(err, members){
                doc.members = members;
                res.json({ err: ERR.SUCCESS , result: { data: doc }});
            });
        }
    });
}<|endoftext|>


<commit_before>module.exports = (app) => {
  app.use(require('./auth'));
  app.use(require('./group'));
  app.use('*', (req, res) => {
    res.status(404).send('Oops! 404
Page not found
');
  });
};
<commit_msg>Add Index route<commit_after>module.exports = (app) => {
  app.get('/', (req, res) => res.status(200).send('Welcome to PostIt. Send notification to your love ones'));
  app.use(require('./auth'));
  app.use(require('./group'));
  app.use('*', (req, res) => {
    return res.status(404).send('Oops! 404
Page not found
');
  });
};
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017-2020 Mickael Jeanroy
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

'use strict';

const fs = require('fs');
const path = require('path');
const stringDecoder = require('string_decoder');
const log = require('fancy-log');
const colors = require('ansi-colors');
const PluginError = require('plugin-error');
const _ = require('lodash');
const moment = require('moment');
const commenting = require('commenting');
const through = require('through2');
const applySourceMap = require('vinyl-sourcemaps-apply');
const MagicString = require('magic-string');
const Q = require('q');

module.exports = function gulpHeaderComment(options = {}) {
  const separator = _.isObject(options) && _.isString(options.separator) ? options.separator : '\n';
  const pkgPath = path.join(process.cwd(), 'package.json');
  const pkg = fs.existsSync(pkgPath) ? require(pkgPath) : {};

  return through.obj((file, encoding, cb) => {
    if (file.isNull() || file.isDirectory()) {
      return cb(null, file);
    }

    read(options)
        .then((content) => {
          const extension = getExtension(file);
          const type = extension.slice(1);
          const header = generateHeader(content, extension, pkg);

          if (file.isBuffer()) {
            updateFileContent(file, type, header, separator);
          } else if (file.isStream()) {
            pipeFileContent(file, type, header, separator);
          }

          cb(null, file);
        })
        .catch((err) => {
          // Log error.
          log.error(colors.red(`gulp-header-comment: ${err}`));

          // Wrap error.
          cb(new PluginError('gulp-header-comment', err));
        });
  });
};

/**
 * Add header to given file content.
 *
 * @param {Object} file Original file.
 * @param {string} type File type.
 * @param {string} header Header to add to given file.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function updateFileContent(file, type, header, separator) {
  const input = file.contents.toString();
  const fname = file.relative;
  const result = transform(fname, input, type, header, separator);

  file.contents = toBuffer(result.code);

  if (file.sourceMap && result.map) {
    applySourceMap(file, result.map);
  }
}

/**
 * Stream new file content.
 *
 * @param {File} file Given input file.
 * @param {string} type The file type.
 * @param {string} header Header to add to given file.
 * @param {string} separator Separator between header and file content.
 * @return {void}
 */
function pipeFileContent(file, type, header, separator) {
  return maySkipFirstLine(type) ?
    transformFileStreamContent(file, type, header, separator) :
    prependPipeStream(file, header, separator);
}

/**
 * A very simple function that prepend header to file stream input.
 *
 * @param {File} file The original file stream.
 * @param {string} header The header to prepend to original file stream.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function prependPipeStream(file, header, separator) {
  const stream = through();
  stream.write(toBuffer(header + separator));
  file.contents = file.contents.pipe(stream);
}

/**
 * A very simple function that prepend header to file stream input.
 *
 * @param {File} file The original file stream.
 * @param {string} type File type.
 * @param {string} header The header to prepend to original file stream.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function transformFileStreamContent(file, type, header, separator) {
  file.contents = file.contents.pipe(through(function transformFunction(chunk, enc, cb) {
    const decoder = new stringDecoder.StringDecoder();
    const rawChunk = decoder.end(chunk);
    const fname = file.relative;
    const result = transform(fname, rawChunk, type, header, separator);
    const newContent = result.code;

    if (file.sourceMap && result.map) {
      applySourceMap(file, result.map);
    }

    // eslint-disable-next-line no-invalid-this
    this.push(newContent);

    cb();
  }));
}

/**
 * Get extension for given file.
 *
 * @param {Object} file The file.
 * @return {string} File extension.
 */
function getExtension(file) {
  const ext = path.extname(file.path);
  return ext ? ext.toLowerCase() : ext;
}

/**
 * Generate header from given template.
 *
 * @param {string} content Template of header.
 * @param {string} extension Target file extension.
 * @param {Object} pkg The `package.json` descriptor that will be injected when template will be evaluated.
 * @return {string} Interpolated header.
 */
function generateHeader(content, extension, pkg) {
  const templateFn = _.template(content);
  const template = templateFn({_, moment, pkg});
  return commenting(template.trim(), {extension});
}

/**
 * Add header to given file content.
 *
 * @param {string} fname File name.
 * @param {string} content Original file content.
 * @param {string} type Original file type.
 * @param {string} header The header to add.
 * @param {string} separator The separator to use between original file content and separator.
 * @return {string} The resulting file content.
 */
function transform(fname, content, type, header, separator) {
  const magicStr = new MagicString(content);

  if (!maySkipFirstLine(type)) {
    prependHeader(magicStr, header, separator);
  } else {
    const lineSeparator = '\n';
    const lines = content.split(lineSeparator);
    const firstLine = lines[0].toLowerCase();
    const trimmedFirstLine = _.trim(firstLine);

    if (!shouldSkipFirstLine(type, trimmedFirstLine)) {
      prependHeader(magicStr, header, separator);
    } else {
      magicStr.appendRight(lines[0].length, separator + separator + header);
    }
  }

  return {
    code: magicStr.toString(),
    map: magicStr.generateMap({
      file: `${fname}.map`,
      source: fname,
      includeContent: true,
      hires: true,
    }),
  };
}

/**
 * Prepend header to given file content.
 *
 * @param {MagicString} magicStr Original file content.
 * @param {string} header Header to prepend.
 * @param {string} separator The separator between header and file content.
 */
function prependHeader(magicStr, header, separator) {
  magicStr.prepend(
      header + separator
  );
}

// Set of checker function for each file type that may start with a prolog ling.
const prologCheckers = {
  /**
   * Check that given line is the `DOCTYPE` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `DOCTYPE`, `false` otherwise.
   */
  htm(line) {
    return this.html(line);
  },

  /**
   * Check that given line is the `DOCTYPE` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `DOCTYPE`, `false` otherwise.
   */
  html(line) {
    return _.startsWith(line, '<!doctype');
  },

  /**
   * Check that given line is the `XML` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `XML`, `false` otherwise.
   */
  xml(line) {
    return _.startsWith(line, '<?xml');
  },

  /**
   * Check that given line is the `XML` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `XML`, `false` otherwise.
   */
  svg(line) {
    return this.xml(line);
  },

  /**
   * Check that given line is the `JS` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an JS `#!`, `false` otherwise.
   */
  js(line) {
    return _.startsWith(line, '#!');
  },
};

/**
 * Check if given file type (`js`, `xml`, etc.) may start with a given prolog (a.k.a declaration).
 * For example, XML/SVG files may include a prolog such as `<?xml version="1.0" encoding="UTF-8"?>` and this
 * prolog must always be the first line (before anything else, including comments).
 *
 * @param {string} type File type.
 * @return {boolean} `true` if given file type may start with a prolog, `false` otherwise.
 */
function maySkipFirstLine(type) {
  return _.has(prologCheckers, type);
}

/**
 * Check if given line should be skipped before adding header content.
 *
 * @param {string} type File type.
 * @param {string} line The first line of given file.
 * @return {boolean} `true` if given line should be skipped, `false` otherwise.
 */
function shouldSkipFirstLine(type, line) {
  return prologCheckers[type](line);
}

/**
 * Read file specified by given options.
 *
 * @param {Object} options Read options.
 * @return {Promise<string>} A promise resolved with file content.
 */
function read(options) {
  if (_.isString(options)) {
    return Q.when(options);
  }

  const file = options.file;
  const encoding = options.encoding || 'utf-8';
  const deferred = Q.defer();

  fs.readFile(file, {encoding}, (err, data) => {
    return err ? deferred.reject(err) : deferred.resolve(data);
  });

  return deferred.promise;
}

/**
 * Creates a new Buffer containing string.
 *
 * @param {string} rawString The string content.
 * @return {Buffer} Node Buffer.
 */
function toBuffer(rawString) {
  return Buffer.from ? Buffer.from(rawString) : new Buffer(rawString);
}
<commit_msg>fix: fix default encoding, use what is provided by through2 pkg<commit_after>/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2017-2020 Mickael Jeanroy
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

'use strict';

const fs = require('fs');
const path = require('path');
const stringDecoder = require('string_decoder');
const log = require('fancy-log');
const colors = require('ansi-colors');
const PluginError = require('plugin-error');
const _ = require('lodash');
const moment = require('moment');
const commenting = require('commenting');
const through = require('through2');
const applySourceMap = require('vinyl-sourcemaps-apply');
const MagicString = require('magic-string');
const Q = require('q');

module.exports = function gulpHeaderComment(options = {}) {
  const separator = _.isObject(options) && _.isString(options.separator) ? options.separator : '\n';
  const pkgPath = path.join(process.cwd(), 'package.json');
  const pkg = fs.existsSync(pkgPath) ? require(pkgPath) : {};

  return through.obj((file, encoding, cb) => {
    if (file.isNull() || file.isDirectory()) {
      return cb(null, file);
    }

    read(options, encoding)
        .then((content) => {
          const extension = getExtension(file);
          const type = extension.slice(1);
          const header = generateHeader(content, extension, pkg);

          if (file.isBuffer()) {
            updateFileContent(file, type, header, separator);
          } else if (file.isStream()) {
            pipeFileContent(file, type, header, separator);
          }

          cb(null, file);
        })
        .catch((err) => {
          // Log error.
          log.error(colors.red(`gulp-header-comment: ${err}`));

          // Wrap error.
          cb(new PluginError('gulp-header-comment', err));
        });
  });
};

/**
 * Add header to given file content.
 *
 * @param {Object} file Original file.
 * @param {string} type File type.
 * @param {string} header Header to add to given file.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function updateFileContent(file, type, header, separator) {
  const input = file.contents.toString();
  const fname = file.relative;
  const result = transform(fname, input, type, header, separator);

  file.contents = toBuffer(result.code);

  if (file.sourceMap && result.map) {
    applySourceMap(file, result.map);
  }
}

/**
 * Stream new file content.
 *
 * @param {File} file Given input file.
 * @param {string} type The file type.
 * @param {string} header Header to add to given file.
 * @param {string} separator Separator between header and file content.
 * @return {void}
 */
function pipeFileContent(file, type, header, separator) {
  return maySkipFirstLine(type) ?
    transformFileStreamContent(file, type, header, separator) :
    prependPipeStream(file, header, separator);
}

/**
 * A very simple function that prepend header to file stream input.
 *
 * @param {File} file The original file stream.
 * @param {string} header The header to prepend to original file stream.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function prependPipeStream(file, header, separator) {
  const stream = through();
  stream.write(toBuffer(header + separator));
  file.contents = file.contents.pipe(stream);
}

/**
 * A very simple function that prepend header to file stream input.
 *
 * @param {File} file The original file stream.
 * @param {string} type File type.
 * @param {string} header The header to prepend to original file stream.
 * @param {string} separator The separator to use between header and file content.
 * @return {void}
 */
function transformFileStreamContent(file, type, header, separator) {
  file.contents = file.contents.pipe(through(function transformFunction(chunk, enc, cb) {
    const decoder = new stringDecoder.StringDecoder();
    const rawChunk = decoder.end(chunk);
    const fname = file.relative;
    const result = transform(fname, rawChunk, type, header, separator);
    const newContent = result.code;

    if (file.sourceMap && result.map) {
      applySourceMap(file, result.map);
    }

    // eslint-disable-next-line no-invalid-this
    this.push(newContent);

    cb();
  }));
}

/**
 * Get extension for given file.
 *
 * @param {Object} file The file.
 * @return {string} File extension.
 */
function getExtension(file) {
  const ext = path.extname(file.path);
  return ext ? ext.toLowerCase() : ext;
}

/**
 * Generate header from given template.
 *
 * @param {string} content Template of header.
 * @param {string} extension Target file extension.
 * @param {Object} pkg The `package.json` descriptor that will be injected when template will be evaluated.
 * @return {string} Interpolated header.
 */
function generateHeader(content, extension, pkg) {
  const templateFn = _.template(content);
  const template = templateFn({_, moment, pkg});
  return commenting(template.trim(), {extension});
}

/**
 * Add header to given file content.
 *
 * @param {string} fname File name.
 * @param {string} content Original file content.
 * @param {string} type Original file type.
 * @param {string} header The header to add.
 * @param {string} separator The separator to use between original file content and separator.
 * @return {string} The resulting file content.
 */
function transform(fname, content, type, header, separator) {
  const magicStr = new MagicString(content);

  if (!maySkipFirstLine(type)) {
    prependHeader(magicStr, header, separator);
  } else {
    const lineSeparator = '\n';
    const lines = content.split(lineSeparator);
    const firstLine = lines[0].toLowerCase();
    const trimmedFirstLine = _.trim(firstLine);

    if (!shouldSkipFirstLine(type, trimmedFirstLine)) {
      prependHeader(magicStr, header, separator);
    } else {
      magicStr.appendRight(lines[0].length, separator + separator + header);
    }
  }

  return {
    code: magicStr.toString(),
    map: magicStr.generateMap({
      file: `${fname}.map`,
      source: fname,
      includeContent: true,
      hires: true,
    }),
  };
}

/**
 * Prepend header to given file content.
 *
 * @param {MagicString} magicStr Original file content.
 * @param {string} header Header to prepend.
 * @param {string} separator The separator between header and file content.
 */
function prependHeader(magicStr, header, separator) {
  magicStr.prepend(
      header + separator
  );
}

// Set of checker function for each file type that may start with a prolog ling.
const prologCheckers = {
  /**
   * Check that given line is the `DOCTYPE` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `DOCTYPE`, `false` otherwise.
   */
  htm(line) {
    return this.html(line);
  },

  /**
   * Check that given line is the `DOCTYPE` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `DOCTYPE`, `false` otherwise.
   */
  html(line) {
    return _.startsWith(line, '<!doctype');
  },

  /**
   * Check that given line is the `XML` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `XML`, `false` otherwise.
   */
  xml(line) {
    return _.startsWith(line, '<?xml');
  },

  /**
   * Check that given line is the `XML` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an HTML `XML`, `false` otherwise.
   */
  svg(line) {
    return this.xml(line);
  },

  /**
   * Check that given line is the `JS` line.
   *
   * @param {string} line The line to check.
   * @return {boolean} `true` if given is an JS `#!`, `false` otherwise.
   */
  js(line) {
    return _.startsWith(line, '#!');
  },
};

/**
 * Check if given file type (`js`, `xml`, etc.) may start with a given prolog (a.k.a declaration).
 * For example, XML/SVG files may include a prolog such as `<?xml version="1.0" encoding="UTF-8"?>` and this
 * prolog must always be the first line (before anything else, including comments).
 *
 * @param {string} type File type.
 * @return {boolean} `true` if given file type may start with a prolog, `false` otherwise.
 */
function maySkipFirstLine(type) {
  return _.has(prologCheckers, type);
}

/**
 * Check if given line should be skipped before adding header content.
 *
 * @param {string} type File type.
 * @param {string} line The first line of given file.
 * @return {boolean} `true` if given line should be skipped, `false` otherwise.
 */
function shouldSkipFirstLine(type, line) {
  return prologCheckers[type](line);
}

/**
 * Read file specified by given options.
 *
 * @param {Object} options Read options.
 * @param {string} defaultEncoding The default encoding to use.
 * @return {Promise<string>} A promise resolved with file content.
 */
function read(options, defaultEncoding) {
  if (_.isString(options)) {
    return Q.when(options);
  }

  const file = options.file;
  const encoding = options.encoding || defaultEncoding || 'utf-8';
  const deferred = Q.defer();

  fs.readFile(file, {encoding}, (err, data) => {
    return err ? deferred.reject(err) : deferred.resolve(data);
  });

  return deferred.promise;
}

/**
 * Creates a new Buffer containing string.
 *
 * @param {string} rawString The string content.
 * @return {Buffer} Node Buffer.
 */
function toBuffer(rawString) {
  return Buffer.from ? Buffer.from(rawString) : new Buffer(rawString);
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var path = require('path')

// This is returned as the module
var indexRoute = {
    changePage: null,
    router: router
}

router.route('/')
    .get(function (req, res) {
        res.render('main/index', {
            pageId: "Home",
            pageTitle: "Home Control",
            pageDescription: "Home Control's landing page.",
            pageCss: ['main'],
            pageScripts: ['dummyScript'],
            useBootstrap: true
        });
    });

router.route('/switcher')
    .get(isLoggedIn, function (req, res) {
        res.render('main/switcher', {
            pageId: "Switcher",
            pageTitle: "Home Control Switcher",
            pageDescription: "Home Control's switcher page.",
            pageCss: ['main'],
            pageScripts: ['switcher'],
            useBootstrap: true,
            useSocket: true,
            userID: req.session.passport.user
        });
    });

router.route('/viewer')
    .get(isLoggedIn, function (req, res) {
        res.render('main/viewer', {
            pageId: "Viewer",
            pageTitle: "Home Control",
            pageDescription: "Home Control's viewing page.",
            pageCss: ['main'],
            pageScripts: ['viewer'],
            useBootstrap: true,
            useSocket: true,
            userID: req.session.passport.user
        });
    });

router.post('/switch', function(req, res) {
    let page = req.body.result.parameters.page;
    indexRoute.changePage(page);
    res.json({
        "speech": "Showing " + page,
        "speech": "Showing " + page,
        "data": {},
        "contextOut": [],
        "source": "Home.CarlSchriever.com"
    });
});

function isLoggedIn(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/user/login');
}

module.exports = function(changePage) {
    indexRoute.changePage = changePage;

    return indexRoute;
};<commit_msg>No user response<commit_after>var express = require('express');
var router = express.Router();
var path = require('path')

// This is returned as the module
var indexRoute = {
    changePage: null,
    router: router
}

router.route('/')
    .get(function (req, res) {
        res.render('main/index', {
            pageId: "Home",
            pageTitle: "Home Control",
            pageDescription: "Home Control's landing page.",
            pageCss: ['main'],
            pageScripts: ['dummyScript'],
            useBootstrap: true
        });
    });

router.route('/switcher')
    .get(isLoggedIn, function (req, res) {
        res.render('main/switcher', {
            pageId: "Switcher",
            pageTitle: "Home Control Switcher",
            pageDescription: "Home Control's switcher page.",
            pageCss: ['main'],
            pageScripts: ['switcher'],
            useBootstrap: true,
            useSocket: true,
            userID: req.session.passport.user
        });
    });

router.route('/viewer')
    .get(isLoggedIn, function (req, res) {
        res.render('main/viewer', {
            pageId: "Viewer",
            pageTitle: "Home Control",
            pageDescription: "Home Control's viewing page.",
            pageCss: ['main'],
            pageScripts: ['viewer'],
            useBootstrap: true,
            useSocket: true,
            userID: req.session.passport.user
        });
    });

router.post('/switch', function(req, res) {
    let page = req.body.result.parameters.page;
    indexRoute.changePage(page);
    res.json({
        "speech": "Showing " + page,
        "speech": "Showing " + page,
        "data": {},
        "contextOut": [],
        "expectUserResponse": false,
        "source": "Home.CarlSchriever.com"
    });
});

function isLoggedIn(req, res, next) {
    if (req.isAuthenticated()) {
        return next();
    }
    res.redirect('/user/login');
}

module.exports = function(changePage) {
    indexRoute.changePage = changePage;

    return indexRoute;
};<|endoftext|>