<commit_before>/*
 * Mailcheck https://github.com/Kicksend/mailcheck
 * Author
 * Derrick Ko (@derrickko)
 *
 * License
 * Copyright (c) 2012 Receivd, Inc.
 *
 * Licensed under the MIT License.
 *
 * v 1.1
 */

var Kicksend = {
  mailcheck : {
    threshold: 3,

    defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
      "live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
      "facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com"],

    defaultTopLevelDomains: ["co.uk", "com", "net", "org", "info", "edu", "gov", "mil"],

    run: function(opts) {
      opts.domains = opts.domains || Kicksend.mailcheck.defaultDomains;
      opts.topLevelDomains = opts.topLevelDomains || Kicksend.mailcheck.defaultTopLevelDomains;
      opts.distanceFunction = opts.distanceFunction || Kicksend.sift3Distance;

      var result = Kicksend.mailcheck.suggest(encodeURI(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);

      if (result) {
        if (opts.suggested) {
          opts.suggested(result);
        }
      } else {
        if (opts.empty) {
          opts.empty();
        }
      }
    },

    suggest: function(email, domains, topLevelDomains, distanceFunction) {
      email = email.toLowerCase();

      var emailParts = this.splitEmail(email);

      var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction);

      if (closestDomain) {
        if (closestDomain != emailParts.domain) {
          // The email address closely matches one of the supplied domains; return a suggestion
          return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
        }
      } else {
        // The email address does not closely match one of the supplied domains
        var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains);
        if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
          // The email address may have a mispelled top-level domain; return a suggestion
          var domain = emailParts.domain;
          closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
          return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
        }
      }
      /* The email address exactly matches one of the supplied domains, does not closely
       * match any domain and does not appear to simply have a mispelled top-level domain,
       * or is an invalid email address; do not return a suggestion.
       */
      return false;
    },

    findClosestDomain: function(domain, domains, distanceFunction) {
      var dist;
      var minDist = 99;
      var closestDomain = null;

      if (!domain || !domains) {
        return false;
      }
      if(!distanceFunction) {
        distanceFunction = this.sift3Distance;
      }

      for (var i = 0; i < domains.length; i++) {
        if (domain === domains[i]) {
          return domain;
        }
        dist = distanceFunction(domain, domains[i]);
        if (dist < minDist) {
          minDist = dist;
          closestDomain = domains[i];
        }
      }

      if (minDist <= this.threshold && closestDomain !== null) {
        return closestDomain;
      } else {
        return false;
      }
    },

    sift3Distance: function(s1, s2) {
      // sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
      if (s1 == null || s1.length === 0) {
        if (s2 == null || s2.length === 0) {
          return 0;
        } else {
          return s2.length;
        }
      }

      if (s2 == null || s2.length === 0) {
        return s1.length;
      }

      var c = 0;
      var offset1 = 0;
      var offset2 = 0;
      var lcs = 0;
      var maxOffset = 5;

      while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
        if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
          lcs++;
        } else {
          offset1 = 0;
          offset2 = 0;
          for (var i = 0; i < maxOffset; i++) {
            if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
              offset1 = i;
              break;
            }
            if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
              offset2 = i;
              break;
            }
          }
        }
        c++;
      }
      return (s1.length + s2.length) /2 - lcs;
    },

    splitEmail: function(email) {
      var parts = email.split('@');

      if (parts.length < 2) {
        return false;
      }

      for (var i = 0; i < parts.length; i++) {
        if (parts[i] === '') {
          return false;
        }
      }

      var domain = parts.pop();
      var domainParts = domain.split('.');
      var tld = '';

      if (domainParts.length == 0) {
        // The address does not have a top-level domain
        return false;
      } else if (domainParts.length == 1) {
        // The address has only a top-level domain (valid under RFC)
        tld = domainParts[0];
      } else {
        // The address has a domain and a top-level domain
        for (var i = 1; i < domainParts.length; i++) {
          tld += domainParts[i] + '.';
        }
        if (domainParts.length >= 2) {
          tld = tld.substring(0, tld.length - 1);
        }
      }

      return {
        topLevelDomain: tld,
        domain: domain,
        address: parts.join('@')
      }
    }
  }
};

if (window.jQuery) {
  (function($){
    $.fn.mailcheck = function(opts) {
      var self = this;
      if (opts.suggested) {
        var oldSuggested = opts.suggested;
        opts.suggested = function(result) {
          oldSuggested(self, result);
        };
      }

      if (opts.empty) {
        var oldEmpty = opts.empty;
        opts.empty = function() {
          oldEmpty.call(null, self);
        };
      }

      opts.email = this.val();
      Kicksend.mailcheck.run(opts);
    }
  })(jQuery);
}
<commit_msg>Node support: implement require() export!<commit_after>/*
 * Mailcheck https://github.com/Kicksend/mailcheck
 * Author
 * Derrick Ko (@derrickko)
 *
 * License
 * Copyright (c) 2012 Receivd, Inc.
 *
 * Licensed under the MIT License.
 *
 * v 1.1
 */

var Kicksend = {
  mailcheck : {
    threshold: 3,

    defaultDomains: ["yahoo.com", "google.com", "hotmail.com", "gmail.com", "me.com", "aol.com", "mac.com",
      "live.com", "comcast.net", "googlemail.com", "msn.com", "hotmail.co.uk", "yahoo.co.uk",
      "facebook.com", "verizon.net", "sbcglobal.net", "att.net", "gmx.com", "mail.com", "outlook.com"],

    defaultTopLevelDomains: ["co.uk", "com", "net", "org", "info", "edu", "gov", "mil"],

    run: function(opts) {
      opts.domains = opts.domains || Kicksend.mailcheck.defaultDomains;
      opts.topLevelDomains = opts.topLevelDomains || Kicksend.mailcheck.defaultTopLevelDomains;
      opts.distanceFunction = opts.distanceFunction || Kicksend.sift3Distance;

      var result = Kicksend.mailcheck.suggest(encodeURI(opts.email), opts.domains, opts.topLevelDomains, opts.distanceFunction);

      if (result) {
        if (opts.suggested) {
          opts.suggested(result);
        }
      } else {
        if (opts.empty) {
          opts.empty();
        }
      }
    },

    suggest: function(email, domains, topLevelDomains, distanceFunction) {
      email = email.toLowerCase();

      var emailParts = this.splitEmail(email);

      var closestDomain = this.findClosestDomain(emailParts.domain, domains, distanceFunction);

      if (closestDomain) {
        if (closestDomain != emailParts.domain) {
          // The email address closely matches one of the supplied domains; return a suggestion
          return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
        }
      } else {
        // The email address does not closely match one of the supplied domains
        var closestTopLevelDomain = this.findClosestDomain(emailParts.topLevelDomain, topLevelDomains);
        if (emailParts.domain && closestTopLevelDomain && closestTopLevelDomain != emailParts.topLevelDomain) {
          // The email address may have a mispelled top-level domain; return a suggestion
          var domain = emailParts.domain;
          closestDomain = domain.substring(0, domain.lastIndexOf(emailParts.topLevelDomain)) + closestTopLevelDomain;
          return { address: emailParts.address, domain: closestDomain, full: emailParts.address + "@" + closestDomain };
        }
      }
      /* The email address exactly matches one of the supplied domains, does not closely
       * match any domain and does not appear to simply have a mispelled top-level domain,
       * or is an invalid email address; do not return a suggestion.
       */
      return false;
    },

    findClosestDomain: function(domain, domains, distanceFunction) {
      var dist;
      var minDist = 99;
      var closestDomain = null;

      if (!domain || !domains) {
        return false;
      }
      if(!distanceFunction) {
        distanceFunction = this.sift3Distance;
      }

      for (var i = 0; i < domains.length; i++) {
        if (domain === domains[i]) {
          return domain;
        }
        dist = distanceFunction(domain, domains[i]);
        if (dist < minDist) {
          minDist = dist;
          closestDomain = domains[i];
        }
      }

      if (minDist <= this.threshold && closestDomain !== null) {
        return closestDomain;
      } else {
        return false;
      }
    },

    sift3Distance: function(s1, s2) {
      // sift3: http://siderite.blogspot.com/2007/04/super-fast-and-accurate-string-distance.html
      if (s1 == null || s1.length === 0) {
        if (s2 == null || s2.length === 0) {
          return 0;
        } else {
          return s2.length;
        }
      }

      if (s2 == null || s2.length === 0) {
        return s1.length;
      }

      var c = 0;
      var offset1 = 0;
      var offset2 = 0;
      var lcs = 0;
      var maxOffset = 5;

      while ((c + offset1 < s1.length) && (c + offset2 < s2.length)) {
        if (s1.charAt(c + offset1) == s2.charAt(c + offset2)) {
          lcs++;
        } else {
          offset1 = 0;
          offset2 = 0;
          for (var i = 0; i < maxOffset; i++) {
            if ((c + i < s1.length) && (s1.charAt(c + i) == s2.charAt(c))) {
              offset1 = i;
              break;
            }
            if ((c + i < s2.length) && (s1.charAt(c) == s2.charAt(c + i))) {
              offset2 = i;
              break;
            }
          }
        }
        c++;
      }
      return (s1.length + s2.length) /2 - lcs;
    },

    splitEmail: function(email) {
      var parts = email.split('@');

      if (parts.length < 2) {
        return false;
      }

      for (var i = 0; i < parts.length; i++) {
        if (parts[i] === '') {
          return false;
        }
      }

      var domain = parts.pop();
      var domainParts = domain.split('.');
      var tld = '';

      if (domainParts.length == 0) {
        // The address does not have a top-level domain
        return false;
      } else if (domainParts.length == 1) {
        // The address has only a top-level domain (valid under RFC)
        tld = domainParts[0];
      } else {
        // The address has a domain and a top-level domain
        for (var i = 1; i < domainParts.length; i++) {
          tld += domainParts[i] + '.';
        }
        if (domainParts.length >= 2) {
          tld = tld.substring(0, tld.length - 1);
        }
      }

      return {
        topLevelDomain: tld,
        domain: domain,
        address: parts.join('@')
      }
    }
  }
};

