<commit_before>import { paramByApp } from '../data/dictionaryHelper';

const params = require('./parameters');

function paramToNames(p) {
  const countsAndDetails = paramByApp(p);
  const boardPluralNames = countsAndDetails.boardCounts.map(item => item.plural);
  if (boardPluralNames.length < 4) { boardPluralNames.push('Files'); }
  const detailPluralNames = countsAndDetails.projectDetails.map(item => item.plural);
  if (detailPluralNames.length < 4) { detailPluralNames.push('Files'); }
  return {
    boardPluralNames,
    chartNames: countsAndDetails.chartCounts.map(item => item.name),
    detailPluralNames,
  };
}

/**
 * Setup configuration variables based on the "app" the data-portal is
 * being deployed into (Brain Health Commons, Blood Pack, ...)
 *
 * @param {app, dev, basename, mockStore, hostname} opts overrides for defaults
 */
function buildConfig(opts) {
  const defaults = {
    dev: !!(process.env.NODE_ENV && process.env.NODE_ENV === 'dev'),
    mockStore: !!(process.env.MOCK_STORE && process.env.MOCK_STORE === 'true'),
    app: process.env.APP || 'generic',
    basename: process.env.BASENAME || '/',
    hostname: typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.hostname}/` : 'http://localhost/',
  };

  //
  // Override default basename if loading via /dev.html
  // dev.html loads bundle.js via https://localhost...
  //
  if (typeof location !== 'undefined' && location.pathname.indexOf(`${defaults.basename}dev.html`) === 0) {
    defaults.basename += 'dev.html';
  }

  const { dev, mockStore, app, basename, hostname } = Object.assign({}, defaults, opts);

  const submissionApiPath = `${hostname}api/v0/submission/`;
  const apiPath = `${hostname}api/`;
  const submissionApiOauthPath = `${hostname}api/v0/oauth2/`;
  // let credentialOauthPath = `${hostname}middleware/oauth2/v0/`;
  const graphqlPath = `${hostname}api/v0/submission/graphql/`;
  let userapiPath = `${hostname}user/`;
  let credentialCdisPath = `${userapiPath}credentials/cdis/`;
  let login = {
    url: `${userapiPath}login/google?redirect=`,
    title: 'Login from Google',
  };
  const loginPath = `${userapiPath}login/`;
  const graphqlSchemaUrl = `${hostname}data/schema.json`;
  // let credentialPath = `${hostname}middleware/aws/v0/access_key/`;

  let appname = 'Unasigned';
  let navItems = [];
  let dashboardIcons = [
    'account_circle',
    'receipt',
    'invert_colors',
    'description',
  ];
  let localTheme = {
    'barGraph.lineColor': '#666666',
    'barGraph.bar1Color': '#8884d8',
    'barGraph.bar2Color': '#82ca9d',
    'summary.borderTopColor': '#c87152',
    'summary.borderColor': '#222222',
    'summary.countColor': '#ff4200',
    'summary.iconColor': '#008000',
    'projectTable.summaryRowColor': '#eeeeee',
    'projectTable.submitButtonColor': '#dddddd',
    tableBarColor: '#7d7474',
  };
  const requiredCerts = [];
  const homepageParams = paramToNames(params);

  if (app === 'bpa') {
    appname = 'BloodPAC Metadata Submission Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'gtex') {
    appname = 'NIH Data Commons Consortium Pilot Phase\nGTEx & TOPMed Data Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'collections', link: `${hostname}dcp`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}jupyter`, color: '#a2a2a2', name: 'workspace' },
    ];
  } else if (app === 'edc') {
    appname = 'Environmental Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
    ];
    dashboardIcons = [
      'satellite',
      'track_changes',
      'description',
      'timeline',
    ];
  } else if (app === 'kf') {
    appname = 'Gabriella Miller Kids First Pediatric Data Coordinating Center Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#A51C30', name: 'home' },
      { icon: 'search', link: '/query', color: '#2D728F', name: 'query' },
      { icon: 'class', link: '/DD', color: '#A51C30', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#2D728F', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#A51C30', name: 'data' },
    ];
    localTheme = {
      'barGraph.lineColor': '#DFDFDF',
      'barGraph.bar1Color': '#00ADEE',
      'barGraph.bar2Color': '#BE1E2D',
      'summary.borderTopColor': '#F6921E',
      'summary.borderColor': '#DFDFDF',
      'summary.countColor': '#F6921E',
      'summary.iconColor': '#00ADEE',
      'projectTable.summaryRowColor': '#DFDFDF',
      'projectTable.submitButtonColor': '#DFDFDF',
      tableBarColor: '#CC3399',
    };
  } else if (app === 'bhc') {
    appname = 'The Brain Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#A51C30', name: 'home' },
      { icon: 'collections', link: `${hostname}bhc`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#2D728F', name: 'query' },
      { icon: 'class', link: '/DD', color: '#A51C30', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#2D728F', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#A51C30', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
      { icon: 'dvr', link: 'https://demo.braincommons.org/', color: '#a2a2a2', name: 'demo' },
    ];
    localTheme = {
      'barGraph.lineColor': '#666666',
      'barGraph.bar1Color': '#6193b1',
      'barGraph.bar2Color': '#94af83',
      'summary.borderTopColor': '#94af83',
      'summary.borderColor': '#222222',
      'summary.countColor': '#d00000',
      'summary.iconColor': '#7aa19b',
      'projectTable.summaryRowColor': '#565656',
      'projectTable.submitButtonColor': '#dddddd',
      tableBarColor: '#7d7474',
    };
  } else if (app === 'acct') {
    appname = 'ACCOuNT Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'genomel') {
    appname = 'GenoMEL Data Commons Portal';
    const userapiPathOut = 'https://login.bionimbus.org/';
    credentialCdisPath = `${userapiPath}credentials/cdis/`;
    // login = {
    //   url: `${userapiPathOut}login/shib?redirect=`,
    //   title: 'Login from NIH',
    // };
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'ndh') {
    appname = 'NIAID Data Hub Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'collections', link: `${hostname}ndh`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#daa5Z20', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
    ];
  } else if (app === 'gdc') {
    userapiPath = dev === true ? `${hostname}user/` : `${hostname}api/`;
    // credentialPath = `${userapiPath}credentials/cleversafe/`;
    // credentialOauthPath = `${userapiPath}oauth2/`;
    appname = 'GDC Jamboree Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
    ];
    login = {
      url: 'https://itrusteauth.nih.gov/affwebservices/public/saml2sso?SPID=https://bionimbus-pdc.opensciencedatacloud.org/shibboleth&RelayState=',
      title: 'Login from NIH',
    };
  } else {
    appname = 'Generic Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#1d3674', name: 'home' },
      { icon: 'search', link: '/query', color: '#ad7e1c', name: 'query' },
      { icon: 'class', link: '/DD', color: '#1d3674', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#1d3674', name: 'data' },
    ];
  }

  const conf = {
    dev,
    mockStore,
    app,
    basename,
    hostname,
    userapiPath,
    apiPath,
    submissionApiPath,
    submissionApiOauthPath,
    credentialCdisPath,
    graphqlPath,
    graphqlSchemaUrl,
    appname,
    navItems,
    boardPluralNames: homepageParams.boardPluralNames,
    chartNames: homepageParams.chartNames,
    detailPluralNames: homepageParams.detailPluralNames,
    dashboardIcons,
    localTheme,
    login,
    loginPath,
    requiredCerts,
    buildConfig,
  };
  return conf;
}