// Export the mailcheck object if we're in a CommonJS env (e.g. Node).
// Modeled off of Underscore.js.
if (typeof module !== 'undefined' && module.exports) {
    module.exports = Kicksend.mailcheck;
}

if (typeof window !== 'undefined' && window.jQuery) {
  (function($){
    $.fn.mailcheck = function(opts) {
      var self = this;
      if (opts.suggested) {
        var oldSuggested = opts.suggested;
        opts.suggested = function(result) {
          oldSuggested(self, result);
        };
      }

      if (opts.empty) {
        var oldEmpty = opts.empty;
        opts.empty = function() {
          oldEmpty.call(null, self);
        };
      }

      opts.email = this.val();
      Kicksend.mailcheck.run(opts);
    }
  })(jQuery);
}
<|endoftext|>


<commit_before>var file_formats = require('../renderer/file-actions.js').formats
const {shell} = require('electron')

// build 'Open...' and 'Save As...' submenus
var open_submenu = []
var save_submenu = []
for (var format in file_formats) {
  var open_option = {
    label: file_formats[format].label,
    click: (function(format) {
      return function() {
        fileActions.openFile(format)
      }
    }(file_formats[format]))
  }
  if (format === 'csv') {
    open_option.accelerator = 'CmdOrCtrl+O'
  }
  open_submenu.push(open_option)
// label should have ... appended to end of each menu item
  var save_option = {
    label: file_formats[format].label,
    click: (function(format) {
      return function() {
        fileActions.saveFileAs(format)
      }
    }(file_formats[format]))
  }
  if (format === 'csv') {
    save_option.accelerator = 'Shift+CmdOrCtrl+S'
  }
  save_submenu.push(save_option)
}
// Placeholder for Custom Dialect feature
// open_submenu.push({
//   label: 'Custom Dialect...',
//   enabled: false,
//   click: function() {
//     fileActions.openCustom()
//   }
// })
// save_submenu.push({
//   label: 'Custom Dialect...',
//   enabled: false,
//   click: function() {
//     fileActions.saveAsCustom()
//   }
// })

exports.menu = [
  {
// Only show the Data Curator menu for macOS.
// TO DO: add test for macOS...
    label: 'Data Curator',
    submenu: [
      {
        label: 'About Data Curator',
        click: function() {
          utils.showSidePanel('about')
        }
      }, {
        label: 'Check for Update',
        enabled: false
      }, {
        type: 'separator'
      }, {
        label: process.platform === 'darwin'
          ? 'Preferences'
          : 'Settings',
        accelerator: 'CmdOrCtrl+,',
        click: function() {
          utils.showSidePanel('preferences')
        }
      }, {
        type: 'separator'
      }, {
        role: 'services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        role: 'hide'
      }, {
        role: 'hideothers'
      }, {
        role: 'unhide'
      }, {
        type: 'separator'
      }, {
        role: 'quit'
      }
    ]
  }, {
    label: 'File',
    submenu: [
      {
        label: 'New',
        accelerator: 'CmdOrCtrl+N',
        click: function() {
          utils.createWindowTab()
        }
      }, {
        type: 'separator'
      }, {
        label: 'Open',
        submenu: open_submenu
      }, {
        label: 'Open Excel Sheet...',
        click: function() {
          excel.importExcel()
        }
// Placeholder for future feature
//      }, {
//        label: 'Open Google Sheet...',
//        enabled: false
      }, {
        label: 'Open Data Package...'
// Placeholder for future feature
//      }, {
//        label: 'Open Recent',
//        submenu: [
//          {
//            label: 'example.csv',
//            enabled: false
//          }, {
//            type: 'separator'
//          }, {
//            label: 'Clear Menu',
//            enabled: false
//          }
//        ]
      }, {
// Placeholder for non-macOS Settings for future feature
        type: 'separator'
      }, {
        label: 'Save',
        accelerator: 'CmdOrCtrl+S',
        click: function() {
          fileActions.saveFile()
        },
        id: 'save'
      }, {
        label: 'Save As',
        submenu: save_submenu
      }, {
        label: 'Save All',
        accelerator: 'Alt+CmdOrCtrl+S'
      }, {
        type: 'separator'
      }, {
        label: 'Close Tab',
        accelerator: 'CmdOrCtrl+W'
      }
// Placeholder for future features
//, {
//        label: 'Close All'
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Print',
//        accelerator: 'CmdOrCtrl+P',
//        enabled: false
//      }
    ]
  }, {
    label: 'Edit',
    submenu: [
      {
        role: 'undo'
      }, {
        role: 'redo',
        accelerator: 'CmdOrCtrl+Y'
      }, {
        type: 'separator'
      }, {
        role: 'cut'
      }, {
        role: 'copy'
      }, {
        role: 'paste'
      }, {
        role: 'selectall'
      }, {
        type: 'separator'
      }, {
        label: 'Insert Row Above',
        accelerator: 'CmdOrCtrl+I',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertRowAbove')
        }
      }, {
        label: 'Insert Row Below',
        accelerator: 'CmdOrCtrl+K',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertRowBelow')
        }
      }, {
        type: 'separator'
      }, {
        label: 'Insert Column Before',
        accelerator: 'CmdOrCtrl+J',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertColumnLeft')
        }
      }, {
        label: 'Insert Column After',
        accelerator: 'CmdOrCtrl+L',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertColumnRight')
        }
      }, {
        type: 'separator'
      }, {
        label: 'Remove Row(s)',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('removeRows')
        }
      }, {
        label: 'Remove Column(s)',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('removeColumns')
        }
      }
    ]
  }, {
// Placeholder for future features
//    label: 'View',
//    submenu: [
//      {
//        label: 'Read Only',
//        type: 'checkbox',
//        checked: true,
//        enabled: false
//      }, {
// TO DO: hide toggledevtools in production release and make a application shortcut
//        role: 'toggledevtools'
//      }, {
//        type: 'separator'
//      }, {
//        role: 'togglefullscreen'
//      }
//    ]
//  }, {
//    label: 'Find',
//    submenu: [
//      {
//        label: 'Find',
//        accelerator: 'CmdOrCtrl+F',
//        enabled: false
//      }, {
//        label: 'Find Next',
//        accelerator: 'CmdOrCtrl+G',
//        enabled: false
//      }, {
//        label: 'Find Previous',
//        accelerator: 'Shift+CmdOrCtrl+G',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Replace',
//        accelerator: 'Alt+CmdOrCtrl+F',
//        enabled: false
//      }, {
//        label: 'Replace Next',
//        accelerator: 'Alt+CmdOrCtrl+E',
//        enabled: false
//      }, {
//        label: 'Replace All',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Sort',
//        accelerator: 'Shift+CmdOrCtrl+R',
//        enabled: false
//      }, {
//        label: 'Filter',
//        enabled: false
//      }
//    ]
//  }, {
    label: 'Tools',
    submenu: [
      {
// TO DO: hide toggledevtools in production release and make a application shortcut
        role: 'toggledevtools'
      }, {
        type: 'separator'
      }, {
        label: 'Fix Ragged Rows',
        click: function() {
          tools.fixRaggedRowsFile()
        }
// Placeholder for future features
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Import Column Properties...',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Create Constraint from Column',
//        enabled: false
//      }, {
//        label: 'Create Look-up Table from Column',
//        enabled: false
      }, {
        type: 'separator'
      }, {
        label: 'Validate Table',
        accelerator: 'Shift+CmdOrCtrl+V',
        click: function() {
          validate.validateFile()
        }
      }, {
        type: 'separator'
      }, {
        label: 'Guess Column Properties'
      }, {
        label: 'Set Column Properties'
      }, {
        label: 'Set Table Properties'
      }, {
// Placeholder for future features
//        label: 'Set View Properties',
//        enabled: false
//       , icon: '/static/img/locked.svg'
//      }, {
        label: 'Set Provenance Information'
      }, {
// Placeholder for future features
//        label: 'Generate Data Quality Information',
//        enabled: false
//       , icon: '/static/img/locked.svg'
//      }, {
        label: 'Set Data Package Properties'
      }, {
        type: 'separator'
      }, {
// TO DO: Conditionally enabled based on required properties being set and no changes since last successful validation
        label: 'Export Data Package...',
        accelerator: 'CmdOrCtrl+D',
        click: function() {
          datapackage.exportdata()
        }
      }
// Placeholder for future features
//      , {
// Conditionally enabled based on API keys set and Data Package Exported
//        label: 'Publish Data Package to',
//        enabled: false,
//        submenu: [
//          {
//            label: 'CKAN',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }, {
//            label: 'DataHub',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }, {
//            label: 'OctoPub',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }
//        ]
//      }
    ]
  }, {
// TO DO: Update this menu if Data Curator is a multi window app
    label: 'Window',
    submenu: [
// TO DO: hide below in Windows and Linux
      {
        role: 'minimize'
      }, {
        role: 'zoom'
      }, {
        type: 'separator'
// hide above
      }, {
        label: 'Next Tab',
        accelerator: 'CmdOrCtrl+Right'
      }, {
        label: 'Previous Tab',
        accelerator: 'CmdOrCtrl+Left'
      }, {
// TO DO: hide below in Windows and Linux
        type: 'separator'
      }, {
        role: 'front'
      }
// hide above
    ]
  }, {
    role: 'help',
    submenu: [
      {
// Placeholder for future features
//        label: 'Data Curator Help',
// show accelerator for Windows and Linux only
//        accelerator: process.platform === 'darwin'
//          ? ''
//          : 'F1',
// hide above
//        click: function() {
//          shell.openExternal('https://odiqueensland.github.io/data-curator-help/')
//        }
//      }, {
        label: 'Keyboard Shortcuts',
        accelerator: 'CmdOrCtrl+/',
        click: function() {
          help.showKeyboardHelp()
        }
      }, {
        type: 'separator'
// Placeholder for Windows/Linux 'Check for Updates' future feature
      }, {
        label: 'Support Forum',
        click: function() {
          shell.openExternal('https://ask.theodi.org.au/c/projects/data-curator')
        }
      }, {
        label: 'Report Issues',
        click: function() {
          shell.openExternal('https://github.com/ODIQueensland/data-curator/blob/develop/.github/CONTRIBUTING.md')
        }
      }
// Placeholder for future feature
//      , {
//        type: 'separator'
//      }, {
//        label: 'Welcome Guide',
//        enabled: false
//      }
    ]
  }
]
<commit_msg>hide check for update and preferences<commit_after>var file_formats = require('../renderer/file-actions.js').formats
const {shell} = require('electron')

// build 'Open...' and 'Save As...' submenus
var open_submenu = []
var save_submenu = []
for (var format in file_formats) {
  var open_option = {
    label: file_formats[format].label,
    click: (function(format) {
      return function() {
        fileActions.openFile(format)
      }
    }(file_formats[format]))
  }
  if (format === 'csv') {
    open_option.accelerator = 'CmdOrCtrl+O'
  }
  open_submenu.push(open_option)
// label should have ... appended to end of each menu item
  var save_option = {
    label: file_formats[format].label,
    click: (function(format) {
      return function() {
        fileActions.saveFileAs(format)
      }
    }(file_formats[format]))
  }
  if (format === 'csv') {
    save_option.accelerator = 'Shift+CmdOrCtrl+S'
  }
  save_submenu.push(save_option)
}
// Placeholder for Custom Dialect feature
// open_submenu.push({
//   label: 'Custom Dialect...',
//   enabled: false,
//   click: function() {
//     fileActions.openCustom()
//   }
// })
// save_submenu.push({
//   label: 'Custom Dialect...',
//   enabled: false,
//   click: function() {
//     fileActions.saveAsCustom()
//   }
// })