const defaultConf = buildConfig();
// Commonjs style export, so can load from nodejs into data/gqlSetup
module.exports = defaultConf;
<commit_msg>feat(urls): Update urls for better commonality (#264)<commit_after>import { paramByApp } from '../data/dictionaryHelper';

const params = require('./parameters');

function paramToNames(p) {
  const countsAndDetails = paramByApp(p);
  const boardPluralNames = countsAndDetails.boardCounts.map(item => item.plural);
  if (boardPluralNames.length < 4) { boardPluralNames.push('Files'); }
  const detailPluralNames = countsAndDetails.projectDetails.map(item => item.plural);
  if (detailPluralNames.length < 4) { detailPluralNames.push('Files'); }
  return {
    boardPluralNames,
    chartNames: countsAndDetails.chartCounts.map(item => item.name),
    detailPluralNames,
  };
}

/**
 * Setup configuration variables based on the "app" the data-portal is
 * being deployed into (Brain Health Commons, Blood Pack, ...)
 *
 * @param {app, dev, basename, mockStore, hostname} opts overrides for defaults
 */
function buildConfig(opts) {
  const defaults = {
    dev: !!(process.env.NODE_ENV && process.env.NODE_ENV === 'dev'),
    mockStore: !!(process.env.MOCK_STORE && process.env.MOCK_STORE === 'true'),
    app: process.env.APP || 'generic',
    basename: process.env.BASENAME || '/',
    hostname: typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.hostname}/` : 'http://localhost/',
  };

  //
  // Override default basename if loading via /dev.html
  // dev.html loads bundle.js via https://localhost...
  //
  if (typeof location !== 'undefined' && location.pathname.indexOf(`${defaults.basename}dev.html`) === 0) {
    defaults.basename += 'dev.html';
  }

  const { dev, mockStore, app, basename, hostname } = Object.assign({}, defaults, opts);

  const submissionApiPath = `${hostname}api/v0/submission/`;
  const apiPath = `${hostname}api/`;
  const submissionApiOauthPath = `${hostname}api/v0/oauth2/`;
  // let credentialOauthPath = `${hostname}middleware/oauth2/v0/`;
  const graphqlPath = `${hostname}api/v0/submission/graphql/`;
  let userapiPath = `${hostname}user/`;
  let credentialCdisPath = `${userapiPath}credentials/cdis/`;
  let login = {
    url: `${userapiPath}login/google?redirect=`,
    title: 'Login from Google',
  };
  const loginPath = `${userapiPath}login/`;
  const graphqlSchemaUrl = `${hostname}data/schema.json`;
  // let credentialPath = `${hostname}middleware/aws/v0/access_key/`;

  let appname = 'Unasigned';
  let navItems = [];
  let dashboardIcons = [
    'account_circle',
    'receipt',
    'invert_colors',
    'description',
  ];
  let localTheme = {
    'barGraph.lineColor': '#666666',
    'barGraph.bar1Color': '#8884d8',
    'barGraph.bar2Color': '#82ca9d',
    'summary.borderTopColor': '#c87152',
    'summary.borderColor': '#222222',
    'summary.countColor': '#ff4200',
    'summary.iconColor': '#008000',
    'projectTable.summaryRowColor': '#eeeeee',
    'projectTable.submitButtonColor': '#dddddd',
    tableBarColor: '#7d7474',
  };
  const requiredCerts = [];
  const homepageParams = paramToNames(params);

  if (app === 'bpa') {
    appname = 'BloodPAC Metadata Submission Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'gtex') {
    appname = 'NIH Data Commons Consortium Pilot Phase\nGTEx & TOPMed Data Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'collections', link: `${hostname}shiny/`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
    ];
  } else if (app === 'edc') {
    appname = 'Environmental Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
    ];
    dashboardIcons = [
      'satellite',
      'track_changes',
      'description',
      'timeline',
    ];
  } else if (app === 'kf') {
    appname = 'Gabriella Miller Kids First Pediatric Data Coordinating Center Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#A51C30', name: 'home' },
      { icon: 'search', link: '/query', color: '#2D728F', name: 'query' },
      { icon: 'class', link: '/DD', color: '#A51C30', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#2D728F', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#A51C30', name: 'data' },
    ];
    localTheme = {
      'barGraph.lineColor': '#DFDFDF',
      'barGraph.bar1Color': '#00ADEE',
      'barGraph.bar2Color': '#BE1E2D',
      'summary.borderTopColor': '#F6921E',
      'summary.borderColor': '#DFDFDF',
      'summary.countColor': '#F6921E',
      'summary.iconColor': '#00ADEE',
      'projectTable.summaryRowColor': '#DFDFDF',
      'projectTable.submitButtonColor': '#DFDFDF',
      tableBarColor: '#CC3399',
    };
  } else if (app === 'bhc') {
    appname = 'The Brain Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#A51C30', name: 'home' },
      { icon: 'collections', link: `${hostname}shiny/`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#2D728F', name: 'query' },
      { icon: 'class', link: '/DD', color: '#A51C30', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#2D728F', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#A51C30', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
      { icon: 'dvr', link: 'https://demo.braincommons.org/', color: '#a2a2a2', name: 'demo' },
    ];
    localTheme = {
      'barGraph.lineColor': '#666666',
      'barGraph.bar1Color': '#6193b1',
      'barGraph.bar2Color': '#94af83',
      'summary.borderTopColor': '#94af83',
      'summary.borderColor': '#222222',
      'summary.countColor': '#d00000',
      'summary.iconColor': '#7aa19b',
      'projectTable.summaryRowColor': '#565656',
      'projectTable.submitButtonColor': '#dddddd',
      tableBarColor: '#7d7474',
    };
  } else if (app === 'acct') {
    appname = 'ACCOuNT Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'genomel') {
    appname = 'GenoMEL Data Commons Portal';
    const userapiPathOut = 'https://login.bionimbus.org/';
    credentialCdisPath = `${userapiPath}credentials/cdis/`;
    // login = {
    //   url: `${userapiPathOut}login/shib?redirect=`,
    //   title: 'Login from NIH',
    // };
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'search', link: '/query', color: '#daa520', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
    ];
  } else if (app === 'ndh') {
    appname = 'NIAID Data Hub Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
      { icon: 'collections', link: `${hostname}shiny/`, color: '#a2a2a2', name: 'exploration' },
      { icon: 'search', link: '/query', color: '#daa5Z20', name: 'query' },
      { icon: 'class', link: '/DD', color: '#a2a2a2', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#a2a2a2', name: 'data' },
      { icon: 'dvr', link: `${hostname}workspace/`, color: '#a2a2a2', name: 'workspace' },
    ];
  } else if (app === 'gdc') {
    userapiPath = dev === true ? `${hostname}user/` : `${hostname}api/`;
    // credentialPath = `${userapiPath}credentials/cleversafe/`;
    // credentialOauthPath = `${userapiPath}oauth2/`;
    appname = 'GDC Jamboree Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#a2a2a2', name: 'home' },
    ];
    login = {
      url: 'https://itrusteauth.nih.gov/affwebservices/public/saml2sso?SPID=https://bionimbus-pdc.opensciencedatacloud.org/shibboleth&RelayState=',
      title: 'Login from NIH',
    };
  } else {
    appname = 'Generic Data Commons Portal';
    navItems = [
      { icon: 'home', link: '/', color: '#1d3674', name: 'home' },
      { icon: 'search', link: '/query', color: '#ad7e1c', name: 'query' },
      { icon: 'class', link: '/DD', color: '#1d3674', name: 'dictionary' },
      { icon: 'face', link: '/identity', color: '#daa520', name: 'profile' },
      { icon: 'content_copy', link: '/files', color: '#1d3674', name: 'data' },
    ];
  }

  const conf = {
    dev,
    mockStore,
    app,
    basename,
    hostname,
    userapiPath,
    apiPath,
    submissionApiPath,
    submissionApiOauthPath,
    credentialCdisPath,
    graphqlPath,
    graphqlSchemaUrl,
    appname,
    navItems,
    boardPluralNames: homepageParams.boardPluralNames,
    chartNames: homepageParams.chartNames,
    detailPluralNames: homepageParams.detailPluralNames,
    dashboardIcons,
    localTheme,
    login,
    loginPath,
    requiredCerts,
    buildConfig,
  };
  return conf;
}

const defaultConf = buildConfig();
// Commonjs style export, so can load from nodejs into data/gqlSetup
module.exports = defaultConf;
<|endoftext|>


<commit_before>define(function() {

return {

  // The following palette description
  // is copied from compiled CoffeeScript.
  COFFEESCRIPT_PALETTE: [
    {
      name: 'Move',
      color: 'red',
      blocks: [
        {
          block: 'fd 100',
          title: 'Move forward'
        }, {
          block: 'rt 90',
          title: 'Turn right'
        }, {
          block: 'lt 90',
          title: 'Turn left'
        }, {
          block: 'bk 100',
          title: 'Move backward'
        }, {
          block: 'rt 180, 100',
          title: 'Make a wide right arc'
        }, {
          block: 'lt 180, 100',
          title: 'Make a wide left arc'
        }, {
          block: 'speed 10',
          title: 'Set the speed of the turtle'
        }, {
          block: 'speed Infinity',
          title: 'Use infinite speed'
        }, {
          block: 'home()',
          title: 'Jump to the origin, turned up'
        }, {
          block: 'turnto 270',
          title: 'Turn to an absolute direction'
        }, {
          block: 'turnto lastclick',
          title: 'Turn toward a located object'
        }, {
          block: 'moveto 100, 50',
          title: 'Move to coordinates'
        }, {
          block: 'movexy 30, 20',
          title: 'Move by changing x and y'
        }, {
          block: 'move 10, 5',
          title: "Move sideways or diagonal from turtle's angle"
        }, {
          block: 'jumpto 100, 50',
          title: 'Jump to coordinates without drawing'
        }, {
          block: 'jumpxy 30, 20',
          title: 'Jump changing x and y without drawing'
        }, {
          block: 'jump 10, 5',
          title: "Move sideways or diagonal without drawing"
        }
      ]
    }, {
      name: 'Control',
      color: 'orange',
      blocks: [
        {
          block: 'for [1..3]\n  ``',
          title: 'Do something multiple times'
        }, {
          block: 'for x in [1..3]\n  ``',
          title: 'Do something multiple times...?'
        }, {
          block: 'if `` is ``\n  ``',
          title: 'Do something only if a condition is true'
        }, {
          block: 'if `` is ``\n  ``\nelse\n  ``',
          title: 'Do something if a condition is true, otherwise something else'
        }, {
          block: "tick 1, ->\n  write 'ticked'",
          title: 'Repeat something forever at qually-spaced times'
        }, {
          block: "button \'Click\', ->\n  write 'clicked'",
          title: 'Make a button and do something when clicked'
        }, {
          block: "keydown \'X\', ->\n  write 'x pressed'",
          title: 'Do something when a keyboard key is pressed'
        }, {
          block: "click (e) ->\n  moveto e",
          title: 'Move to a location when document is clicked'
        }
      ]
    }, {
      name: 'Draw',
      color: 'blue',
      blocks: [
        {
          block: 'pen purple, 10',
          title: 'Set pen color and size'
        }, {
          block: 'dot green, 50',
          title: 'Make a dot'
        }, {
          block: 'box yellow, 50',
          title: 'Make a square'
        }, {
          block: 'fill blue',
          title: 'Fill traced shape'
        }, {
          block: 'cs()',
          title: 'Clear screen'
        }, {
          block: 'cg()',
          title: 'Clear graphics'
        }, {
          block: 'pu()',
          title: 'Lift the pen up'
        }, {
          block: 'pd()',
          title: 'Put the pen down'
        }, {
          block: 'scale 3',
          title: 'Scale turtle drawing'
        }
      ]
    }, {
      name: 'Math',
      color: 'green',
      blocks: [
        {
          block: 'x = ``',
          title: 'Set a variable'
        }, {
          block: '`` + ``',
          title: 'Add two numbers'
        }, {
          block: '`` - ``',
          title: 'Subtract two numbers'
        }, {
          block: '`` * ``',
          title: 'Multiply two numbers'
        }, {
          block: '`` / ``',
          title: 'Divide two numbers'
        }, {
          block: '`` is ``',
          title: 'Compare two values'
        }, {
          block: '`` < ``',
          title: 'Compare two values'
        }, {
          block: '`` > ``',
          title: 'Compare two values'
        }, {
          block: 'random [1..100]',
          title: 'Get a random number in a range'
        }, {
          block: 'round ``',
          title: 'Round to the nearest integer'
        }, {
          block: 'abs ``',
          title: 'Absolute value'
        }, {
          block: 'max ``, ``',
          title: 'Get the larger of two numbers'
        }, {
          block: 'min ``, ``',
          title: 'Get the smaller on two numbers'
        }, {
          block: 'text.match /pattern/',
          title: 'Test if pattern is found in text'
        }, {
          block: 'f = (param) ->\n  ``',
          title: 'Define a new function'
        }, {
          block: 'myfunc(arg)',
          title: 'Use a custom function'
        }
      ]
    }, {
      name: 'Text',
      color: 'yellow',
      blocks: [
        {
          block: 'write \'Hello.\'',
          title: 'Write text in the document'
        }, {
          block: 'type \'zz*(-.-)*zz\'',
          title: 'Typewrite text in the document'
        }, {
          block: 'label \'spot\'',
          title: 'Write text at the turtle'
        }, {
          block: 'read \'\?\', (x) ->\x  write x,
          title: 'Read input from the user'
        }, {
          block: 'readnum \'Side\', (n) ->\n  write \'A\' + n * n',
          title: 'Read a number from the user'
        }, {
          block: 'readstr \'Idea?\', (n) ->\n  write n.length',
          title: 'Read a whole line of text'
        }, {
          block: "table [\n  ['a','b','c']\n  [1,2,3]\n]",
          title: 'Write a table in the document'
        }, {
          block: 'log [1..10]',
          title: 'Log an object to debug'
        }, {
          block: 'd = write \'dice\'',
          title: 'Remember d as a text element'
        }, {
          block: 'tick 1, ->\n  d.text random [1..6]',
          title: 'Change d text content'
        }
      ]
    }, {
      name: 'Sprites',
      color: 'violet',
      blocks: [
        {
          block: 'wear \'/img/apple\'',
          title: 'Use an image for the turtle'
        }, {
          block: 't = new Turtle red',
          title: 'Make a new turtle'
        }, {
          block: 't.fd 100',
          title: 'Move turtle t forward'
        }, {
          block: 't.rt 90',
          title: 'Turn turtle t right'
        }, {
          block: 't.lt 90',
          title: 'Turn turtle t left'
        }, {
          block: 't.bk 100',
          title: 'Move turtle t backward'
        }, {
          block: 'ht()',
          title: 'Hide the main turtle'
        }, {
          block: 'st()',
          title: 'Show the main turtle'
        }, {
          block: 's = new Sprite',
          title: 'Make a blank sprite'
        }, {
          block: 's.wear \'/img/dragon\'',
          title: 'Load an image in sprite s'
        }, {
          block: 'drawon s',
          title: 'Draw on sprite s'
        }, {
          block: 'drawon document',
          title: 'Draw on the document'
        }, {
          block: 'p = new Piano',
          title: 'Make a visible insturment'
        }, {
          block: 'p.play \'CDEDC\'',
          title: 'Play and show music notes'
        }, {
          block: 'q = new Pencil',
          title: 'Make an invisible and fast drawing sprite'
        }, {
          block: 'q.pen black, 1',
          title: 'Use a thin black pen'
        }, {
          block: 'q.drawon s',
          title: 'Use q to draw on sprite s'
        }, {
          block: 'q.rt 360, 100',
          title: 'Trace a circle on the right'
        }, {
          block: 'q.lt 360, 100',
          title: 'Trace a circle on the left'
        }, {
          block: 'q.fill pink',
          title: 'Fill the traced path'
        }
      ]
    }
  ],

  JAVASCRIPT_PALETTE: [
    {
      name: 'Draw',
      color: 'blue',
      blocks: [
        {
          block: 'pen(red);',
          title: 'Set the pen color'
        }, {
          block: 'fd(100);',
          title: 'Move forward'
        }, {
          block: 'rt(90);',
          title: 'Turn right'
        }, {
          block: 'lt(90);',
          title: 'Turn left'
        }, {
          block: 'bk(100);',
          title: 'Move backward'
        }, {
          block: 'speed(10);',
          title: 'Set the speed of the turtle'
        }, {
          block: 'dot(blue, 50);',
          title: 'Make a dot'
        }, {
          block: 'box(green, 50);',
          title: 'Make a square'
        }, {
          block: 'write(\'hello\');',
          title: 'Write text on the screen'
        }, {
          block: 'label(\'hello\');',
          title: 'Write text at the turtle'
        }, {
          block: 'ht();',
          title: 'Hide the turtle'
        }, {
          block: 'st();',
          title: 'Show the turtle'
        }, {
          block: 'pu();',
          title: 'Pick the pen up'
        }, {
          block: 'pd();',
          title: 'Put the pen down'
        }, {
          block: 'pen(purple, 10);',
          title: 'Set the pen color and thickness'
        }, {
          block: 'rt(180, 100);',
          title: 'Make a wide right turn'
        }, {
          block: 'lt(180, 100);',
          title: 'Make a wide left turn'
        }, {
          block: 'slide(100, 20);',
          title: 'Slide sideways or diagonally'
        }, {
          block: 'jump(100, 20);',
          title: 'Jump without drawing'
        }, {
          block: 'play(\'GEC\');',
          title: 'Play music notes'
        }, {
          block: 'wear(\'/img/cat-icon\');',
          title: 'Change the turtle image'
        }
      ]
    }, {
      name: 'Control',
      color: 'orange',
      blocks: [
        {
          block: 'for (var i = 0; i < 4; i++) {\n  __;\n}',
          title: 'Do something multiple times'
        }, {
          block: 'if (__) {\n  __;\n}',
          title: 'Do something only if a condition is true'
        }, {
          block: 'if (__) {\n  __;\n} else {\n  __;\n}',
          title: 'Do something if a condition is true, otherwise do something else'
        }, {
          block: 'while (__) {\n  __;\n}',
          title: 'Repeat something while a condition is true'
        }
      ]
    }, {
      name: 'Math',
      color: 'green',
      blocks: [
        {
          block: 'var x = __;',
          title: 'Create a variable for the first time'
        }, {
          block: 'x = __;',
          title: 'Reassign a variable'
        }, {
          block: '__ + __',
          title: 'Add two numbers'
        }, {
          block: '__ - __',
          title: 'Subtract two numbers'
        }, {
          block: '__ * __',
          title: 'Multiply two numbers'
        }, {
          block: '__ / __',
          title: 'Divide two numbers'
        }, {
          block: '__ === __',
          title: 'Compare two numbers'
        }, {
          block: '__ > __',
          title: 'Compare two numbers'
        }, {
          block: '__ < __',
          title: 'Compare two numbers'
        }, {
          block: 'random(1, 100)',
          title: 'Get a random number in a range'
        }, {
          block: 'round(__)',
          title: 'Round to the nearest integer'
        }, {
          block: 'abs(__)',
          title: 'Absolute value'
        }, {
          block: 'max(__, __)',
          title: 'Absolute value'
        }, {
          block: 'min(__, __)',
          title: 'Absolute value'
        }
      ]
    }, {
      name: 'Functions',
      color: 'violet',
      blocks: [
        {
          block: 'function myFunction() {\n  __;\n}',
          title: 'Create a function without an argument'
        }, {
          block: 'function myFunction(n) {\n  __;\n}',
          title: 'Create a function with an argument'
        }, {
          block: 'myFunction()',
          title: 'Use a function without an argument'
        }, {
          block: 'myFunction(n)',
          title: 'Use a function with argument'
        }
      ]
    }
  ]
};

});
<commit_msg>Escape the ? in read, attempt 2<commit_after>define(function() {

return {

  // The following palette description
  // is copied from compiled CoffeeScript.
  COFFEESCRIPT_PALETTE: [
    {
      name: 'Move',
      color: 'red',
      blocks: [
        {
          block: 'fd 100',
          title: 'Move forward'
        }, {
          block: 'rt 90',
          title: 'Turn right'
        }, {
          block: 'lt 90',
          title: 'Turn left'
        }, {
          block: 'bk 100',
          title: 'Move backward'
        }, {
          block: 'rt 180, 100',
          title: 'Make a wide right arc'
        }, {
          block: 'lt 180, 100',
          title: 'Make a wide left arc'
        }, {
          block: 'speed 10',
          title: 'Set the speed of the turtle'
        }, {
          block: 'speed Infinity',
          title: 'Use infinite speed'
        }, {
          block: 'home()',
          title: 'Jump to the origin, turned up'
        }, {
          block: 'turnto 270',
          title: 'Turn to an absolute direction'
        }, {
          block: 'turnto lastclick',
          title: 'Turn toward a located object'
        }, {
          block: 'moveto 100, 50',
          title: 'Move to coordinates'
        }, {
          block: 'movexy 30, 20',
          title: 'Move by changing x and y'
        }, {
          block: 'move 10, 5',
          title: "Move sideways or diagonal from turtle's angle"
        }, {
          block: 'jumpto 100, 50',
          title: 'Jump to coordinates without drawing'
        }, {
          block: 'jumpxy 30, 20',
          title: 'Jump changing x and y without drawing'
        }, {
          block: 'jump 10, 5',
          title: "Move sideways or diagonal without drawing"
        }
      ]
    }, {
      name: 'Control',
      color: 'orange',
      blocks: [
        {
          block: 'for [1..3]\n  ``',
          title: 'Do something multiple times'
        }, {
          block: 'for x in [1..3]\n  ``',
          title: 'Do something multiple times...?'
        }, {
          block: 'if `` is ``\n  ``',
          title: 'Do something only if a condition is true'
        }, {
          block: 'if `` is ``\n  ``\nelse\n  ``',
          title: 'Do something if a condition is true, otherwise something else'
        }, {
          block: "tick 1, ->\n  write 'ticked'",
          title: 'Repeat something forever at qually-spaced times'
        }, {
          block: "button \'Click\', ->\n  write 'clicked'",
          title: 'Make a button and do something when clicked'
        }, {
          block: "keydown \'X\', ->\n  write 'x pressed'",
          title: 'Do something when a keyboard key is pressed'
        }, {
          block: "click (e) ->\n  moveto e",
          title: 'Move to a location when document is clicked'
        }
      ]
    }, {
      name: 'Draw',
      color: 'blue',
      blocks: [
        {
          block: 'pen purple, 10',
          title: 'Set pen color and size'
        }, {
          block: 'dot green, 50',
          title: 'Make a dot'
        }, {
          block: 'box yellow, 50',
          title: 'Make a square'
        }, {
          block: 'fill blue',
          title: 'Fill traced shape'
        }, {
          block: 'cs()',
          title: 'Clear screen'
        }, {
          block: 'cg()',
          title: 'Clear graphics'
        }, {
          block: 'pu()',
          title: 'Lift the pen up'
        }, {
          block: 'pd()',
          title: 'Put the pen down'
        }, {
          block: 'scale 3',
          title: 'Scale turtle drawing'
        }
      ]
    }, {
      name: 'Math',
      color: 'green',
      blocks: [
        {
          block: 'x = ``',
          title: 'Set a variable'
        }, {
          block: '`` + ``',
          title: 'Add two numbers'
        }, {
          block: '`` - ``',
          title: 'Subtract two numbers'
        }, {
          block: '`` * ``',
          title: 'Multiply two numbers'
        }, {
          block: '`` / ``',
          title: 'Divide two numbers'
        }, {
          block: '`` is ``',
          title: 'Compare two values'
        }, {
          block: '`` < ``',
          title: 'Compare two values'
        }, {
          block: '`` > ``',
          title: 'Compare two values'
        }, {
          block: 'random [1..100]',
          title: 'Get a random number in a range'
        }, {
          block: 'round ``',
          title: 'Round to the nearest integer'
        }, {
          block: 'abs ``',
          title: 'Absolute value'
        }, {
          block: 'max ``, ``',
          title: 'Get the larger of two numbers'
        }, {
          block: 'min ``, ``',
          title: 'Get the smaller on two numbers'
        }, {
          block: 'text.match /pattern/',
          title: 'Test if pattern is found in text'
        }, {
          block: 'f = (param) ->\n  ``',
          title: 'Define a new function'
        }, {
          block: 'myfunc(arg)',
          title: 'Use a custom function'
        }
      ]
    }, {
      name: 'Text',
      color: 'yellow',
      blocks: [
        {
          block: 'write \'Hello.\'',
          title: 'Write text in the document'
        }, {
          block: 'type \'zz*(-.-)*zz\'',
          title: 'Typewrite text in the document'
        }, {
          block: 'label \'spot\'',
          title: 'Write text at the turtle'
        }, {
          block: 'read \'\?\', (x) ->\x  write x',
          title: 'Read input from the user'
        }, {
          block: 'readnum \'Side\', (n) ->\n  write \'A\' + n * n',
          title: 'Read a number from the user'
        }, {
          block: 'readstr \'Idea?\', (n) ->\n  write n.length',
          title: 'Read a whole line of text'
        }, {
          block: "table [\n  ['a','b','c']\n  [1,2,3]\n]",
          title: 'Write a table in the document'
        }, {
          block: 'log [1..10]',
          title: 'Log an object to debug'
        }, {
          block: 'd = write \'dice\'',
          title: 'Remember d as a text element'
        }, {
          block: 'tick 1, ->\n  d.text random [1..6]',
          title: 'Change d text content'
        }
      ]
    }, {
      name: 'Sprites',
      color: 'violet',
      blocks: [
        {
          block: 'wear \'/img/apple\'',
          title: 'Use an image for the turtle'
        }, {
          block: 't = new Turtle red',
          title: 'Make a new turtle'
        }, {
          block: 't.fd 100',
          title: 'Move turtle t forward'
        }, {
          block: 't.rt 90',
          title: 'Turn turtle t right'
        }, {
          block: 't.lt 90',
          title: 'Turn turtle t left'
        }, {
          block: 't.bk 100',
          title: 'Move turtle t backward'
        }, {
          block: 'ht()',
          title: 'Hide the main turtle'
        }, {
          block: 'st()',
          title: 'Show the main turtle'
        }, {
          block: 's = new Sprite',
          title: 'Make a blank sprite'
        }, {
          block: 's.wear \'/img/dragon\'',
          title: 'Load an image in sprite s'
        }, {
          block: 'drawon s',
          title: 'Draw on sprite s'
        }, {
          block: 'drawon document',
          title: 'Draw on the document'
        }, {
          block: 'p = new Piano',
          title: 'Make a visible insturment'
        }, {
          block: 'p.play \'CDEDC\'',
          title: 'Play and show music notes'
        }, {
          block: 'q = new Pencil',
          title: 'Make an invisible and fast drawing sprite'
        }, {
          block: 'q.pen black, 1',
          title: 'Use a thin black pen'
        }, {
          block: 'q.drawon s',
          title: 'Use q to draw on sprite s'
        }, {
          block: 'q.rt 360, 100',
          title: 'Trace a circle on the right'
        }, {
          block: 'q.lt 360, 100',
          title: 'Trace a circle on the left'
        }, {
          block: 'q.fill pink',
          title: 'Fill the traced path'
        }
      ]
    }
  ],

  JAVASCRIPT_PALETTE: [
    {
      name: 'Draw',
      color: 'blue',
      blocks: [
        {
          block: 'pen(red);',
          title: 'Set the pen color'
        }, {
          block: 'fd(100);',
          title: 'Move forward'
        }, {
          block: 'rt(90);',
          title: 'Turn right'
        }, {
          block: 'lt(90);',
          title: 'Turn left'
        }, {
          block: 'bk(100);',
          title: 'Move backward'
        }, {
          block: 'speed(10);',
          title: 'Set the speed of the turtle'
        }, {
          block: 'dot(blue, 50);',
          title: 'Make a dot'
        }, {
          block: 'box(green, 50);',
          title: 'Make a square'
        }, {
          block: 'write(\'hello\');',
          title: 'Write text on the screen'
        }, {
          block: 'label(\'hello\');',
          title: 'Write text at the turtle'
        }, {
          block: 'ht();',
          title: 'Hide the turtle'
        }, {
          block: 'st();',
          title: 'Show the turtle'
        }, {
          block: 'pu();',
          title: 'Pick the pen up'
        }, {
          block: 'pd();',
          title: 'Put the pen down'
        }, {
          block: 'pen(purple, 10);',
          title: 'Set the pen color and thickness'
        }, {
          block: 'rt(180, 100);',
          title: 'Make a wide right turn'
        }, {
          block: 'lt(180, 100);',
          title: 'Make a wide left turn'
        }, {
          block: 'slide(100, 20);',
          title: 'Slide sideways or diagonally'
        }, {
          block: 'jump(100, 20);',
          title: 'Jump without drawing'
        }, {
          block: 'play(\'GEC\');',
          title: 'Play music notes'
        }, {
          block: 'wear(\'/img/cat-icon\');',
          title: 'Change the turtle image'
        }
      ]
    }, {
      name: 'Control',
      color: 'orange',
      blocks: [
        {
          block: 'for (var i = 0; i < 4; i++) {\n  __;\n}',
          title: 'Do something multiple times'
        }, {
          block: 'if (__) {\n  __;\n}',
          title: 'Do something only if a condition is true'
        }, {
          block: 'if (__) {\n  __;\n} else {\n  __;\n}',
          title: 'Do something if a condition is true, otherwise do something else'
        }, {
          block: 'while (__) {\n  __;\n}',
          title: 'Repeat something while a condition is true'
        }
      ]
    }, {
      name: 'Math',
      color: 'green',
      blocks: [
        {
          block: 'var x = __;',
          title: 'Create a variable for the first time'
        }, {
          block: 'x = __;',
          title: 'Reassign a variable'
        }, {
          block: '__ + __',
          title: 'Add two numbers'
        }, {
          block: '__ - __',
          title: 'Subtract two numbers'
        }, {
          block: '__ * __',
          title: 'Multiply two numbers'
        }, {
          block: '__ / __',
          title: 'Divide two numbers'
        }, {
          block: '__ === __',
          title: 'Compare two numbers'
        }, {
          block: '__ > __',
          title: 'Compare two numbers'
        }, {
          block: '__ < __',
          title: 'Compare two numbers'
        }, {
          block: 'random(1, 100)',
          title: 'Get a random number in a range'
        }, {
          block: 'round(__)',
          title: 'Round to the nearest integer'
        }, {
          block: 'abs(__)',
          title: 'Absolute value'
        }, {
          block: 'max(__, __)',
          title: 'Absolute value'
        }, {
          block: 'min(__, __)',
          title: 'Absolute value'
        }
      ]
    }, {
      name: 'Functions',
      color: 'violet',
      blocks: [
        {
          block: 'function myFunction() {\n  __;\n}',
          title: 'Create a function without an argument'
        }, {
          block: 'function myFunction(n) {\n  __;\n}',
          title: 'Create a function with an argument'
        }, {
          block: 'myFunction()',
          title: 'Use a function without an argument'
        }, {
          block: 'myFunction(n)',
          title: 'Use a function with argument'
        }
      ]
    }
  ]
};

});
<|endoftext|>


<commit_before>var BaseCollection = require('./commons/basecollection');
var HeapNode = require('./heapnode');

/**
 * @classdesc It is a data structure organized as a balanced binary tree,
 *            following some rules. This can be implemented in an arrangement,
 *            so that it is accessed as a binary tree:
 *
 * Parent (i) = return 1 / 2
 *
 * Left (i) = return i * 2
 *
 * Right (i) = return (i * 2) + 1
 *
 * These operations can be performed quickly using bitwise operations. For the
 * left child moves the bits to the left, to the right moves the bits to the
 * right and applies the operation "or" to 1. To find the parent, shifts a bit
 * to the right. The advantage of using bitwise operations is that each uses
 * only one processor clock and is highly efficient. There are two types of
 * heaps: The maximum heaps (max heap), in which the value of all nodes are
 * smaller than those of their respective parents; And heaps of min (min heap),
 * in which the value of all nodes is greater than those of their respective
 * parents. Thus, at a maximum heap, the highest value of the set is at the root
 * of the tree, while at the minimum heap the root stores the smallest existing
 * value. This can be defined by determining a sort function in the class
 * constructor.
 *
 * @requires HeapNode
 * @constructor
 * @augments BaseCollection
 * @param {function}
 *          compare A function to mantain sort heap
 */
var Heap = function Heap(compare) {
  BaseCollection.call(this, {
    _dataStore: [],
    _compare: compare,
  });
};

Heap.prototype = Object.create(BaseCollection.prototype, {

  constructor: Heap,

  /**
   * @private
   */
  _dataStore: {
    value: undefined,
    enumerable: true,
    configurable: false,
    writable: true,
  },

  /**
   * @private
   */
  _compare: {
    value: undefined,
    enumerable: false,
    configurable: true,
    writable: true,
  },

  /**
   * @private
   */
  _swap: {
    value: function(nodeA, nodeB) {
      var temp = nodeA.value;
      nodeA.value = nodeB.value;
      nodeB.value = temp;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @private
   */
  _heapifyUp: {
    value: function(index) {
      var node = this._dataStore[index];

      if (node.hasParent && this._compare(node.parent.value, node.value) > 0) {
        this._swap(node.parent, node);
        this._heapifyUp(node.parent.index);
      }
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @private
   */
  _heapifyDown: {
    value: function(index) {
      var node = this._dataStore[index];

      var candidate = node;

      if (node.hasLeft && this._compare(candidate.value, node.left.value) > 0) {
        candidate = node.left;
      }

      if (node.hasRight && this._compare(candidate.value, node.right.value) > 0) {
        candidate = node.right;
      }

      if (node == candidate) {
        return;
      }

      this._swap(node, candidate);

      this._heapifyDown(candidate.index);
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Return first element on Heap, without remove.
   *
   * @method
   * @memberof Heap.prototype
   * @return Object
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var heapmin = new Heap(function(a, b){
   *   return a - b;
   * });
   *
   * heapmin.add(10);
   * heapmin.add(8);
   * heapmin.add(9);
   * heapmin.add(7);
   *
   * console.log(heapmin.peek());
   */
  peek: {
    value: function() {
      if (this._dataStore.length == 0) {
        return null;
      }

      return this._dataStore[0].value;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Return first element on Heap, remove.
   *
   * @method
   * @memberof Heap.prototype
   * @return Object
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var heapmax = new Heap(function(a, b){
   *   return b - a;
   * });
   *
   * heapmax.add(1);
   * heapmax.add(2);
   * heapmax.add(3);
   * heapmax.add(4);
   *
   * while(!heapmax.empty) {
   *   console.log(heapmax.poll());
   * }
   */
  poll: {
    value: function() {
      this._swap(this._dataStore[0], this._dataStore[this._dataStore.length - 1]);

      var node = this._dataStore.pop();

      if (this._dataStore.length > 0) {
        this._heapifyDown(0);
      }

      return node.value;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Appends the specified element.
   *
   * @method
   * @memberof Heap.prototype
   * @param {value}
   *          value
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var obj01 = {
   *   index: 1,
   *   name: 'Ximenes'
   * };
   *
   * var obj02 = {
   *   index: 2,
   *   name: 'Nunes'
   * };
   *
   * var obj03 = {
   *   index: 3,
   *   name: 'Vallim'
   * };
   *
   * var heapmin = new Heap(function(a, b){
   *   return a.index - b.index;
   * });
   *
   * heapmin.add(obj01);
   * heapmin.add(obj02);
   * heapmin.add(obj03);
   *
   * while(!heapmin.empty) {
   *   console.log(heapmin.poll());
   * }
   */
  add: {
    value: function(value) {
      var index = this._dataStore.length;

      this._dataStore.push(new HeapNode(this._dataStore, value, index));

      this._heapifyUp(index);
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @inheritdoc
   * @memberof Heap.prototype
   */
  length: {
    get: function() {
      return this._dataStore.length;
    },
    configurable: false,
  },

  /**
   * @inheritdoc
   * @memberof Heap.prototype
   */
  empty: {
    get: function() {
      return this._dataStore.length == 0;
    },
    configurable: false,
  },

  /**
   * @inheritdoc
   * @method
   * @memberof Heap.prototype
   */
  clear: {
    value: function() {
      this._dataStore = [];
    },
    configurable: false,
  },
});

module.exports = Heap;
<commit_msg>Bug fix<commit_after>var BaseCollection = require('./commons/basecollection');
var HeapNode = require('./heapnode');

/**
 * @classdesc It is a data structure organized as a balanced binary tree,
 *            following some rules. This can be implemented in an arrangement,
 *            so that it is accessed as a binary tree:
 *
 * Parent (i) = return 1 / 2
 *
 * Left (i) = return i * 2
 *
 * Right (i) = return (i * 2) + 1
 *
 * These operations can be performed quickly using bitwise operations. For the
 * left child moves the bits to the left, to the right moves the bits to the
 * right and applies the operation "or" to 1. To find the parent, shifts a bit
 * to the right. The advantage of using bitwise operations is that each uses
 * only one processor clock and is highly efficient. There are two types of
 * heaps: The maximum heaps (max heap), in which the value of all nodes are
 * smaller than those of their respective parents; And heaps of min (min heap),
 * in which the value of all nodes is greater than those of their respective
 * parents. Thus, at a maximum heap, the highest value of the set is at the root
 * of the tree, while at the minimum heap the root stores the smallest existing
 * value. This can be defined by determining a sort function in the class
 * constructor.
 *
 * @requires HeapNode
 * @constructor
 * @augments BaseCollection
 * @param {function}
 *          compare A function to mantain sort heap
 */
var Heap = function Heap(compare) {
  BaseCollection.call(this, {
    _dataStore: [],
    _compare: compare,
  });
};

Heap.prototype = Object.create(BaseCollection.prototype, {

  constructor: Heap,

  /**
   * @private
   */
  _dataStore: {
    value: undefined,
    enumerable: true,
    configurable: false,
    writable: true,
  },

  /**
   * @private
   */
  _compare: {
    value: undefined,
    enumerable: false,
    configurable: true,
    writable: true,
  },

  /**
   * @private
   */
  _swap: {
    value: function(nodeA, nodeB) {
      var temp = nodeA.value;
      nodeA.value = nodeB.value;
      nodeB.value = temp;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @private
   */
  _heapifyUp: {
    value: function(index) {
      var node = this._dataStore[index];

      if (node.hasParent && this._compare(node.parent.value, node.value) > 0) {
        this._swap(node.parent, node);
        this._heapifyUp(node.parent.index);
      }
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @private
   */
  _heapifyDown: {
    value: function(index) {
      var node = this._dataStore[index];

      var candidate = node;

      if (node.hasLeft && this._compare(candidate.value, node.left.value) > 0) {
        candidate = node.left;
      }

      if (node.hasRight && this._compare(candidate.value, node.right.value) > 0) {
        candidate = node.right;
      }

      if (node.index != candidate.index) {
        this._swap(node, candidate);
        this._heapifyDown(candidate.index);
      }
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Return first element on Heap, without remove.
   *
   * @method
   * @memberof Heap.prototype
   * @return Object
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var heapmin = new Heap(function(a, b){
   *   return a - b;
   * });
   *
   * heapmin.add(10);
   * heapmin.add(8);
   * heapmin.add(9);
   * heapmin.add(7);
   *
   * console.log(heapmin.peek());
   */
  peek: {
    value: function() {
      if (this._dataStore.length == 0) {
        return null;
      }

      return this._dataStore[0].value;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Return first element on Heap, remove.
   *
   * @method
   * @memberof Heap.prototype
   * @return Object
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var heapmax = new Heap(function(a, b){
   *   return b - a;
   * });
   *
   * heapmax.add(1);
   * heapmax.add(2);
   * heapmax.add(3);
   * heapmax.add(4);
   *
   * while(!heapmax.empty) {
   *   console.log(heapmax.poll());
   * }
   */
  poll: {
    value: function() {
      this._swap(this._dataStore[0], this._dataStore[this._dataStore.length - 1]);

      var node = this._dataStore.pop();

      if (this._dataStore.length > 0) {
        this._heapifyDown(0);
      }

      return node.value;
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * Appends the specified element.
   *
   * @method
   * @memberof Heap.prototype
   * @param {value}
   *          value
   *
   * @playground
   * var Heap = require("javascript-collections").Heap;
   *
   * var obj01 = {
   *   index: 1,
   *   name: 'Ximenes'
   * };
   *
   * var obj02 = {
   *   index: 2,
   *   name: 'Nunes'
   * };
   *
   * var obj03 = {
   *   index: 3,
   *   name: 'Vallim'
   * };
   *
   * var heapmin = new Heap(function(a, b){
   *   return a.index - b.index;
   * });
   *
   * heapmin.add(obj01);
   * heapmin.add(obj02);
   * heapmin.add(obj03);
   *
   * while(!heapmin.empty) {
   *   console.log(heapmin.poll());
   * }
   */
  add: {
    value: function(value) {
      var index = this._dataStore.length;

      this._dataStore.push(new HeapNode(this._dataStore, value, index));

      this._heapifyUp(index);
    },
    enumerable: false,
    configurable: false,
    writable: false,
  },

  /**
   * @inheritdoc
   * @memberof Heap.prototype
   */
  length: {
    get: function() {
      return this._dataStore.length;
    },
    configurable: false,
  },

  /**
   * @inheritdoc
   * @memberof Heap.prototype
   */
  empty: {
    get: function() {
      return this._dataStore.length == 0;
    },
    configurable: false,
  },

  /**
   * @inheritdoc
   * @method
   * @memberof Heap.prototype
   */
  clear: {
    value: function() {
      this._dataStore = [];
    },
    configurable: false,
  },
});

module.exports = Heap;
<|endoftext|>


<commit_before>"use strict";

/**
 * Works for time in the range 4000 B.C. - 3000 A.C.
 * Timestamp is calculated from year 1, 1st January, 00:00.
 * Timestamp is in milliseconds.
 *
 * The year 0 is that in which one supposes that Jesus Christ was born, which several chronologists mark 1 before the birth of Jesus Christ
 and which we marked 0, so that the sum of the years before and after Jesus Christ gives the interval which is between these years,
 and where numbers divisible by 4 mark the leap years as so many before or after Jesus Christ.
 —Jacques Cassini, Tables astronomiques, 5, translated from French
 *
 * Conclusion: Year 0 in our library equals year -1 B.C.
 *
 */
var Time = (function () {
    var appContext = window || global;

    /* TEMP Start */

    //            // Call hidden function
    //            var isPositionValid = validatePosition.call(this);

    //    function DateExtended(firstName, subject) {
    //        Date.call(this, firstName);
    //    }
    //    DateExtended.prototype = Object.create(Date.prototype);

    //        if (!(date instanceof Date)) {
    //            throw new Error("Date should be a Time.Date() object.");
    //        }

    /* TEMP End */

    var Util = (function () {
        /**
         * Works only for custom objects with no recursive references.
         *
         * If two references point to the same sub-object,
         * the copy contains two different copies of it.
         */
        var clone = function (obj) {
            if ((obj === null) || (typeof obj !== "object")) {
                return obj;
            }

            var cloned = obj.constructor();

            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    cloned[key] = clone(obj[key]);
                }
            }
            return cloned;
        };

        return {
            "clone": clone
        };
    }());

    var ValidatorGeneral = (function () {
        var isEmpty = function (value) {
            return value === undefined || value === null || value === "";
        };

        var isInteger = function (value) {
            return (typeof value === 'number') && value % 1 === 0;
        };

        return {
            "isEmpty": isEmpty,
            "isInteger": isInteger
        };
    }());

    var Const = (function () {
        var DAYS = {
            "SUNDAY": 0,
            "MONDAY": 1,
            "TUESDAY": 2,
            "WEDNESDAY": 3,
            "THURSDAY": 4,
            "FRIDAY": 5,
            "SATURDAY": 6
        };

        var MONTHS = {
            "JANUARY": 0,
            "FEBRUARY": 1,
            "MARCH": 2,
            "APRIL": 3,
            "MAY": 4,
            "JUNE": 5,
            "JULY": 6,
            "AUGUST": 7,
            "SEPTEMBER": 8,
            "OCTOBER": 9,
            "NOVEMBER": 10,
            "DECEMBER": 11
        };

        var PERIODS_IN_MILLISEC = (function () {
            var second = 1000;
            var minute = second * 60;
            var hour = minute * 60;
            var day = hour * 24;

            return {
                "SECOND": second,
                "MINUTE": minute,
                "HOUR": hour,
                "DAY": day
            };
        }());

        var LIMITS = {
            "MIN_TIMESTAMP": -128563200000000,
            "MAX_TIMESTAMP": 96422400000000,
            "MIN_YEAR": -4000,
            "MAX_YEAR": 3000,
            "MIN_MONTH": 0,
            "MAX_MONTH": 11,
            "MIN_DAY": 1,
            "MAX_DAY": 31,
            "MIN_HOUR": 0,
            "MAX_HOUR": 23,
            "MIN_MINUTE": 0,
            "MAX_MINUTE": 59,
            "MIN_SECOND": 0,
            "MAX_SECOND": 59,
            "MIN_MILLISECOND": 0,
            "MAX_MILLISECOND": 1000
        };

        var MISC = {
            "LEAP_YEAR_DAYS": 366,
            "COMMON_YEAR_DAYS": 365
        };

        var allConstLists = [DAYS, MONTHS, PERIODS_IN_MILLISEC, LIMITS, MISC];

        var get = function (requestedConst) {
            if (ValidatorGeneral.isEmpty(requestedConst)) {
                throw new Error("Invalid argument: Please provide a string argument for the requested constant.");
            }
            for (var index in allConstLists) {
                var currentList = allConstLists[index];
                for (var key in currentList) {
                    if (key === requestedConst) {
                        return currentList[key];
                    }
                }
            }
        };

        return {
            "get": get
        };
    }());

    var ValidatorDate = (function () {
        var isVanillaDate = function (value) {
            return !isEmpty(value) && (value instanceof appContext.Date);
        };

        var isTimestamp = function (value) {
            return isInteger(value) && value <= Const.get("MAX_TIMESTAMP") && value >= Const.get("MIN_TIMESTAMP");
        };

        var isYear = function (value) {
            return isInteger(value) && value <= Const.get("MAX_YEAR") && value >= Const.get("MIN_YEAR");
        };

        var isMonth = function (value) {
            return isInteger(value) && value <= Const.get("MAX_MONTH") && value >= Const.get("MIN_MONTH");
        };

        var isDay = function (value) {
            return isInteger(value) && value <= Const.get("MAX_DAY") && value >= Const.get("MIN_DAY");
        };

        var isHour = function (value) {
            return isInteger(value) && value <= Const.get("MAX_HOUR") && value >= Const.get("MIN_HOUR");
        };

        var isMinute = function (value) {
            return isInteger(value) && value <= Const.get("MAX_MINUTE") && value >= Const.get("MIN_MINUTE");
        };

        var isSecond = function (value) {
            return isInteger(value) && value <= Const.get("MAX_SECOND") && value >= Const.get("MIN_SECOND");
        };

        var isMillisecond = function (value) {
            return isInteger(value) && value <= Const.get("MAX_MILLISECOND") && value >= Const.get("MIN_MILLISECOND");
        };

        var isLeapYear = function (value) {
            if (!isInteger(value)) {
                throw new Error("Year should be an integer number.");
            }

            var isLeap = false;

            if (value % 4 === 0) {
                if (value % 100 === 0) {
                    if (value % 400 === 0) {
                        isLeap = true;
                    } else {
                        isLeap = false;
                    }
                } else {
                    isLeap = true;
                }
            } else {
                isLeap = false;
            }

            return isLeap;
        };

        var isFormatString = function (value) {
            // TODO:
            return (typeof value !== "string");
        };

        return {
            "isTimestamp": isTimestamp,
            "isLeapYear": isLeapYear,
            "isVanillaDate": isVanillaDate,
            "isYear": isYear,
            "isMonth": isMonth,
            "isDay": isDay,
            "isHour": isHour,
            "isMinute": isMinute,
            "isSecond": isSecond,
            "isMillisecond": isMillisecond,
            "isFormatString": isFormatString
        };
    }());

    var parse = function (dateString, formatType) {
        if ((typeof dateString !== "string") || (typeof formatType !== "string")) {
            throw new Error("Invalid arguments: Expected string for date and format.");
        }
        return new Date();
    };

    var getDaysInYear = function (year) {
        return (ValidatorDate.isLeapYear(year)) ? Const.getDaysLeapYear() : Const.getDaysCommonYear();
    };

    var convertVanillaDate = function (date) {
        if (!ValidatorDate.isVanillaDate(date)) {
            throw new Error("Invalid argument: Expected vanilla JavaScript Date.");
        }

        var cutomDate = new Date();
        cutomDate.year(date.getFullYear());
        cutomDate.month(date.getMonth());
        cutomDate.date(date.getDate());
        cutomDate.hour(date.getHours());
        cutomDate.minute(date.getMinutes());
        cutomDate.second(date.getSeconds());
        cutomDate.millisecond(date.getMilliseconds());
        return cutomDate;
    };

//    var convertTimestampToDate = function (timestamp) {
//        if (!ValidatorDate.isTimestamp(timestamp)) {
//            throw new Error("Invalid argument: timestamp.");
//        }
//
//        var cutomDate = new Date();
//
//        return cutomDate;
//    };

    var Date = (function () {
        // Constructor
        var Date = function (timestamp) {
            if (!(this instanceof Date)) {
                return new Date(timestamp);
            }

            this._year = 0;
            this._month = 0;
            this._day = 1;
            this._hour = 0;
            this._minute = 0;
            this._second = 0;
            this._millisecond = 0;

            if (!ValidatorGeneral.isEmpty(timestamp)) {
                if (!ValidatorDate.isTimestamp(timestamp)) {
                    throw new Error("Invalid argument: timestamp.");
                }
                //TODO: convertTimestampToDate(timestamp);
            } else {
                var nowVanillaDate = new appContext.Date();
                this._year = nowVanillaDate.getFullYear();
                this._month = nowVanillaDate.getMonth();
                this._day = nowVanillaDate.getDate();
                this._hour = nowVanillaDate.getHours();
                this._minute = nowVanillaDate.getMinutes();
                this._second = nowVanillaDate.getSeconds();
                this._millisecond = nowVanillaDate.getMilliseconds();
            }
        };

        Date.prototype.year = function (year) {
            if (ValidatorGeneral.isEmpty(year)) {
                return this._year;
            }

            if (ValidatorDate.isYear(year)) {
                if (!ValidatorDate.isLeapYear(year)) {
                    if (this._day === 29 && this._month === Const.MONTHS.FEBRUARY) {
                        throw new Error("Invalid argument: year. Cannot set a common year when the date is 29 February.");
                    }
                }

                this._year = year;
                return this;
            }

            throw new Error("Invalid argument: year");
        };

        Date.prototype.month = function (month) {
            if (ValidatorGeneral.isEmpty(month)) {
                return this._month;
            }

            if (ValidatorDate.isMonth(month)) {
                this._month = month;
                return this;
            }

            throw new Error("Invalid argument: month");
        };

        Date.prototype.day = function (day) {
            if (ValidatorGeneral.isEmpty(day)) {
                return this._day;
            }

            if (ValidatorDate.isDay(day)) {
                this._day = day;
                return this;
            }

            throw new Error("Invalid argument: day");
        };

        Date.prototype.hour = function (hour) {
            if (ValidatorGeneral.isEmpty(hour)) {
                return this._hour;
            }

            if (ValidatorDate.isHour(hour)) {
                this._hour = hour;
                return this;
            }

            throw new Error("Invalid argument: hour");
        };

        Date.prototype.minute = function (minute) {
            if (ValidatorGeneral.isEmpty(minute)) {
                return this._minute;
            }

            if (ValidatorDate.isMinute(minute)) {
                this._minute = minute;
                return this;
            }

            throw new Error("Invalid argument: minute");
        };

        Date.prototype.second = function (second) {
            if (ValidatorGeneral.isEmpty(second)) {
                return this._second;
            }

            if (ValidatorDate.isSecond(second)) {
                this._second = second;
                return this;
            }

            throw new Error("Invalid argument: second");
        };

        Date.prototype.millisecond = function (millisecond) {
            if (ValidatorGeneral.isEmpty(millisecond)) {
                return this._millisecond;
            }

            if (ValidatorDate.isMillisecond(millisecond)) {
                this._millisecond = millisecond;
                return this;
            }

            throw new Error("Invalid argument: millisecond");
        };

        Date.prototype.format = function format(format) {
            if (!ValidatorDate.isFormatString(format)) {
                throw new Error("Invalid argument: format.");
            }
            // TODO:
            return "1st July 2015";
        };

        Date.prototype.getTimestamp = function () {
            return this._timestamp;
        };

        Date.prototype.getDayOfWeek = function () {
            // TODO:
        };

        Date.prototype.isLeapYear = function () {
            return ValidatorDate.isLeapYear(this._year);
        };

        Date.prototype.toString = function () {
            var toString = "timestamp: " + this._timestamp + "\r\n year: " + this._year + "\r\n month: " + this._month
                    + "\r\n day: " + this._day + "\r\n hour: " + this._hour + "\r\n minute: " + this._minute
                    + "\r\n second: " + this._second + "\r\n millisecond: " + this._millisecond;
            return toString;
        };

        return Date;
    }());

    return {
        "Date": Date,
        "parse": parse,
        "get": Const.get,
        "isLeapYear": ValidatorDate.isLeapYear,
        "getDaysInYear": getDaysInYear,
        "convertVanillaDate": convertVanillaDate
    };
}());<commit_msg>Date properties made private and getter/setter functions are now privileged<commit_after>"use strict";

/**
 * Works for time in the range 4000 B.C. - 3000 A.C.
 * Timestamp is calculated from year 1, 1st January, 00:00.
 * Timestamp is in milliseconds.
 *
 * The year 0 is that in which one supposes that Jesus Christ was born, which several chronologists mark 1 before the birth of Jesus Christ
 and which we marked 0, so that the sum of the years before and after Jesus Christ gives the interval which is between these years,
 and where numbers divisible by 4 mark the leap years as so many before or after Jesus Christ.
 —Jacques Cassini, Tables astronomiques, 5, translated from French
 *
 * Conclusion: Year 0 in our library equals year -1 B.C.
 *
 */
var Time = (function () {
    var appContext = window || global;

    /* TEMP Start */

    //    function error(msg) {
    //        console.error('\r\n' + msg + '\r\n');
    //        // TODO: stop function
    //    }

    //    function DateExtended(firstName, subject) {
    //        Date.call(this, firstName);
    //    }
    //    DateExtended.prototype = Object.create(Date.prototype);

    /* TEMP End */

    var Util = (function () {
        /**
         * Works only for custom objects with no recursive references.
         *
         * If two references point to the same sub-object,
         * the copy contains two different copies of it.
         */
        var clone = function (obj) {
            if ((obj === null) || (typeof obj !== "object")) {
                return obj;
            }

            var cloned = obj.constructor();

            for (var key in obj) {
                if (obj.hasOwnProperty(key)) {
                    cloned[key] = clone(obj[key]);
                }
            }
            return cloned;
        };

        return {
            "clone": clone
        };
    }());

    var ValidatorGeneral = (function () {
        var isEmpty = function (value) {
            return value === undefined || value === null || value === "";
        };

        var isInteger = function (value) {
            return (typeof value === 'number') && value % 1 === 0;
        };

        return {
            "isEmpty": isEmpty,
            "isInteger": isInteger
        };
    }());

    var Const = (function () {
        var DAYS = {
            "SUNDAY": 0,
            "MONDAY": 1,
            "TUESDAY": 2,
            "WEDNESDAY": 3,
            "THURSDAY": 4,
            "FRIDAY": 5,
            "SATURDAY": 6
        };

        var MONTHS = {
            "JANUARY": 0,
            "FEBRUARY": 1,
            "MARCH": 2,
            "APRIL": 3,
            "MAY": 4,
            "JUNE": 5,
            "JULY": 6,
            "AUGUST": 7,
            "SEPTEMBER": 8,
            "OCTOBER": 9,
            "NOVEMBER": 10,
            "DECEMBER": 11
        };

        var PERIODS_IN_MILLISEC = (function () {
            var second = 1000;
            var minute = second * 60;
            var hour = minute * 60;
            var day = hour * 24;

            return {
                "SECOND": second,
                "MINUTE": minute,
                "HOUR": hour,
                "DAY": day
            };
        }());

        var LIMITS = {
            "MIN_TIMESTAMP": -128563200000000,
            "MAX_TIMESTAMP": 96422400000000,
            "MIN_YEAR": -4000,
            "MAX_YEAR": 3000,
            "MIN_MONTH": 0,
            "MAX_MONTH": 11,
            "MIN_DAY": 1,
            "MAX_DAY": 31,
            "MIN_HOUR": 0,
            "MAX_HOUR": 23,
            "MIN_MINUTE": 0,
            "MAX_MINUTE": 59,
            "MIN_SECOND": 0,
            "MAX_SECOND": 59,
            "MIN_MILLISECOND": 0,
            "MAX_MILLISECOND": 1000
        };

        var MISC = {
            "LEAP_YEAR_DAYS": 366,
            "COMMON_YEAR_DAYS": 365
        };

        var allConstLists = [DAYS, MONTHS, PERIODS_IN_MILLISEC, LIMITS, MISC];

        var get = function (requestedConst) {
            if (ValidatorGeneral.isEmpty(requestedConst)) {
                throw new Error("Invalid argument: Please provide a string argument for the requested constant.");
            }
            for (var index in allConstLists) {
                var currentList = allConstLists[index];
                for (var key in currentList) {
                    if (key === requestedConst) {
                        return currentList[key];
                    }
                }
            }
        };

        return {
            "get": get
        };
    }());

    var ValidatorDate = (function () {
        var isVanillaDate = function (value) {
            return (value instanceof appContext.Date);
        };

        var isTimestamp = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_TIMESTAMP") && value >= Const.get("MIN_TIMESTAMP");
        };

        var isYear = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_YEAR") && value >= Const.get("MIN_YEAR");
        };

        var isMonth = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_MONTH") && value >= Const.get("MIN_MONTH");
        };

        var isDay = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_DAY") && value >= Const.get("MIN_DAY");
        };

        var isHour = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_HOUR") && value >= Const.get("MIN_HOUR");
        };

        var isMinute = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_MINUTE") && value >= Const.get("MIN_MINUTE");
        };

        var isSecond = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_SECOND") && value >= Const.get("MIN_SECOND");
        };

        var isMillisecond = function (value) {
            return ValidatorGeneral.isInteger(value) && value <= Const.get("MAX_MILLISECOND") && value >= Const.get("MIN_MILLISECOND");
        };

        var isLeapYear = function (value) {
            if (!ValidatorGeneral.isInteger(value)) {
                throw new Error("Year should be an integer number.");
            }

            var isLeap = false;

            if (value % 4 === 0) {
                if (value % 100 === 0) {
                    if (value % 400 === 0) {
                        isLeap = true;
                    } else {
                        isLeap = false;
                    }
                } else {
                    isLeap = true;
                }
            } else {
                isLeap = false;
            }

            return isLeap;
        };

        var isFormatString = function (value) {
            // TODO:
            return (typeof value !== "string");
        };

        return {
            "isTimestamp": isTimestamp,
            "isLeapYear": isLeapYear,
            "isVanillaDate": isVanillaDate,
            "isYear": isYear,
            "isMonth": isMonth,
            "isDay": isDay,
            "isHour": isHour,
            "isMinute": isMinute,
            "isSecond": isSecond,
            "isMillisecond": isMillisecond,
            "isFormatString": isFormatString
        };
    }());

    var parseToDate = function (dateString, formatType) {
        if ((typeof dateString !== "string") || (typeof formatType !== "string")) {
            throw new Error("Invalid arguments: Expected string for date and format.");
        }
        return new Date();
    };

    var getDaysInYear = function (year) {
        return (ValidatorDate.isLeapYear(year)) ? Const.getDaysLeapYear() : Const.getDaysCommonYear();
    };

    var Date = (function () {
        // Constructor
        var Date = function (arg, format) {
            if (!(this instanceof Date)) {
                return new Date(arg, format);
            }

            // Private properties
            var _year = 0;
            var _month = 0;
            var _day = 1;
            var _hour = 0;
            var _minute = 0;
            var _second = 0;
            var _millisecond = 0;

            // Private methods
            var setPropertiesFromVanillaDate = function (date) {
                // TODO: decide if UTC or current time zone time is taken
                _year = date.getUTCFullYear();
                _month = date.getUTCMonth();
                _day = date.getUTCDate();
                _hour = date.getUTCHours();
                _minute = date.getUTCMinutes();
                _second = date.getUTCSeconds();
                _millisecond = date.getUTCMilliseconds();
            };

            // Constructor base
            if (!ValidatorGeneral.isEmpty(arg)) {
                if (!ValidatorGeneral.isEmpty(format)) {
                    if (ValidatorDate.isFormatString(format)) {
                        // TODO: Parse date as string to Time.Date() obj based on given format string.
                    } else {
                        throw new Error("Invalid arguments: Date constructor with 2 parameters expects date string and format string.");
                    }
                }

                if (ValidatorDate.isVanillaDate(arg)) {
                    // Converts vanilla Date() obj to Time.Date() obj
                    setPropertiesFromVanillaDate.call(this, arg);
                } else if (ValidatorDate.isTimestamp(arg)) {
                    // TODO: Convert Time.js timestamp number to Time.Date() obj.
                } else {
                    throw new Error("Invalid argument: Expected timestamp, vanilla JavaScript Date or no argument.");
                }
            } else {
                // Sets the current time to the newly instantiated Time.Date() obj.
                var nowVanillaDate = new appContext.Date();
                setPropertiesFromVanillaDate.call(this, nowVanillaDate);
            }

            // Privileged methods
            this.year = function (year) {
                if (ValidatorGeneral.isEmpty(year)) {
                    return _year;
                }

                if (ValidatorDate.isYear(year)) {
                    if (!ValidatorDate.isLeapYear(year)) {
                        if (_day === 29 && _month === Const.MONTHS.FEBRUARY) {
                            throw new Error("Invalid argument: year. Cannot set a common year when the date is 29 February.");
                        }
                    }

                    _year = year;
                    return this;
                }

                throw new Error("Invalid argument: year");
            };

            this.month = function (month) {
                if (ValidatorGeneral.isEmpty(month)) {
                    return _month;
                }

                if (ValidatorDate.isMonth(month)) {
                    _month = month;
                    return this;
                }

                throw new Error("Invalid argument: month");
            };

            this.day = function (day) {
                if (ValidatorGeneral.isEmpty(day)) {
                    return _day;
                }

                if (ValidatorDate.isDay(day)) {
                    _day = day;
                    return this;
                }

                throw new Error("Invalid argument: day");
            };

            this.hour = function (hour) {
                if (ValidatorGeneral.isEmpty(hour)) {
                    return _hour;
                }

                if (ValidatorDate.isHour(hour)) {
                    _hour = hour;
                    return this;
                }

                throw new Error("Invalid argument: hour");
            };

            this.minute = function (minute) {
                if (ValidatorGeneral.isEmpty(minute)) {
                    return _minute;
                }

                if (ValidatorDate.isMinute(minute)) {
                    _minute = minute;
                    return this;
                }

                throw new Error("Invalid argument: minute");
            };

            this.second = function (second) {
                if (ValidatorGeneral.isEmpty(second)) {
                    return _second;
                }

                if (ValidatorDate.isSecond(second)) {
                    _second = second;
                    return this;
                }

                throw new Error("Invalid argument: second");
            };

            this.millisecond = function (millisecond) {
                if (ValidatorGeneral.isEmpty(millisecond)) {
                    return _millisecond;
                }

                if (ValidatorDate.isMillisecond(millisecond)) {
                    _millisecond = millisecond;
                    return this;
                }

                throw new Error("Invalid argument: millisecond");
            };
        };

        Date.prototype.format = function format(format) {
            if (!ValidatorDate.isFormatString(format)) {
                throw new Error("Invalid argument: format.");
            }
            // TODO:
            return "1st July 2015";
        };

        Date.prototype.getTimestamp = function () {
            // TODO:
        };

        Date.prototype.getDayOfWeek = function () {
            // TODO:
        };

        Date.prototype.isLeapYear = function () {
            return ValidatorDate.isLeapYear(this.year());
        };

        Date.prototype.toString = function () {
            var toString = "year: " + this.year() + "\r\n month: " + this.month() + "\r\n day: " + this.day()
                    + "\r\n hour: " + this.hour() + "\r\n minute: " + this.minute()
                    + "\r\n second: " + this.second() + "\r\n millisecond: " + this.millisecond();
            return toString;
        };

        return Date;
    }());

    return {
        "Date": Date,
        "parseToDate": parseToDate,
        "getConst": Const.get,
        "isLeapYear": ValidatorDate.isLeapYear,
        "getDaysInYear": getDaysInYear
    };
}());<|endoftext|>