exports.menu = [
  {
// Only show the Data Curator menu for macOS.
// TO DO: add test for macOS...
    label: 'Data Curator',
    submenu: [
      {
        label: 'About Data Curator',
        click: function() {
          utils.showSidePanel('about')
        }
// Placeholder for future feature
//      }, {
//        label: 'Check for Update',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: process.platform === 'darwin'
//          ? 'Preferences'
//          : 'Settings',
//        accelerator: 'CmdOrCtrl+,',
//        click: function() {
//          utils.showSidePanel('preferences')
//        }
      }, {
        type: 'separator'
      }, {
        role: 'services',
        submenu: []
      }, {
        type: 'separator'
      }, {
        role: 'hide'
      }, {
        role: 'hideothers'
      }, {
        role: 'unhide'
      }, {
        type: 'separator'
      }, {
        role: 'quit'
      }
    ]
  }, {
    label: 'File',
    submenu: [
      {
        label: 'New',
        accelerator: 'CmdOrCtrl+N',
        click: function() {
          utils.createWindowTab()
        }
      }, {
        type: 'separator'
      }, {
        label: 'Open',
        submenu: open_submenu
      }, {
        label: 'Open Excel Sheet...',
        click: function() {
          excel.importExcel()
        }
// Placeholder for future feature
//      }, {
//        label: 'Open Google Sheet...',
//        enabled: false
      }, {
        label: 'Open Data Package...'
// Placeholder for future feature
//      }, {
//        label: 'Open Recent',
//        submenu: [
//          {
//            label: 'example.csv',
//            enabled: false
//          }, {
//            type: 'separator'
//          }, {
//            label: 'Clear Menu',
//            enabled: false
//          }
//        ]
      }, {
// Placeholder for non-macOS Settings for future feature
        type: 'separator'
      }, {
        label: 'Save',
        accelerator: 'CmdOrCtrl+S',
        click: function() {
          fileActions.saveFile()
        },
        id: 'save'
      }, {
        label: 'Save As',
        submenu: save_submenu
      }, {
        label: 'Save All',
        accelerator: 'Alt+CmdOrCtrl+S'
      }, {
        type: 'separator'
      }, {
        label: 'Close Tab',
        accelerator: 'CmdOrCtrl+W'
      }
// Placeholder for future features
//, {
//        label: 'Close All'
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Print',
//        accelerator: 'CmdOrCtrl+P',
//        enabled: false
//      }
    ]
  }, {
    label: 'Edit',
    submenu: [
      {
        role: 'undo'
      }, {
        role: 'redo',
        accelerator: 'CmdOrCtrl+Y'
      }, {
        type: 'separator'
      }, {
        role: 'cut'
      }, {
        role: 'copy'
      }, {
        role: 'paste'
      }, {
        role: 'selectall'
      }, {
        type: 'separator'
      }, {
        label: 'Insert Row Above',
        accelerator: 'CmdOrCtrl+I',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertRowAbove')
        }
      }, {
        label: 'Insert Row Below',
        accelerator: 'CmdOrCtrl+K',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertRowBelow')
        }
      }, {
        type: 'separator'
      }, {
        label: 'Insert Column Before',
        accelerator: 'CmdOrCtrl+J',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertColumnLeft')
        }
      }, {
        label: 'Insert Column After',
        accelerator: 'CmdOrCtrl+L',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('insertColumnRight')
        }
      }, {
        type: 'separator'
      }, {
        label: 'Remove Row(s)',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('removeRows')
        }
      }, {
        label: 'Remove Column(s)',
        click: function() {
          BrowserWindow.getFocusedWindow().webContents.send('removeColumns')
        }
      }
    ]
  }, {
// Placeholder for future features
//    label: 'View',
//    submenu: [
//      {
//        label: 'Read Only',
//        type: 'checkbox',
//        checked: true,
//        enabled: false
//      }, {
// TO DO: hide toggledevtools in production release and make a application shortcut
//        role: 'toggledevtools'
//      }, {
//        type: 'separator'
//      }, {
//        role: 'togglefullscreen'
//      }
//    ]
//  }, {
//    label: 'Find',
//    submenu: [
//      {
//        label: 'Find',
//        accelerator: 'CmdOrCtrl+F',
//        enabled: false
//      }, {
//        label: 'Find Next',
//        accelerator: 'CmdOrCtrl+G',
//        enabled: false
//      }, {
//        label: 'Find Previous',
//        accelerator: 'Shift+CmdOrCtrl+G',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Replace',
//        accelerator: 'Alt+CmdOrCtrl+F',
//        enabled: false
//      }, {
//        label: 'Replace Next',
//        accelerator: 'Alt+CmdOrCtrl+E',
//        enabled: false
//      }, {
//        label: 'Replace All',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Sort',
//        accelerator: 'Shift+CmdOrCtrl+R',
//        enabled: false
//      }, {
//        label: 'Filter',
//        enabled: false
//      }
//    ]
//  }, {
    label: 'Tools',
    submenu: [
      {
// TO DO: hide toggledevtools in production release and make a application shortcut
        role: 'toggledevtools'
      }, {
        type: 'separator'
      }, {
        label: 'Fix Ragged Rows',
        click: function() {
          tools.fixRaggedRowsFile()
        }
// Placeholder for future features
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Import Column Properties...',
//        enabled: false
//      }, {
//        type: 'separator'
//      }, {
//        label: 'Create Constraint from Column',
//        enabled: false
//      }, {
//        label: 'Create Look-up Table from Column',
//        enabled: false
      }, {
        type: 'separator'
      }, {
        label: 'Validate Table',
        accelerator: 'Shift+CmdOrCtrl+V',
        click: function() {
          validate.validateFile()
        }
      }, {
        type: 'separator'
      }, {
        label: 'Guess Column Properties'
      }, {
        label: 'Set Column Properties'
      }, {
        label: 'Set Table Properties'
      }, {
// Placeholder for future features
//        label: 'Set View Properties',
//        enabled: false
//       , icon: '/static/img/locked.svg'
//      }, {
        label: 'Set Provenance Information'
      }, {
// Placeholder for future features
//        label: 'Generate Data Quality Information',
//        enabled: false
//       , icon: '/static/img/locked.svg'
//      }, {
        label: 'Set Data Package Properties'
      }, {
        type: 'separator'
      }, {
// TO DO: Conditionally enabled based on required properties being set and no changes since last successful validation
        label: 'Export Data Package...',
        accelerator: 'CmdOrCtrl+D',
        click: function() {
          datapackage.exportdata()
        }
      }
// Placeholder for future features
//      , {
// Conditionally enabled based on API keys set and Data Package Exported
//        label: 'Publish Data Package to',
//        enabled: false,
//        submenu: [
//          {
//            label: 'CKAN',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }, {
//            label: 'DataHub',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }, {
//            label: 'OctoPub',
//            enabled: false
//          , icon: '/static/img/locked.svg'
//          }
//        ]
//      }
    ]
  }, {
// TO DO: Update this menu if Data Curator is a multi window app
    label: 'Window',
    submenu: [
// TO DO: hide below in Windows and Linux
      {
        role: 'minimize'
      }, {
        role: 'zoom'
      }, {
        type: 'separator'
// hide above
      }, {
        label: 'Next Tab',
        accelerator: 'CmdOrCtrl+Right'
      }, {
        label: 'Previous Tab',
        accelerator: 'CmdOrCtrl+Left'
      }, {
// TO DO: hide below in Windows and Linux
        type: 'separator'
      }, {
        role: 'front'
      }
// hide above
    ]
  }, {
    role: 'help',
    submenu: [
      {
// Placeholder for future features
//        label: 'Data Curator Help',
// show accelerator for Windows and Linux only
//        accelerator: process.platform === 'darwin'
//          ? ''
//          : 'F1',
// hide above
//        click: function() {
//          shell.openExternal('https://odiqueensland.github.io/data-curator-help/')
//        }
//      }, {
        label: 'Keyboard Shortcuts',
        accelerator: 'CmdOrCtrl+/',
        click: function() {
          help.showKeyboardHelp()
        }
      }, {
        type: 'separator'
// Placeholder for Windows/Linux 'Check for Updates' future feature
      }, {
        label: 'Support Forum',
        click: function() {
          shell.openExternal('https://ask.theodi.org.au/c/projects/data-curator')
        }
      }, {
        label: 'Report Issues',
        click: function() {
          shell.openExternal('https://github.com/ODIQueensland/data-curator/blob/develop/.github/CONTRIBUTING.md')
        }
      }
// Placeholder for future feature
//      , {
//        type: 'separator'
//      }, {
//        label: 'Welcome Guide',
//        enabled: false
//      }
    ]
  }
]
<|endoftext|>


<commit_before>
angular.module('os.administrative.job.addedit', ['os.administrative.models'])
  .controller('JobAddEditCtrl', function($scope, $state, $translate, SavedQuery, currentUser, job) {

    var defSavedQueries = undefined;

    function init() {
      job.$$editAllowed = !job.id || currentUser.admin || currentUser.id == job.createdBy.id;
      job.startDate = job.startDate || new Date();
      job.rtArgsProvided = job.rtArgsProvided || false;

      $scope.weekDays = getWeekDays();
      $scope.job =  job;
      $scope.savedQueries = [];
      if (job.type == 'QUERY') {
        onQueryTypeSelect();
      }
    }

    function getWeekDays() {
      var weekDays = [
        {name: 'SUNDAY'}, {name: 'MONDAY'}, {name: 'TUESDAY'}, {name: 'WEDNESDAY'},
        {name: 'THURSDAY'}, {name: 'FRIDAY'}, {name: 'SATURDAY'}
      ];

      $translate('job.week_days.SUNDAY').then(
        function(wd) {
          angular.forEach(weekDays,
            function(wd) {
              wd.caption = $translate.instant('jobs.week_days.' + wd.name);
            }
          );
        }
      );

      return weekDays;
    }

    function loadSavedQueries(searchTerm) {
      if (!searchTerm && defSavedQueries) {
        $scope.savedQueries = defSavedQueries;
        return;
      }

      SavedQuery.query({searchString: searchTerm}).then(
        function(savedQueries) {
          $scope.savedQueries = savedQueries;
          if (!searchTerm) {
            defSavedQueries = savedQueries;
          }
        }
      );
    }

    function onQueryTypeSelect() {
      job.runAs = currentUser;
      loadSavedQueries();
    }

    $scope.selectQueryType = onQueryTypeSelect;

    $scope.loadSavedQueries = loadSavedQueries;

    $scope.saveOrUpdateJob = function() {
      $scope.job.$saveOrUpdate().then(
        function(result) {
          $state.go('job-list');
        }
      );
    }

    init();
  });
<commit_msg>OPSMN-5380: The UI is updated to not change the "Run As" user when the job is being edited.<commit_after>
angular.module('os.administrative.job.addedit', ['os.administrative.models'])
  .controller('JobAddEditCtrl', function($scope, $state, $translate, SavedQuery, currentUser, job) {

    var defSavedQueries = undefined;

    function init() {
      job.$$editAllowed = !job.id || currentUser.admin || currentUser.id == job.createdBy.id;
      job.startDate = job.startDate || new Date();
      job.rtArgsProvided = job.rtArgsProvided || false;

      $scope.weekDays = getWeekDays();
      $scope.job =  job;
      $scope.savedQueries = [];
      if (job.type == 'QUERY') {
        onQueryTypeSelect();
      }
    }

    function getWeekDays() {
      var weekDays = [
        {name: 'SUNDAY'}, {name: 'MONDAY'}, {name: 'TUESDAY'}, {name: 'WEDNESDAY'},
        {name: 'THURSDAY'}, {name: 'FRIDAY'}, {name: 'SATURDAY'}
      ];

      $translate('job.week_days.SUNDAY').then(
        function(wd) {
          angular.forEach(weekDays,
            function(wd) {
              wd.caption = $translate.instant('jobs.week_days.' + wd.name);
            }
          );
        }
      );

      return weekDays;
    }

    function loadSavedQueries(searchTerm) {
      if (!searchTerm && defSavedQueries) {
        $scope.savedQueries = defSavedQueries;
        return;
      }

      SavedQuery.query({searchString: searchTerm}).then(
        function(savedQueries) {
          $scope.savedQueries = savedQueries;
          if (!searchTerm) {
            defSavedQueries = savedQueries;
          }
        }
      );
    }

    function onQueryTypeSelect() {
      if (!job.id && !job.runAs) {
        job.runAs = currentUser;
      }

      loadSavedQueries();
    }

    $scope.selectQueryType = onQueryTypeSelect;

    $scope.loadSavedQueries = loadSavedQueries;

    $scope.saveOrUpdateJob = function() {
      $scope.job.$saveOrUpdate().then(
        function(result) {
          $state.go('job-list');
        }
      );
    }

    init();
  });
<|endoftext|>


<commit_before>const fs = require('fs');
const path = require('path');
const yargs = require('yargs').argv;

const validEnvironments = ['beta', 'development'];
if (!validEnvironments.includes(yargs.env)) {
  console.log(`Invalid ENVIRONMENT provided. Must be one of: [${validEnvironments.join('|')}]`);
  process.exit(1);
}

const env = yargs.env;
const workspaceRoot = path.join(__dirname, '..');
const buildDirectory = path.join(workspaceRoot, 'dist', 'extension');
const manifestPath = path.join(buildDirectory, 'manifest.json');

const manifest = require(manifestPath);
const changes = require(path.join(workspaceRoot, 'src', `manifest.${env}.json`));

// Clobber any keys in the beta manifest across.
Object.assign(manifest, changes);

// If we're in a github action, append the build number to the version number.
if (process.env.GITHUB_RUN_ID) {
  manifest.version += `.${process.env.GITHUB_RUN_ID}`;
  console.log(`using version: ${manifest.version}`);
}

// Delete the old one.
fs.unlinkSync(manifestPath);

// And write our new one.
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));

console.log(`${env} manifest applied.`);
<commit_msg>fix: use GITHUB_RUN_NUMBER for beta manifest version<commit_after>const fs = require('fs');
const path = require('path');
const yargs = require('yargs').argv;

const validEnvironments = ['beta', 'development'];
if (!validEnvironments.includes(yargs.env)) {
  console.log(`Invalid ENVIRONMENT provided. Must be one of: [${validEnvironments.join('|')}]`);
  process.exit(1);
}

const env = yargs.env;
const workspaceRoot = path.join(__dirname, '..');
const buildDirectory = path.join(workspaceRoot, 'dist', 'extension');
const manifestPath = path.join(buildDirectory, 'manifest.json');

const manifest = require(manifestPath);
const changes = require(path.join(workspaceRoot, 'src', `manifest.${env}.json`));

// Clobber any keys in the beta manifest across.
Object.assign(manifest, changes);

// If we're in a github action, append the build number to the version number.
if (process.env.GITHUB_RUN_NUMBER) {
  manifest.version += `.${process.env.GITHUB_RUN_NUMBER}`;
  console.log(`using version: ${manifest.version}`);
}

// Delete the old one.
fs.unlinkSync(manifestPath);

// And write our new one.
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));

console.log(`${env} manifest applied.`);
<|endoftext|>


<commit_before>export function next() {
    return {
        type: 'PLAYER_NEXT',
    }
}

export function prev() {
    return {
        type: 'PLAYER_PREV',
    }
}

export function add_next(file) {
    return {
        type: 'PLAYLIST_ADD_NEXT',
        file: file,
    }
}

export function add_last(file) {
    return {
        type: 'PLAYLIST_ADD_LAST',
        file: file,
    }
}

export function add_now(file) {
    return {
        type: 'PLAYLIST_ADD_NOW',
        file: file,
    }
}
<commit_msg>consistency<commit_after>export function next() {
    return {
        type: 'PLAYER_NEXT',
    }
}

export function prev() {
    return {
        type: 'PLAYER_PREV',
    }
}

export function add_next(item) {
    return {
        type: 'PLAYLIST_ADD_NEXT',
        item: item,
    }
}

export function add_last(item) {
    return {
        type: 'PLAYLIST_ADD_LAST',
        item: item,
    }
}

export function add_now(item) {
    return {
        type: 'PLAYLIST_ADD_NOW',
        item: item,
    }
}
<|endoftext|>


<commit_before>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 11/5/12
 * Time: 9:51 PM
 * To change this template use File | Settings | File Templates.
 */

define([
    'config/anthill',
    'modules/crud'
], function initModel(AntHill, CRUD) {

    /**
     * Define Base model
     * @class BaseModel
     * @extends CRUD
     * @extends AntHill
     * @constructor
     */
    var BaseModel = function BaseModel() {

    };

    return BaseModel.extend('BaseModel', {

        /**
         * Get scope config
         * @member BaseModel
         * @param {String} [key]
         * @returns {*}
         */
        getConfig: function getConfig(key) {
            var scope = this.scope,
                config = scope.config,
                reference = scope.config;

            if (typeof(key) === 'undefined') {
                return config;
            }

            /**
             * Split key by slash
             * @type {Array}
             */
            var path = key.split('/');

            for (var i = 0, l = path.length; i < l; i++) {

                /**
                 * Get config node
                 */
                var node = path[i];

                if (reference.hasOwnProperty(node)) {

                    scope.logger.debug('Get config by key', node);
                    reference = reference[node];

                } else {
                    scope.logger.warn('Undefined config key', node);
                    return false;
                }
            }

            scope.logger.debug('Get config', reference);

            return reference;
        },

        /**
         * Set scope config
         * @member BaseModel
         * @param {String} [key]
         * @param {*} [value]
         * @returns {scope.config}
         */
        setConfig: function setConfig(key, value) {
            var scope = this.scope,
                config = scope.config;
            if (config.hasOwnProperty(key)) {
                scope.logger.debug('Update config', key, value);
                config[key] = value;
            }
            scope.logger.debug('Set config new data', key, value);
            config[key] = value;
            return this.getConfig(key);
        },

        /**
         * Get scope namespace
         * @member BaseModel
         * @param {*} node
         * @returns {string}
         */
        getNameSpace: function getNameSpace(node) {
            var base = this.base,
                scope = base.isDefined(node) ?
                    node : this.scope,
                constructor = base.isFunction(scope) ?
                    scope : scope.constructor;

            return constructor.name.toLowerCase();
        },

        /**
         * Find item in a whole project
         * @member BaseModel
         * @param {*} root
         * @param {string} uuid
         * @return {*}
         */
        findItemByUUID: function findItemByUUID(root, uuid) {

            if (!root) {
                this.scope.logger.error('Undefined root', root);
            }

            // Get child node
            var child = root.model.getItemByUUID(uuid);

            if (child) {
                return child;
            }

            // Get all items
            var items = root.model.getItems();

            for (var index in items) {

                if (items.hasOwnProperty(index)) {

                    var item = items[index];

                    // Recursive search
                    var search = item.model.findItemByUUID(
                        item, uuid
                    );

                    if (search) {
                        return search;
                    }
                }
            }
        },

        /**
         * Get parent items
         * @member BaseModel
         * @returns {*}
         */
        getParentItems: function getParentItems() {
            return this.scope.controller.getContainment().items;
        },

        /**
         * Get items
         * @member BaseModel
         * @returns {*}
         */
        getItems: function getItems() {
            return this.scope.items;
        },

        /**
         * Get all items apart of item
         * @member BaseModel
         * @param {{model}} item
         * @returns {Array}
         */
        getItemsApartOf: function getItemsApartOf(item) {

            var items = this.getItems(),
                nodes = [], index, node, nodeUUID,
                uuid = item.model.getUUID();

            for (index in items) {

                if (items.hasOwnProperty(index)) {

                    node = items[index];
                    nodeUUID = node.model.getUUID();

                    if (uuid !== nodeUUID) {
                        nodes.push(node);
                    }
                }
            }
            return nodes;
        },

        /**
         * Get UUID
         * @member BaseModel
         * @param {{model}} [node]
         * @returns {String}
         */
        getUUID: function getUUID(node) {
            return this.base.isDefined(node) ?
                node.model ?
                    node.model.getUUID() :
                    'Undefined ' + node.constructor.name :
                this.getConfig('uuid');
        },

        /**
         * Get item from collector by UUID
         * @member BaseModel
         * @param {string} uuid
         * @returns {*}
         */
        getItemByUUID: function getItemByUUID(uuid) {
            var base = this.base,
                items = this.getItems(),
                item = base.lib.hash.isHashKey(items, uuid) ?
                    items[uuid] : undefined;

            if (!base.isDefined(item)) {
                this.scope.logger.debug('Undefined item');
            }
            return item;
        },

        /**
         * Reset collector
         * @member BaseModel
         * @returns {*}
         */
        resetItems: function resetItems() {
            this.scope.items = {};
            return this.getItems();
        },

        /**
         * Delete widget from collector
         * @member BaseModel
         * @param uuid
         * @returns {*}
         */
        deleteItem: function deleteItem(uuid) {
            delete this.scope.controller.getContainment().items[uuid];
            return this.getParentItems();
        },

        /**
         * Update collector
         * @member BaseModel
         * @param {string} uuid
         * @param hash
         * returns {*}
         */
        updateItem: function updateItem(uuid, hash) {
            var item = this.getItemByUUID(uuid);
            $.extend(true, item, hash);
            return item;
        },

        /**
         * Add item to collector
         * @member BaseModel
         * @param {{model}} node
         * @param {boolean} [force]
         * @returns {*}
         */
        setItem: function setItem(node, force) {
            var base = this.base;

            node = base.define(node, {}, true);
            force = base.defineBoolean(force, false, true);

            var uuid = node.model.getUUID(),
                item = base.isDefined(this.getItemByUUID(uuid));
            if (force || !item) {
                this.getItems()[uuid] = node;
            } else if (item) {
                this.scope.logger.warn('Item already in collector');
            }
            return this.getItemByUUID(uuid);
        },

        /**
         * Get Item constructor name
         * @member BaseModel
         * @returns {string}
         */
        getItemNameSpace: function getItemNameSpace() {
            this.scope.logger.debug('Get item namespace');
            if (this.hasOwnProperty('item')) {
                return this.item.name.toLowerCase();
            }

            this.scope.logger.debug('Undefined item');
        },

        /**
         * Get items order
         * @member BaseModel
         * @returns {*}
         */
        getOrder: function getOrder() {
            return this.getConfig('order');
        },

        /**
         * Get prefs
         * @member BaseModel
         * @param {string} prefs
         * @returns {boolean|string}
         */
        getContentPrefs: function getContentPrefs(prefs) {

            if (!this.preferences[prefs]) {
                this.scope.logger.warn('Undefined preference', prefs);
                return false;
            }

            return this.preferences[prefs].value;
        },

        /**
         * Get prefs
         * @member BaseModel
         * @param {string} prefs
         * @returns {*}
         */
        getPrefs: function getPrefs(prefs) {

            if (this.base.isDefined(this.preferences)) {
                return this.getContentPrefs(prefs);
            }

            /**
             * Define prefs
             * @type {{}}
             */
            var preferences = this.scope.config.preferences;

            if (!preferences) {
                this.scope.logger.warn('Unable to locate preference', prefs);
                return false;
            }

            return preferences[prefs];
        },

        /**
         * Set prefs
         * @member BaseModel
         * @param {string} prefs
         * @param {*} value
         */
        setPrefs: function setPrefs(prefs, value) {

            /**
             * Define new prefs
             * @type {*}
             */
            this.preferences[prefs] = this.base.define(
                this.preferences[prefs], {}, true
            );

            /**
             * Define prefs
             * @type {string}
             */
            this.preferences[prefs].value = value;
        },

        /**
         * Copy prefs
         * @member BaseModel
         * @param source
         * @returns {boolean}
         */
        copyPrefs: function copyPrefs(source) {

            /**
             * Define
             * @type {string}
             */
            var cname = this.scope.constructor.name.toLowerCase(),
                prefs = source.model.preferences;

            if (source.constructor.name.toLowerCase() !== cname) {
                this.scope.logger.warn('Unable to copy preferences', source);
                return false;
            }

            for (var index in prefs) {

                if (prefs.hasOwnProperty(index)) {

                    if (index.match(new RegExp(cname))) {

                        this.setPrefs(index, prefs[index].value);
                        this.scope.logger.debug(
                            'Copied prefs', source, index, prefs[index]
                        );
                    }
                }
            }
        },

        /**
         * Set rules on loading
         * @member BaseModel
         * @param rules
         */
        setRules: function setRules(rules) {

            /**
             * Local rules storage
             * @member BaseModel
             * @type {{}}
             */
            this.rules = rules;
        },

        /**
         * Set Title
         * @member BaseModel
         * @param {string} title
         */
        setTitle: function setTitle(title) {
            this.setPrefs('title', title);
        },

        /**
         * Set Description
         * @member BaseModel
         * @param {string} description
         */
        setDescription: function setDescription(description) {
            this.setPrefs('description', description);
        },

        /**
         * Set on click Url
         * @member BaseModel
         * @param {string} url
         */
        setOnClickOpenUrl: function setOnClickOpenUrl(url) {

            this.setPrefs('onClickOpenUrl', url);

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList.setOnClickUrl,
                url
            );
        },

        /**
         * Set on top
         * @member BaseModel
         * @param {boolean} ontop
         */
        setAlwaysOnTop: function setAlwaysOnTop(ontop) {

            this.setPrefs('alwaysOnTop', ontop);

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList.setAlwaysOnTop,
                ontop
            );
        },

        /**
         * Save widget layer
         * @member BaseModel
         */
        setLayerUp: function setLayerUp(eventName) {

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList[eventName],
                true
            );
        },

        /**
         * Set overlapping
         * @member BaseModel
         * @param {boolean} overlapping
         */
        setOverlapping: function setOverlapping(overlapping) {
            this.setPrefs('overlapping', overlapping);
        },

        /**
         * Set statistics
         * @member BaseModel
         * @param {boolean} statistics
         */
        setStatistics: function setStatistics(statistics) {
            this.setPrefs('statistics', statistics);
        },

        /**
         * Check items limit
         * @member BaseModel
         * @param {Function} constructor
         * @param {Number} limit
         * @returns {boolean}
         */
        checkLimit: function checkLimit(constructor, limit) {
            var base = this.base,
                namespace = this.getNameSpace(constructor);

            limit = base.isDefined(limit) ?
                limit :
                this.getConfig(namespace).limit;

            if (!base.isDefined(limit)) {
                return false;
            }

            return base.lib.hash.hashLength(this.getItems()) >= limit;

        },

        /**
         * Update items collector
         * @member BaseModel
         * @param {function} Constructor
         * @param {{}} opts
         * @returns {*}
         */
        updateCollector: function updateCollector(Constructor, opts) {

            var namespace = this.getNameSpace(Constructor),
                scope = this.scope,
                cname = Constructor.name,
                node = scope[cname.toLowerCase()],
                base = this.base;

            this.setConfig(namespace, base.define(scope.config[namespace], {}, true));

            /**
             * Define limit
             * @type {number}
             */
            var limit = this.getConfig(namespace).limit;

            if (this.checkLimit(Constructor, limit)) {
                scope.logger.warn(
                        cname + ': Maximum limit reached',
                    limit
                );
                node.model.setConfig('limit', true);

            } else {

                /**
                 * Init node
                 * @type {Constructor}
                 */
                node = new Constructor(base.define(opts, {}, true));

                if (base.isDefined(node.model)) {

                    this.setItem(node);

                } else {

                    scope.logger.warn(
                            cname + ' was created with some errors',
                        node
                    );
                }

                /**
                 * Update counter
                 * @type {Number}
                 */
                scope.config[namespace].counter =
                    base.lib.hash.hashLength(this.getItems());

                /**
                 * Store item
                 * @type {*}
                 */
                scope[cname.toLowerCase()] = node;

                node.model.setConfig('limit', false);
            }

            return node;
        },

        /**
         * Return loaded data
         * @member BaseModel
         * @param data
         * @returns {*}
         * @private
         */
        _returnLoadData: function _returnLoadData(data) {
            this.scope.controller.setAsLoading(false);
            return data;
        },

        /**
         * Load data
         * @member BaseModel
         * @param [data]
         * @returns {*}
         */
        loadData: function loadData(data) {

            this.scope.controller.setAsLoading(true);

            /**
             * Set data
             */
            data = this.base.isDefined(data) ?
                data : this.setting.load();

            if (!data.hasOwnProperty('collector')) {
                return this._returnLoadData(false);
            }

            if (!this.base.isDefined(this.item)) {
                return this._returnLoadData(data.collector);
            }

            var cname = this.item.name,
                lname = cname.toLowerCase(),
                collector = this.base.define(data.collector, {}, true);

            if (collector.hasOwnProperty(lname)) {

                for (var index in collector[lname]) {

                    if (collector[lname].hasOwnProperty(index)) {

                        // Create item
                        this.scope.api['create' + cname](
                            this.base.define(collector[lname][index], {}, true),
                            true,
                            true
                        );
                    }
                }
            }

            this.loadData.bind(this.scope[lname].model)(data);

            return this._returnLoadData(data.collector);
        }

    }, AntHill.prototype, CRUD.prototype);

});<commit_msg>fix loading after add new page<commit_after>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 11/5/12
 * Time: 9:51 PM
 * To change this template use File | Settings | File Templates.
 */

define([
    'config/anthill',
    'modules/crud'
], function initModel(AntHill, CRUD) {

    /**
     * Define Base model
     * @class BaseModel
     * @extends CRUD
     * @extends AntHill
     * @constructor
     */
    var BaseModel = function BaseModel() {

    };

    return BaseModel.extend('BaseModel', {

        /**
         * Get scope config
         * @member BaseModel
         * @param {String} [key]
         * @returns {*}
         */
        getConfig: function getConfig(key) {
            var scope = this.scope,
                config = scope.config,
                reference = scope.config;

            if (typeof(key) === 'undefined') {
                return config;
            }

            /**
             * Split key by slash
             * @type {Array}
             */
            var path = key.split('/');

            for (var i = 0, l = path.length; i < l; i++) {

                /**
                 * Get config node
                 */
                var node = path[i];

                if (reference.hasOwnProperty(node)) {

                    scope.logger.debug('Get config by key', node);
                    reference = reference[node];

                } else {
                    scope.logger.warn('Undefined config key', node);
                    return false;
                }
            }

            scope.logger.debug('Get config', reference);

            return reference;
        },

        /**
         * Set scope config
         * @member BaseModel
         * @param {String} [key]
         * @param {*} [value]
         * @returns {scope.config}
         */
        setConfig: function setConfig(key, value) {
            var scope = this.scope,
                config = scope.config;
            if (config.hasOwnProperty(key)) {
                scope.logger.debug('Update config', key, value);
                config[key] = value;
            }
            scope.logger.debug('Set config new data', key, value);
            config[key] = value;
            return this.getConfig(key);
        },

        /**
         * Get scope namespace
         * @member BaseModel
         * @param {*} node
         * @returns {string}
         */
        getNameSpace: function getNameSpace(node) {
            var base = this.base,
                scope = base.isDefined(node) ?
                    node : this.scope,
                constructor = base.isFunction(scope) ?
                    scope : scope.constructor;

            return constructor.name.toLowerCase();
        },

        /**
         * Find item in a whole project
         * @member BaseModel
         * @param {*} root
         * @param {string} uuid
         * @return {*}
         */
        findItemByUUID: function findItemByUUID(root, uuid) {

            if (!root) {
                this.scope.logger.error('Undefined root', root);
            }

            // Get child node
            var child = root.model.getItemByUUID(uuid);

            if (child) {
                return child;
            }

            // Get all items
            var items = root.model.getItems();

            for (var index in items) {

                if (items.hasOwnProperty(index)) {

                    var item = items[index];

                    // Recursive search
                    var search = item.model.findItemByUUID(
                        item, uuid
                    );

                    if (search) {
                        return search;
                    }
                }
            }
        },

        /**
         * Get parent items
         * @member BaseModel
         * @returns {*}
         */
        getParentItems: function getParentItems() {
            return this.scope.controller.getContainment().items;
        },

        /**
         * Get items
         * @member BaseModel
         * @returns {*}
         */
        getItems: function getItems() {
            return this.scope.items;
        },

        /**
         * Get all items apart of item
         * @member BaseModel
         * @param {{model}} item
         * @returns {Array}
         */
        getItemsApartOf: function getItemsApartOf(item) {

            var items = this.getItems(),
                nodes = [], index, node, nodeUUID,
                uuid = item.model.getUUID();

            for (index in items) {

                if (items.hasOwnProperty(index)) {

                    node = items[index];
                    nodeUUID = node.model.getUUID();

                    if (uuid !== nodeUUID) {
                        nodes.push(node);
                    }
                }
            }
            return nodes;
        },

        /**
         * Get UUID
         * @member BaseModel
         * @param {{model}} [node]
         * @returns {String}
         */
        getUUID: function getUUID(node) {
            return this.base.isDefined(node) ?
                node.model ?
                    node.model.getUUID() :
                    'Undefined ' + node.constructor.name :
                this.getConfig('uuid');
        },

        /**
         * Get item from collector by UUID
         * @member BaseModel
         * @param {string} uuid
         * @returns {*}
         */
        getItemByUUID: function getItemByUUID(uuid) {
            var base = this.base,
                items = this.getItems(),
                item = base.lib.hash.isHashKey(items, uuid) ?
                    items[uuid] : undefined;

            if (!base.isDefined(item)) {
                this.scope.logger.debug('Undefined item');
            }
            return item;
        },

        /**
         * Reset collector
         * @member BaseModel
         * @returns {*}
         */
        resetItems: function resetItems() {
            this.scope.items = {};
            return this.getItems();
        },

        /**
         * Delete widget from collector
         * @member BaseModel
         * @param uuid
         * @returns {*}
         */
        deleteItem: function deleteItem(uuid) {
            delete this.scope.controller.getContainment().items[uuid];
            return this.getParentItems();
        },

        /**
         * Update collector
         * @member BaseModel
         * @param {string} uuid
         * @param hash
         * returns {*}
         */
        updateItem: function updateItem(uuid, hash) {
            var item = this.getItemByUUID(uuid);
            $.extend(true, item, hash);
            return item;
        },

        /**
         * Add item to collector
         * @member BaseModel
         * @param {{model}} node
         * @param {boolean} [force]
         * @returns {*}
         */
        setItem: function setItem(node, force) {
            var base = this.base;

            node = base.define(node, {}, true);
            force = base.defineBoolean(force, false, true);

            var uuid = node.model.getUUID(),
                item = base.isDefined(this.getItemByUUID(uuid));
            if (force || !item) {
                this.getItems()[uuid] = node;
            } else if (item) {
                this.scope.logger.warn('Item already in collector');
            }
            return this.getItemByUUID(uuid);
        },

        /**
         * Get Item constructor name
         * @member BaseModel
         * @returns {string}
         */
        getItemNameSpace: function getItemNameSpace() {
            this.scope.logger.debug('Get item namespace');
            if (this.hasOwnProperty('item')) {
                return this.item.name.toLowerCase();
            }

            this.scope.logger.debug('Undefined item');
        },

        /**
         * Get items order
         * @member BaseModel
         * @returns {*}
         */
        getOrder: function getOrder() {
            return this.getConfig('order');
        },

        /**
         * Get prefs
         * @member BaseModel
         * @param {string} prefs
         * @returns {boolean|string}
         */
        getContentPrefs: function getContentPrefs(prefs) {

            if (!this.preferences[prefs]) {
                this.scope.logger.warn('Undefined preference', prefs);
                return false;
            }

            return this.preferences[prefs].value;
        },

        /**
         * Get prefs
         * @member BaseModel
         * @param {string} prefs
         * @returns {*}
         */
        getPrefs: function getPrefs(prefs) {

            if (this.base.isDefined(this.preferences)) {
                return this.getContentPrefs(prefs);
            }

            /**
             * Define prefs
             * @type {{}}
             */
            var preferences = this.scope.config.preferences;

            if (!preferences) {
                this.scope.logger.warn('Unable to locate preference', prefs);
                return false;
            }

            return preferences[prefs];
        },

        /**
         * Set prefs
         * @member BaseModel
         * @param {string} prefs
         * @param {*} value
         */
        setPrefs: function setPrefs(prefs, value) {

            /**
             * Define new prefs
             * @type {*}
             */
            this.preferences[prefs] = this.base.define(
                this.preferences[prefs], {}, true
            );

            /**
             * Define prefs
             * @type {string}
             */
            this.preferences[prefs].value = value;
        },

        /**
         * Copy prefs
         * @member BaseModel
         * @param source
         * @returns {boolean}
         */
        copyPrefs: function copyPrefs(source) {

            /**
             * Define
             * @type {string}
             */
            var cname = this.scope.constructor.name.toLowerCase(),
                prefs = source.model.preferences;

            if (source.constructor.name.toLowerCase() !== cname) {
                this.scope.logger.warn('Unable to copy preferences', source);
                return false;
            }

            for (var index in prefs) {

                if (prefs.hasOwnProperty(index)) {

                    if (index.match(new RegExp(cname))) {

                        this.setPrefs(index, prefs[index].value);
                        this.scope.logger.debug(
                            'Copied prefs', source, index, prefs[index]
                        );
                    }
                }
            }
        },

        /**
         * Set rules on loading
         * @member BaseModel
         * @param rules
         */
        setRules: function setRules(rules) {

            /**
             * Local rules storage
             * @member BaseModel
             * @type {{}}
             */
            this.rules = rules;
        },

        /**
         * Set Title
         * @member BaseModel
         * @param {string} title
         */
        setTitle: function setTitle(title) {
            this.setPrefs('title', title);
        },

        /**
         * Set Description
         * @member BaseModel
         * @param {string} description
         */
        setDescription: function setDescription(description) {
            this.setPrefs('description', description);
        },

        /**
         * Set on click Url
         * @member BaseModel
         * @param {string} url
         */
        setOnClickOpenUrl: function setOnClickOpenUrl(url) {

            this.setPrefs('onClickOpenUrl', url);

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList.setOnClickUrl,
                url
            );
        },

        /**
         * Set on top
         * @member BaseModel
         * @param {boolean} ontop
         */
        setAlwaysOnTop: function setAlwaysOnTop(ontop) {

            this.setPrefs('alwaysOnTop', ontop);

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList.setAlwaysOnTop,
                ontop
            );
        },

        /**
         * Save widget layer
         * @member BaseModel
         */
        setLayerUp: function setLayerUp(eventName) {

            /**
             * Define scope
             * @type {Widget}
             */
            var scope = this.scope.controller.getContainment();

            scope.observer.publish(
                scope.eventmanager.eventList[eventName],
                true
            );
        },

        /**
         * Set overlapping
         * @member BaseModel
         * @param {boolean} overlapping
         */
        setOverlapping: function setOverlapping(overlapping) {
            this.setPrefs('overlapping', overlapping);
        },

        /**
         * Set statistics
         * @member BaseModel
         * @param {boolean} statistics
         */
        setStatistics: function setStatistics(statistics) {
            this.setPrefs('statistics', statistics);
        },

        /**
         * Check items limit
         * @member BaseModel
         * @param {Function} constructor
         * @param {Number} limit
         * @returns {boolean}
         */
        checkLimit: function checkLimit(constructor, limit) {
            var base = this.base,
                namespace = this.getNameSpace(constructor);

            limit = base.isDefined(limit) ?
                limit :
                this.getConfig(namespace).limit;

            if (!base.isDefined(limit)) {
                return false;
            }

            return base.lib.hash.hashLength(this.getItems()) >= limit;

        },

        /**
         * Update items collector
         * @member BaseModel
         * @param {function} Constructor
         * @param {{}} opts
         * @returns {*}
         */
        updateCollector: function updateCollector(Constructor, opts) {

            var namespace = this.getNameSpace(Constructor),
                scope = this.scope,
                cname = Constructor.name,
                node = scope[cname.toLowerCase()],
                base = this.base;

            this.setConfig(namespace, base.define(scope.config[namespace], {}, true));

            /**
             * Define limit
             * @type {number}
             */
            var limit = this.getConfig(namespace).limit;

            if (this.checkLimit(Constructor, limit)) {
                scope.logger.warn(
                        cname + ': Maximum limit reached',
                    limit
                );
                node.model.setConfig('limit', true);

            } else {

                /**
                 * Init node
                 * @type {Constructor}
                 */
                node = new Constructor(base.define(opts, {}, true));

                if (base.isDefined(node.model)) {

                    this.setItem(node);

                } else {

                    scope.logger.warn(
                            cname + ' was created with some errors',
                        node
                    );
                }

                /**
                 * Update counter
                 * @type {Number}
                 */
                scope.config[namespace].counter =
                    base.lib.hash.hashLength(this.getItems());

                /**
                 * Store item
                 * @type {*}
                 */
                scope[cname.toLowerCase()] = node;

                node.model.setConfig('limit', false);
            }

            return node;
        },

        /**
         * Return loaded data
         * @member BaseModel
         * @param data
         * @returns {*}
         * @private
         */
        _returnLoadData: function _returnLoadData(data) {
            this.scope.controller.setAsLoading(false);
            return data;
        },

        /**
         * Load data
         * @member BaseModel
         * @param [data]
         * @returns {*}
         */
        loadData: function loadData(data) {

            this.scope.controller.setAsLoading(true);

            /**
             * Set data
             */
            data = this.base.isDefined(data) ?
                data : this.setting.load();

            if (!data.hasOwnProperty('collector')) {
                return this._returnLoadData(false);
            }

            if (!this.base.isDefined(this.item)) {
                return this._returnLoadData(data.collector);
            }

            var cname = this.item.name,
                lname = cname.toLowerCase(),
                collector = this.base.define(data.collector, {}, true);

            if (collector.hasOwnProperty(lname)) {

                for (var index in collector[lname]) {

                    if (collector[lname].hasOwnProperty(index)) {

                        // Create item
                        this.scope.api['create' + cname](
                            this.base.define(collector[lname][index], {}, true),
                            true,
                            true
                        );
                    }
                }
            }

            if (this.scope[lname].model) {

                this.loadData.bind(this.scope[lname].model)(data);
            }

            return this._returnLoadData(data.collector);
        }

    }, AntHill.prototype, CRUD.prototype);

});<|endoftext|>