<commit_before>/* exported Tendou */
/* jshint latedef: false */
var Tendou = (function(lightdm) {
  'use strict';

  /*
   *
   * Private properties
   *
   */

  var el_form_login_form = null, // Login form
      el_input_user        = null, // User input field
      el_input_pass        = null, // Password input field
      el_list_user_list    = null, // List of users
      el_text_message      = null, // Messages to display to the user
      el_heading_full_name = null, // Heading for the current user's full name
      el_figure_profile    = null, // Container for the current user's picture
      el_img_profile       = null, // Container for the current user's picture
      el_button_shutdown   = null, // Shutdown button
      el_button_restart    = null, // Restart button
      el_button_sleep      = null, // Sleep button
      current_user_index   = 0,    // Index of the currently selected user
      keypress_handlers    = {},   // Registered keypress callbacks
      default_avatar       = 'images/default-avatar.png',

  /*
   *
   * Private methods
   *
   */

  Private = {
    /**
     * Initializes methods that are used with LightDM.
     */
    init_lightdm_handlers: function() {
      /**
       * Begins authenticating the given user.
       *
       * @param The username of the user to start authenticating.
       */
      window.start_authentication = function(username) {
        lightdm.cancel_timed_login(); // Cancel any previous login attempt
        lightdm.start_authentication(username);
      };

      /**
       * Provide the user-entered password to LightDM.
       */
      window.provide_secret = function() {
        // Pass the user-entered password to LightDM
        lightdm.provide_secret(el_input_pass.value);
      };

      /**
       * Called when authentication of the user is complete.
       */
      window.authentication_complete = function() {
        if (lightdm.is_authenticated) {
          // Log in if the user was successfully authenticated
          lightdm.login(
            lightdm.authentication_user,
            lightdm.default_session
          );
        } else {
          // Show an error message if authentication was not successful
          show_error('Your password was incorrect');

          // Reset the password field and remove the wait indicator
          el_input_pass.value = '';
          el_input_pass.focus();
          hide_wait_indicator();

          // Restart authentication for the current user
          lightdm.start_authentication(lightdm.users[current_user_index]);
        }
      };

      /**
       * Called for LightDM to display errors.
       */
      window.show_error = function() { /* do nothing */ };

      /**
       * Called for LightDM to display the login prompt.
       */
      window.show_prompt = function() { /* do nothing */ };
    },

    /**
     * Register keypress handlers.
     */
    init_keypress_handler: function() {
      window.onkeydown = Private.keypress_event_translator;

      // Up arrow selects previous user, down arrow selects next user
      Public.register_keypress_handler(38, Public.select_previous_user);
      Public.register_keypress_handler(40, Public.select_next_user);
    },

    /**
     * Calls `keypress_handler` with the information from a KeyboardEvent.
     * `preventDefault` will be called on the event if it is handled.
     *
     * @param event e The KeyboardEvent to forward to `keypress_handler`.
     */
    keypress_event_translator: function(e) {
      var key = (e.key ? e.key : e.keyCode);

      if (Private.keypress_handler(key)) {
        e.preventDefault();
      }
    },

    /**
     * Calls all callbacks registered to a specific keybinding.
     * The return value should be used to determine whether to call
     * preventDefault() on the KeyboardEvent object.
     *
     * @param int key_code The code of the key pressed.
     * @return bool True if the key was handled, false otherwise.
     */
    keypress_handler: function(key_code) {
      var was_handled = false;

      if (keypress_handlers[key_code] !== undefined) {
        keypress_handlers[key_code].forEach(function(callback) {
          was_handled = true;
          callback();
        });
      }

      return was_handled;
    },

    /**
     * Returns the index of the current user.
     *
     * @return int The index of the current user in the LightDM user array.
     */
    get_current_user_index: function() {
      return current_user_index;
    },

    /**
     * Returns the index of the previous user.
     *
     * @return int The index of the previous user in the LightDM user array.
     */
    get_previous_user_index: function() {
      var previous_index = ((current_user_index - 1)+lightdm.num_users);
      return previous_index % lightdm.num_users;
    },

    /**
     * Returns the index of the next user.
     *
     * @return int The index of the next user in the LightDM user array.
     */
    get_next_user_index: function() {
      return ((current_user_index + 1) % lightdm.num_users);
    },

    /**
     * Sets the current user to the user with the given id.
     *
     * @param int user_index Index of the user in the LightDM user array.
     */
    set_current_user_index: function(user_index) {
      var current_user_name = lightdm.users[user_index].name;

      // Update the index of the current user globally
      current_user_index = user_index;

      // Cancel authentication for a previous authentication attempt
      if (lightdm._username) {
        lightdm.cancel_authentication();
      }

      // Start authentication for the new user
      if (current_user_name !== null) {
        window.start_authentication(current_user_name);
      }
    },
  },

  /*
   *
   * Public members
   *
   */

  Public = {
    /**
     * Initializes the functionality for this theme.
     */
    init: function() {
      Private.init_lightdm_handlers();
      Private.init_keypress_handler();

      // DOM initializers
      init_dom_elements();
      init_dom_users_list();
      init_dom_listeners();
    },

    /**
     * Selects the previous LightDM user.
     */
    select_previous_user: function() {
      Private.set_current_user_index(Private.get_previous_user_index());
      indicate_current_user_on_screen();
    },

    /**
     * Selects the next LightDM user.
     */
    select_next_user: function() {
      Private.set_current_user_index(Private.get_next_user_index());
      indicate_current_user_on_screen();
    },

    /**
     * Returns the full name for the user with the given id, if available.
     * If a full name is not available, their real name will be used.
     * If there is no real name, their username will be used.
     *
     * @param int user_index Index of the user in the LightDM user array.
     * @return string The full name for the user.
     */
    get_full_name_from_index: function(user_index) {
      var user = lightdm.users[user_index];
      var name;

      if (user.display_name) {
        name = user.display_name;
      } else if (user.real_name) {
        name = user.real_name;
      } else {
        name = user.name;
      }

      return name;
    },

    /**
     * Returns the path of the picture for the user with the given id.
     *
     * @param int user_index Index of the user in the LightDM user array.
     */
    get_picture_from_index: function(user_index) {
      var picture;

      if (lightdm.users[user_index].image) {
        picture = lightdm.users[user_index].image;
      } else {
        picture = default_avatar;
      }

      return picture;
    },

    /**
     * Registers a callback for when a specific key is pressed.
     *
     * @param int key The keycode of the key to listen for.
     * @param function callback The function to call when the key is pressed.
     */
    register_keypress_handler: function(key, callback) {
      if (keypress_handlers[key] === undefined) {
        keypress_handlers[key] = [];
      }

      keypress_handlers[key].push(callback);
    },

    /**
     * Expose private methods for the purpose of testing.
     */
    __test_framework__: Private,
  };

  /*
   *
   * Private methods
   *
   */

  function init_dom_elements() {
    el_form_login_form   = document.getElementById('login-form');
    el_input_user        = document.getElementById('user');
    el_input_pass        = document.getElementById('password');
    el_list_user_list    = document.getElementById('user-list');
    el_text_message      = document.getElementById('message');
    el_heading_full_name = document.getElementById('login-name');
    el_figure_profile    = document.getElementById('profile-image');
    el_img_profile       = el_figure_profile.querySelector('img');
    el_button_shutdown   = document.getElementById('shutdown');
    el_button_restart    = document.getElementById('reboot');
    el_button_sleep      = document.getElementById('sleep');
  }

  /**
   * Registeres event listeners on DOM elements.
   */
  function init_dom_listeners() {
    /* Update the current user when a user list entry is clicked */
    el_list_user_list.addEventListener('click', function(e) {
      var user_index = parseInt(e.target.id.replace('user-', ''), 10);

      Private.set_current_user_index(user_index);
      indicate_current_user_on_screen();
    });

    /* Updates the user list when the currently selected user changes. */
    el_input_user.addEventListener('change', function(e) {
      e.preventDefault();
      indicate_current_user_on_screen(e.currentTarget.selectedIndex);
    });

    /* Authenticates with LightDM when the login form is submitted. */
    el_form_login_form.addEventListener('submit', function(e) {
      e.preventDefault();

      // Clear all messages and display the waiting indicator
      clear_message();
      show_wait_indicator();

      window.provide_secret();
    });

    /* Tell LightDM to shut down when the shutdown button is clicked. */
    el_button_shutdown.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('Goodbye');
      lightdm.shutdown();
    });

    /* Tell LightDM to reboot when the reboot button is clicked. */
    el_button_restart.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('See you soon');
      lightdm.restart();
    });

    /* Tell LightDM to sleep when the sleep button is clicked. */
    el_button_sleep.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('Goodnight');
      lightdm.suspend();
    });
  }

  /**
   * Populates the user list with all users registered under LightDM.
   */
  function init_dom_users_list() {
    var user_index;
    var fullname;

    if (lightdm.num_users > 1) {
      for (user_index = 0; user_index < lightdm.num_users; user_index++) {
        if (lightdm.users.hasOwnProperty(user_index)) {
          fullname = Public.get_full_name_from_index(user_index);

          el_list_user_list.insertAdjacentHTML(
            'beforeend',
            '
'+fullname+'
'
          );
        }
      }

      // Select the first user in the list
      Private.set_current_user_index(0);
      indicate_current_user_on_screen();
    }
  }

  /**
   * Displays the given general message to the user.
   *
   * @param string text The message to display.
   */
  function show_message(text) {
    el_text_message.innerHTML= text;
    el_text_message.classList.remove('cleared');
    el_text_message.classList.remove('error');
  }

  /**
   * Displays the given error message to the user.
   *
   * @param string text The error message to display.
   */
  function show_error(text) {
    show_message(text);
    el_text_message.classList.add('error');
  }

  /**
   * Clears all messages displayed to the user.
   */
  function clear_message() {
    show_message('');
    el_text_message.classList.add('cleared');
  }

  /**
   * Displays the wait indicator to the user.
   */
  function show_wait_indicator() {
    el_text_message.insertAdjacentHTML(
      'afterend',
      '

'
    );
  }

  /**
   * Removes the wait indicator.
   */
  function hide_wait_indicator() {
    var spinners = document.getElementsByClassName('spinner');

    while (spinners[0]) {
      spinners[0].parentNode.removeChild(spinners[0]);
    }
  }

  /**
   * Updates the current user picture for the user with the given id.
   *
   * @param int user_index Index of the user in the LightDM user array.
   */
  function update_user_picture(user_index) {
    // Disable animation on the image
    el_figure_profile.style.webkitAnimationName = 'none';
    el_figure_profile.style.animationName = 'none';

    // Change the displayed image
    el_img_profile.src = Public.get_picture_from_index(user_index);

    // Reapply the animation
    setTimeout(function() {
      el_figure_profile.style.webkitAnimationDelay = 0;
      el_figure_profile.style.webkitAnimationName  = 'avatar_in';
      el_figure_profile.style.animationDelay = 0;
      el_figure_profile.style.animationName  = 'avatar_in';
    }, 1);
  }

  /**
   * Updates the currently displayed full name for the user with the given id.
   *
   * @param int user_index Index of the user in the LightDM user array.
   */
  function update_user_full_name(user_index) {
    var full_name = Public.get_full_name_from_index(user_index);
    el_heading_full_name.innerHTML = full_name;
  }

  /**
   * Indicates the currently selected user in the DOM.
   */
  function indicate_current_user_on_screen() {
    var index = current_user_index;
    var el_li_user_entry = document.getElementById('user-'+index);

    // Set this user as the user to log in
    el_input_user.value = lightdm.users[current_user_index].name;

    // Update the display
    update_user_picture(current_user_index);
    update_user_full_name(current_user_index);

    // Deselect all other users
    Array.prototype.forEach.call(
      el_list_user_list.getElementsByClassName('selected'),
      function(e) { e.className = ''; }
    );

    // Mark this user as selected if they have a list entry
    if (el_li_user_entry) {
      el_li_user_entry.className = 'selected';
    }

    // Clear all messages and the wait indicator
    clear_message();
    hide_wait_indicator();
  }

  // Expose the public interface
  return Public;
} (lightdm));
<commit_msg>Minor formatting and bugfix<commit_after>/* exported Tendou */
/* jshint latedef: false */
var Tendou = (function(lightdm) {
  'use strict';

  /*
   *
   * Private properties
   *
   */

  var el_form_login_form   = null, // Login form
      el_input_user        = null, // User input field
      el_input_pass        = null, // Password input field
      el_list_user_list    = null, // List of users
      el_text_message      = null, // Messages to display to the user
      el_heading_full_name = null, // Heading for the current user's full name
      el_figure_profile    = null, // Container for the current user's picture
      el_img_profile       = null, // Container for the current user's picture
      el_button_shutdown   = null, // Shutdown button
      el_button_restart    = null, // Restart button
      el_button_sleep      = null, // Sleep button
      current_user_index   = 0,    // Index of the currently selected user
      keypress_handlers    = {},   // Registered keypress callbacks
      default_avatar       = 'images/default-avatar.png',

  /*
   *
   * Private methods
   *
   */

  Private = {
    /**
     * Initializes methods that are used with LightDM.
     */
    init_lightdm_handlers: function() {
      /**
       * Begins authenticating the given user.
       *
       * @param The username of the user to start authenticating.
       */
      window.start_authentication = function(username) {
        lightdm.cancel_timed_login(); // Cancel any previous login attempt
        lightdm.start_authentication(username);
      };

      /**
       * Provide the user-entered password to LightDM.
       */
      window.provide_secret = function() {
        // Pass the user-entered password to LightDM
        lightdm.provide_secret(el_input_pass.value);
      };

      /**
       * Called when authentication of the user is complete.
       */
      window.authentication_complete = function() {
        if (lightdm.is_authenticated) {
          // Log in if the user was successfully authenticated
          lightdm.login(
            lightdm.authentication_user,
            lightdm.default_session
          );
        } else {
          // Show an error message if authentication was not successful
          show_error('Your password was incorrect');

          // Reset the password field and remove the wait indicator
          el_input_pass.value = '';
          el_input_pass.focus();
          hide_wait_indicator();

          // Restart authentication for the current user
          lightdm.start_authentication(lightdm.users[current_user_index]);
        }
      };

      /**
       * Called for LightDM to display errors.
       */
      window.show_error = function() { /* do nothing */ };

      /**
       * Called for LightDM to display the login prompt.
       */
      window.show_prompt = function() { /* do nothing */ };
    },

    /**
     * Register keypress handlers.
     */
    init_keypress_handler: function() {
      window.onkeydown = Private.keypress_event_translator;

      // Up arrow selects previous user, down arrow selects next user
      Public.register_keypress_handler(38, Public.select_previous_user);
      Public.register_keypress_handler(40, Public.select_next_user);
    },

    /**
     * Calls `keypress_handler` with the information from a KeyboardEvent.
     * `preventDefault` will be called on the event if it is handled.
     *
     * @param event e The KeyboardEvent to forward to `keypress_handler`.
     */
    keypress_event_translator: function(e) {
      var key = (e.key ? e.key : e.keyCode);

      if (Private.keypress_handler(key)) {
        e.preventDefault();
      }
    },

    /**
     * Calls all callbacks registered to a specific keybinding.
     * The return value should be used to determine whether to call
     * preventDefault() on the KeyboardEvent object.
     *
     * @param int key_code The code of the key pressed.
     * @return bool True if the key was handled, false otherwise.
     */
    keypress_handler: function(key_code) {
      var was_handled = false;

      if (keypress_handlers[key_code] !== undefined) {
        keypress_handlers[key_code].forEach(function(callback) {
          was_handled = true;
          callback();
        });
      }

      return was_handled;
    },

    /**
     * Returns the index of the current user.
     *
     * @return int The index of the current user in the LightDM user array.
     */
    get_current_user_index: function() {
      return current_user_index;
    },

    /**
     * Returns the index of the previous user.
     *
     * @return int The index of the previous user in the LightDM user array.
     */
    get_previous_user_index: function() {
      var previous_index = ((current_user_index - 1)+lightdm.num_users);
      return previous_index % lightdm.num_users;
    },

    /**
     * Returns the index of the next user.
     *
     * @return int The index of the next user in the LightDM user array.
     */
    get_next_user_index: function() {
      return ((current_user_index + 1) % lightdm.num_users);
    },

    /**
     * Sets the current user to the user with the given id.
     *
     * @param int user_index Index of the user in the LightDM user array.
     */
    set_current_user_index: function(user_index) {
      var current_user_name = lightdm.users[user_index].name;

      // Update the index of the current user globally
      current_user_index = user_index;

      // Cancel authentication for a previous authentication attempt
      if (lightdm._username) {
        lightdm.cancel_authentication();
      }

      // Start authentication for the new user
      if (current_user_name !== null) {
        window.start_authentication(current_user_name);
      }
    },
  },

  /*
   *
   * Public members
   *
   */

  Public = {
    /**
     * Initializes the functionality for this theme.
     */
    init: function() {
      Private.init_lightdm_handlers();
      Private.init_keypress_handler();

      // DOM initializers
      init_dom_elements();
      init_dom_users_list();
      init_dom_listeners();
    },

    /**
     * Selects the previous LightDM user.
     */
    select_previous_user: function() {
      Private.set_current_user_index(Private.get_previous_user_index());
      indicate_current_user_on_screen();
    },

    /**
     * Selects the next LightDM user.
     */
    select_next_user: function() {
      Private.set_current_user_index(Private.get_next_user_index());
      indicate_current_user_on_screen();
    },

    /**
     * Returns the full name for the user with the given id, if available.
     * If a full name is not available, their real name will be used.
     * If there is no real name, their username will be used.
     *
     * @param int user_index Index of the user in the LightDM user array.
     * @return string The full name for the user.
     */
    get_full_name_from_index: function(user_index) {
      var user = lightdm.users[user_index];
      var name;

      if (user.display_name) {
        name = user.display_name;
      } else if (user.real_name) {
        name = user.real_name;
      } else {
        name = user.name;
      }

      return name;
    },

    /**
     * Returns the path of the picture for the user with the given id.
     *
     * @param int user_index Index of the user in the LightDM user array.
     */
    get_picture_from_index: function(user_index) {
      var picture;

      if (lightdm.users[user_index].image) {
        picture = lightdm.users[user_index].image;
      } else {
        picture = default_avatar;
      }

      return picture;
    },

    /**
     * Registers a callback for when a specific key is pressed.
     *
     * @param int key The keycode of the key to listen for.
     * @param function callback The function to call when the key is pressed.
     */
    register_keypress_handler: function(key, callback) {
      if (keypress_handlers[key] === undefined) {
        keypress_handlers[key] = [];
      }

      keypress_handlers[key].push(callback);
    },

    /**
     * Expose private methods for the purpose of testing.
     */
    __test_framework__: Private,
  };

  /*
   *
   * Private methods
   *
   */

  function init_dom_elements() {
    el_form_login_form   = document.getElementById('login-form');
    el_input_user        = document.getElementById('user');
    el_input_pass        = document.getElementById('password');
    el_list_user_list    = document.getElementById('user-list');
    el_text_message      = document.getElementById('message');
    el_heading_full_name = document.getElementById('login-name');
    el_figure_profile    = document.getElementById('profile-image');
    el_img_profile       = el_figure_profile.querySelector('img');
    el_button_shutdown   = document.getElementById('shutdown');
    el_button_restart    = document.getElementById('reboot');
    el_button_sleep      = document.getElementById('sleep');
  }

  /**
   * Registeres event listeners on DOM elements.
   */
  function init_dom_listeners() {
    /* Update the current user when a user list entry is clicked */
    el_list_user_list.addEventListener('click', function(e) {
      var user_index = parseInt(e.target.id.replace('user-', ''), 10);

      Private.set_current_user_index(user_index);
      indicate_current_user_on_screen();
    });

    /* Updates the user list when the currently selected user changes. */
    el_input_user.addEventListener('change', function(e) {
      e.preventDefault();
      Private.set_current_user_index(e.currentTarget.selectedIndex);
      indicate_current_user_on_screen();
    });

    /* Authenticates with LightDM when the login form is submitted. */
    el_form_login_form.addEventListener('submit', function(e) {
      e.preventDefault();

      // Clear all messages and display the waiting indicator
      clear_message();
      show_wait_indicator();

      window.provide_secret();
    });

    /* Tell LightDM to shut down when the shutdown button is clicked. */
    el_button_shutdown.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('Goodbye');
      lightdm.shutdown();
    });

    /* Tell LightDM to reboot when the reboot button is clicked. */
    el_button_restart.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('See you soon');
      lightdm.restart();
    });

    /* Tell LightDM to sleep when the sleep button is clicked. */
    el_button_sleep.addEventListener('click', function(e) {
      e.preventDefault();
      show_message('Goodnight');
      lightdm.suspend();
    });
  }

  /**
   * Populates the user list with all users registered under LightDM.
   */
  function init_dom_users_list() {
    var user_index;
    var fullname;

    if (lightdm.num_users > 1) {
      for (user_index = 0; user_index < lightdm.num_users; user_index++) {
        if (lightdm.users.hasOwnProperty(user_index)) {
          fullname = Public.get_full_name_from_index(user_index);

          el_list_user_list.insertAdjacentHTML(
            'beforeend',
            '
'+fullname+'
'
          );
        }
      }

      // Select the first user in the list
      Private.set_current_user_index(0);
      indicate_current_user_on_screen();
    }
  }

  /**
   * Displays the given general message to the user.
   *
   * @param string text The message to display.
   */
  function show_message(text) {
    el_text_message.innerHTML= text;
    el_text_message.classList.remove('cleared');
    el_text_message.classList.remove('error');
  }

  /**
   * Displays the given error message to the user.
   *
   * @param string text The error message to display.
   */
  function show_error(text) {
    show_message(text);
    el_text_message.classList.add('error');
  }

  /**
   * Clears all messages displayed to the user.
   */
  function clear_message() {
    show_message('');
    el_text_message.classList.add('cleared');
  }

  /**
   * Displays the wait indicator to the user.
   */
  function show_wait_indicator() {
    el_text_message.insertAdjacentHTML(
      'afterend',
      '

'
    );
  }

  /**
   * Removes the wait indicator.
   */
  function hide_wait_indicator() {
    var spinners = document.getElementsByClassName('spinner');

    while (spinners[0]) {
      spinners[0].parentNode.removeChild(spinners[0]);
    }
  }

  /**
   * Updates the current user picture for the user with the given id.
   *
   * @param int user_index Index of the user in the LightDM user array.
   */
  function update_user_picture(user_index) {
    // Disable animation on the image
    el_figure_profile.style.webkitAnimationName = 'none';
    el_figure_profile.style.animationName = 'none';

    // Change the displayed image
    el_img_profile.src = Public.get_picture_from_index(user_index);

    // Reapply the animation
    setTimeout(function() {
      el_figure_profile.style.webkitAnimationDelay = 0;
      el_figure_profile.style.webkitAnimationName  = 'avatar_in';
      el_figure_profile.style.animationDelay = 0;
      el_figure_profile.style.animationName  = 'avatar_in';
    }, 1);
  }

  /**
   * Updates the currently displayed full name for the user with the given id.
   *
   * @param int user_index Index of the user in the LightDM user array.
   */
  function update_user_full_name(user_index) {
    var full_name = Public.get_full_name_from_index(user_index);
    el_heading_full_name.innerHTML = full_name;
  }

  /**
   * Indicates the currently selected user in the DOM.
   */
  function indicate_current_user_on_screen() {
    var index = current_user_index;
    var el_li_user_entry = document.getElementById('user-'+index);

    // Set this user as the user to log in
    el_input_user.value = lightdm.users[current_user_index].name;

    // Update the display
    update_user_picture(current_user_index);
    update_user_full_name(current_user_index);

    // Deselect all other users
    Array.prototype.forEach.call(
      el_list_user_list.getElementsByClassName('selected'),
      function(e) { e.className = ''; }
    );

    // Mark this user as selected if they have a list entry
    if (el_li_user_entry) {
      el_li_user_entry.className = 'selected';
    }

    // Clear all messages and the wait indicator
    clear_message();
    hide_wait_indicator();
  }

  // Expose the public interface
  return Public;
} (lightdm));
<|endoftext|>


<commit_before>//! moment.js locale configuration
//! locale : Marathi (mr)
//! author : Harshad Kale : https://github.com/kalehv
//! author : Vivek Athalye : https://github.com/vnathalye

(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :
   typeof define === 'function' && define.amd ? define(['moment'], factory) :
   factory(global.moment)
}(this, function (moment) { 'use strict';

    var symbolMap = {
        '1': '१',
        '2': '२',
        '3': '३',
        '4': '४',
        '5': '५',
        '6': '६',
        '7': '७',
        '8': '८',
        '9': '९',
        '0': '०'
    },
    numberMap = {
        '१': '1',
        '२': '2',
        '३': '3',
        '४': '4',
        '५': '5',
        '६': '6',
        '७': '7',
        '८': '8',
        '९': '9',
        '०': '0'
    };

    function mr_relativeTime(number, withoutSuffix, string, isFuture)
    {
        var output = "";
        if (withoutSuffix) {
            switch(string) {
                case "s": output = 'काही सेकंद'; break;
                case "m": output = 'एक मिनिट'; break;
                case "mm": output = '%d मिनिटे'; break;
                case "h": output = 'एक तास'; break;
                case "hh": output = '%d तास'; break;
                case "d": output = 'एक दिवस'; break;
                case "dd": output = '%d दिवस'; break;
                case "M": output = 'एक महिना'; break;
                case "MM": output = '%d महिने'; break;
                case "y": output = 'एक वर्ष'; break;
                case "yy": output = '%d वर्षे'; break;
            }
        }
        else {
            switch (string) {
                case "s": output = 'काही सेकंदां'; break;
                case "m": output = 'एका मिनिटा'; break;
                case "mm": output = '%d मिनिटां'; break;
                case "h": output = 'एका तासा'; break;
                case "hh": output = '%d तासां'; break;
                case "d": output = 'एका दिवसा'; break;
                case "dd": output = '%d दिवसां'; break;
                case "M": output = 'एका महिन्या'; break;
                case "MM": output = '%d महिन्यां'; break;
                case "y": output = 'एका वर्षा'; break;
                case "yy": output = '%d वर्षां'; break;
            }
        }
        return output.replace(/%d/i, number);
    }

    var mr = moment.defineLocale('mr', {
        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
        longDateFormat : {
            LT : 'A h:mm वाजता',
            LTS : 'A h:mm:ss वाजता',
            L : 'DD/MM/YYYY',
            LL : 'D MMMM YYYY',
            LLL : 'D MMMM YYYY, A h:mm वाजता',
            LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
        },
        calendar : {
            sameDay : '[आज] LT',
            nextDay : '[उद्या] LT',
            nextWeek : 'dddd, LT',
            lastDay : '[काल] LT',
            lastWeek: '[मागील] dddd, LT',
            sameElse : 'L'
        },
        relativeTime: {
            future: '%sमध्ये',
            past: '%sपूर्वी',
            s: mr_relativeTime,
            m: mr_relativeTime,
            mm: mr_relativeTime,
            h: mr_relativeTime,
            hh: mr_relativeTime,
            d: mr_relativeTime,
            dd: mr_relativeTime,
            M: mr_relativeTime,
            MM: mr_relativeTime,
            y: mr_relativeTime,
            yy: mr_relativeTime
        },
        preparse: function (string) {
            return string.replace(/[१२३४५६७८९०]/g, function (match) {
                return numberMap[match];
            });
        },
        postformat: function (string) {
            return string.replace(/\d/g, function (match) {
                return symbolMap[match];
            });
        },
        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
        meridiemHour : function (hour, meridiem) {
            if (hour === 12) {
                hour = 0;
            }
            if (meridiem === 'रात्री') {
                return hour < 4 ? hour : hour + 12;
            } else if (meridiem === 'सकाळी') {
                return hour;
            } else if (meridiem === 'दुपारी') {
                return hour >= 10 ? hour : hour + 12;
            } else if (meridiem === 'सायंकाळी') {
                return hour + 12;
            }
        },
        meridiem: function (hour, minute, isLower) {
            if (hour < 4) {
                return 'रात्री';
            } else if (hour < 10) {
                return 'सकाळी';
            } else if (hour < 17) {
                return 'दुपारी';
            } else if (hour < 20) {
                return 'सायंकाळी';
            } else {
                return 'रात्री';
            }
        },
        week : {
            dow : 0, // Sunday is the first day of the week.
            doy : 6  // The week that contains Jan 1st is the first week of the year.
        }
    });

    return mr;

}));<commit_msg>Revert "Changed relativeTime"<commit_after>//! moment.js locale configuration
//! locale : Marathi (mr)
//! author : Harshad Kale : https://github.com/kalehv

(function (global, factory) {
   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :
   typeof define === 'function' && define.amd ? define(['moment'], factory) :
   factory(global.moment)
}(this, function (moment) { 'use strict';

    var symbolMap = {
        '1': '१',
        '2': '२',
        '3': '३',
        '4': '४',
        '5': '५',
        '6': '६',
        '7': '७',
        '8': '८',
        '9': '९',
        '0': '०'
    },
    numberMap = {
        '१': '1',
        '२': '2',
        '३': '3',
        '४': '4',
        '५': '5',
        '६': '6',
        '७': '7',
        '८': '8',
        '९': '9',
        '०': '0'
    };

    var mr = moment.defineLocale('mr', {
        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),
        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),
        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),
        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),
        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),
        longDateFormat : {
            LT : 'A h:mm वाजता',
            LTS : 'A h:mm:ss वाजता',
            L : 'DD/MM/YYYY',
            LL : 'D MMMM YYYY',
            LLL : 'D MMMM YYYY, A h:mm वाजता',
            LLLL : 'dddd, D MMMM YYYY, A h:mm वाजता'
        },
        calendar : {
            sameDay : '[आज] LT',
            nextDay : '[उद्या] LT',
            nextWeek : 'dddd, LT',
            lastDay : '[काल] LT',
            lastWeek: '[मागील] dddd, LT',
            sameElse : 'L'
        },
        relativeTime : {
            future : '%s नंतर',
            past : '%s पूर्वी',
            s : 'सेकंद',
            m: 'एक मिनिट',
            mm: '%d मिनिटे',
            h : 'एक तास',
            hh : '%d तास',
            d : 'एक दिवस',
            dd : '%d दिवस',
            M : 'एक महिना',
            MM : '%d महिने',
            y : 'एक वर्ष',
            yy : '%d वर्षे'
        },
        preparse: function (string) {
            return string.replace(/[१२३४५६७८९०]/g, function (match) {
                return numberMap[match];
            });
        },
        postformat: function (string) {
            return string.replace(/\d/g, function (match) {
                return symbolMap[match];
            });
        },
        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,
        meridiemHour : function (hour, meridiem) {
            if (hour === 12) {
                hour = 0;
            }
            if (meridiem === 'रात्री') {
                return hour < 4 ? hour : hour + 12;
            } else if (meridiem === 'सकाळी') {
                return hour;
            } else if (meridiem === 'दुपारी') {
                return hour >= 10 ? hour : hour + 12;
            } else if (meridiem === 'सायंकाळी') {
                return hour + 12;
            }
        },
        meridiem: function (hour, minute, isLower) {
            if (hour < 4) {
                return 'रात्री';
            } else if (hour < 10) {
                return 'सकाळी';
            } else if (hour < 17) {
                return 'दुपारी';
            } else if (hour < 20) {
                return 'सायंकाळी';
            } else {
                return 'रात्री';
            }
        },
        week : {
            dow : 0, // Sunday is the first day of the week.
            doy : 6  // The week that contains Jan 1st is the first week of the year.
        }
    });

    return mr;

}));<|endoftext|>


<commit_before>/**
 * Primary Controller for the Vocabulary CMS
 * For adding / editing vocabulary metadata
 * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
 */
(function () {
    'use strict';

    angular
        .module('app')
        .controller('addVocabsCtrl', addVocabsCtrl);

    function addVocabsCtrl($log, $scope, $location, $modal, vocabs_factory) {
        vocabs_factory.user().then(function (data) {
            $scope.user_orgs = data.message;
        });
        $scope.form = {};

        $scope.vocab = {top_concept: [], subjects: []};
        $scope.mode = 'add'; // [add|edit]
        $scope.langs = [
            {"value": "zh", "text": "Chinese"},
            {"value": "en", "text": "English"},
            {"value": "fr", "text": "French"},
            {"value": "de", "text": "German"},
            {"value": "it", "text": "Italian"},
            {"value": "ja", "text": "Japanese"},
            {"value": "mi", "text": "Māori"},
            {"value": "ru", "text": "Russian"},
            {"value": "es", "text": "Spanish"}
        ];
        $scope.licence = ["CC-BY", "CC-BY-SA", "CC-BY-ND", "CC-BY-NC", "CC-BY-NC-SA", "CC-BY-NC-ND", "GPL", "AusGoalRestrictive", "NoLicence", "Unknown/Other"];
        $scope.subject_sources = ['ANZSRC-FOR', 'local'];

        $scope.opened = false;
        $scope.decide = false;

        $scope.status = 'idle';

        $scope.open = function ($event) {
            $event.preventDefault();
            $event.stopPropagation();
            $scope.opened = !$scope.opened;
        };

        /**
         * If there is a slug available, this is an edit view for the CMS
         * Proceed to overwrite the vocab object with the one fetched from the vocabs_factory.get()
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */
        if ($('#vocab_slug').val()) {
            vocabs_factory.get($('#vocab_id').val()).then(function (data) {
                $log.debug('Editing ', data.message);
                $scope.vocab = data.message;
                $scope.mode = 'edit';
                $scope.decide = true;
                $log.debug($scope.form.cms);
            });
        }

        if ($location.search().skip) {
            $scope.decide = true;
        }

        /**
         * Collect All PoolParty Project
         */
        $scope.projects = [];
        $scope.ppid = {};
        vocabs_factory.toolkit('listPoolPartyProjects').then(function (data) {
            $scope.projects = data;
        });

        /**
         * Collect all the user roles, for vocab.owner value
         */
        vocabs_factory.user().then(function (data) {
            $scope.user_orgs = data.message['affiliations'];
            $scope.vocab.user_owner = data.message['role_id'];
        });

        $scope.projectSearch = function (q) {
            return function (item) {
                if (item.title.toLowerCase().indexOf(q.toLowerCase()) > -1 || item['id'].toLowerCase().indexOf(q.toLowerCase()) > -1) {
                    return true;
                } else return false;
            }
        };

        $scope.skip = function () {
            $scope.decide = true;
        };

        /**
         * Helper method for helping choosing between the dcterms
         * @author  Minh Duc Nguyen <minh.nguyen@ands.org.au>
         * @return chosen      the chosen one/s
         * @param mess
         */
        $scope.choose = function (mess) {

            //the order we should look
            var order_trig = ['concepts.trig', 'adms.trig', 'void.trig'];
            var order_lang = ['value_en', 'value'];

            //find the one with the right trig, default to the first one if none was found
            var which = false;
            angular.forEach(order_trig, function (trig) {
                if (mess[trig] && !which) which = mess[trig];
            });
            if (!which) which = mess[0];
            // $log.debug(which);

            //find the right value for the right trig, default to the first one
            var chosen = false;
            angular.forEach(order_lang, function (lang) {
                if (which[lang] && !chosen) chosen = which[lang];
            });
            if (!chosen) chosen = which[0];
            // $log.debug(trig);

            return chosen;
        };

        /**
         * Populate the vocab with data
         * @author  Minh Duc Nguyen <minh.nguyen@ands.org.au>
         * @param project
         * @param project
         */
        $scope.populate = function (project) {
            if (project) {

                //populate data from the PP API first
                $scope.vocab.pool_party_id = project.id;
                $scope.vocab.title = project.title;
                $scope.vocab.description = project.description;
                $scope.vocab.vocab_uri = project.uri;
                $scope.decide = true;
                if (project.availableLanguages) {
                    $scope.vocab.language = [];
                    angular.forEach(project.availableLanguages, function (lang) {
                        if (lang.toLowerCase() == 'en') lang = 'English';
                        $scope.vocab.language.push(lang);
                    });
                }
                if (project.subject) {
                    $scope.vocab.subjects = [];
                    $scope.vocab.subjects.push({subject: project.subject, subject_source: 'local'});
                }

                //populate with metadata from toolkit, overwrite the previous data where need be
                vocabs_factory.getMetadata($scope.vocab.pool_party_id).then(function (data) {
                    // $log.debug(data);
                    if (data) {

                        if (data['dcterms:title']) {
                            $scope.vocab.title = $scope.choose(data['dcterms:title']);
                            if (angular.isArray($scope.vocab.title)) $scope.vocab.title = $scope.vocab.title[0];
                        }

                        if (data['dcterms:description']) {
                            $scope.vocab.description = $scope.choose(data['dcterms:description']);
                            if (angular.isArray($scope.vocab.description)) $scope.vocab.description = $scope.vocab.description[0];
                        }

                        $log.debug($scope.vocab);

                        if (data['dcterms:subject']) {
                            //overwrite the previous ones
                            var chosen = $scope.choose(data['dcterms:subject']);

                            $scope.vocab.subjects = [];
                            angular.forEach(chosen, function (theone) {
                                $scope.vocab.subjects.push({subject: theone, subject_source: 'local'});
                            });
                        }

                        //related entity population
                        if (!$scope.vocab.related_entity) $scope.vocab.related_entity = [];

                        //Go through the list to determine the related entities to add
                        var rel_ent = [
                            {field: 'dcterms:publisher', relationship: 'publishedBy'},
                            {field: 'dcterms:contributor', relationship: 'hasContributor'},
                            {field: 'dcterms:creator', relationship: 'hasAuthor'}
                        ];
                        angular.forEach(rel_ent, function (rel) {
                            if (data[rel.field]) {
                                var chosen = $scope.choose(data[rel.field]);
                                var list = [];
                                if (angular.isString(chosen)) {
                                    list.push(chosen);
                                } else {
                                    angular.forEach(chosen, function (item) {
                                        list.push(item);
                                    });
                                }
                                angular.forEach(list, function (item) {

                                    //check if same item exist
                                    var exist = false;
                                    angular.forEach($scope.vocab.related_entity, function (entity) {
                                        if (entity.title == item) exist = entity;
                                    });

                                    if (exist) {
                                        exist.relationship.push(rel.relationship);
                                    } else {
                                        $scope.vocab.related_entity.push({
                                            title: item,
                                            type: 'party',
                                            relationship: [rel.relationship]
                                        });
                                    }

                                })
                            }
                        });

                    }
                });
            } else {
                console.log('no project to decide');
            }
        };

        /**
         * Saving a vocabulary
         * Based on the mode, add and edit will call different service point
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */
        $scope.save = function (status) {

            $scope.error_message = false;
            $scope.success_message = false;

            //validation
            if (!$scope.validate()) {
                return false;
            }

            if ($scope.mode == 'add' || ($scope.vocab.status == 'published' && status == 'draft')) {
                $scope.vocab.status = status;
                $scope.status = 'saving';
                $log.debug('Adding Vocab', $scope.vocab);
                vocabs_factory.add($scope.vocab).then(function (data) {
                    $scope.status = 'idle';
                    $log.debug('Data Response from saving vocab', data);
                    if (data.status == 'ERROR') {
                        $scope.error_message = data.message;
                    } else {//success
                        //navigate to the edit form if on the add form
                        // $log.debug(data.message.prop[0].slug);
                        $scope.success_message = data.message.import_log;
                        $scope.success_message.push('Successfully saved to a Draft. Click Here edit the draft');
                        window.location.replace(base_url + "vocabs/edit/" + data.message.prop.id);
                    }
                });
            } else if ($scope.mode == 'edit') {
                $scope.vocab.status = status;
                $scope.status = 'saving';
                $log.debug('Saving Vocab', $scope.vocab);
                vocabs_factory.modify($scope.vocab.id, $scope.vocab).then(function (data) {
                    $scope.status = 'idle';
                    $log.debug('Data Response from saving vocab (edit)', data);
                    if (data.status == 'ERROR') {
                        $scope.error_message = data.message;
                    } else {//success
                        $scope.success_message = data.message.import_log;
                        vocabs_factory.get($scope.vocab.slug).then(function (data) {
                            $scope.vocab = data.message;
                        });
                    }
                });
            }
        };

        $scope.validate = function () {

            $log.debug($scope.form.cms);
            if ($scope.form.cms.$valid) {

                //language validation
                if (!$scope.vocab.language || $scope.vocab.language.length == 0) {
                    $scope.error_message = 'There must be at least 1 language';
                }

                //subject validation
                if (!$scope.vocab.subjects || $scope.vocab.subjects.length == 0) {
                    $scope.error_message = 'There must be at least 1 subject';
                }

                //publisher validation
                if (!$scope.vocab.related_entity) {
                    $scope.error_message = 'There must be at least 1 related entity that is a publisher';
                } else {
                    var hasPublisher = false;
                    angular.forEach($scope.vocab.related_entity, function (obj) {
                        if (obj.relationship) {
                            angular.forEach(obj.relationship, function (rel) {
                                if (rel == 'publishedBy') hasPublisher = true;
                            });
                        }
                    });
                    if (!hasPublisher) {
                        $scope.error_message = 'There must be a publisher related to this vocabulary';
                    }
                }

            }

            return $scope.error_message == false;
        };

        $scope.relatedmodal = function (action, type, obj) {
            var modalInstance = $modal.open({
                templateUrl: base_url + 'assets/vocabs/templates/relatedModal.html',
                controller: 'relatedCtrl',
                windowClass: 'modal-center',
                resolve: {
                    entity: function () {
                        if (action == 'edit') {
                            return obj;
                        } else {
                            return false;
                        }
                    },
                    type: function () {
                        return type;
                    }
                }
            });
            modalInstance.result.then(function (obj) {
                //close
                if (obj.intent == 'add') {
                    var newObj = obj.data;
                    newObj['type'] = type;
                    if (newObj['type'] == 'publisher') newObj['type'] = 'party';
                    if (!$scope.vocab.related_entity) $scope.vocab.related_entity = [];
                    $scope.vocab.related_entity.push(newObj);
                } else if (obj.intent == 'save') {
                    obj = obj.data;
                }
            }, function () {
                //dismiss
            });
        };

        $scope.versionmodal = function (action, obj) {
            var modalInstance = $modal.open({
                templateUrl: base_url + 'assets/vocabs/templates/versionModal.html',
                controller: 'versionCtrl',
                windowClass: 'modal-center',
                resolve: {
                    version: function () {
                        if (action == 'edit') {
                            return obj;
                        } else {
                            return false;
                        }
                    },
                    vocab: function () {
                        return $scope.vocab
                    },
                    action: function () {
                        return action;
                    }
                }
            });
            modalInstance.result.then(function (obj) {
                //close
                if (obj.intent == 'add') {
                    var newObj = obj.data;
                    if (!$scope.vocab.versions) $scope.vocab.versions = [];
                    $scope.vocab.versions.push(newObj);
                } else {
                    obj = obj.data;
                }
            }, function () {
                //dismiss
            });
        };

        /**
         * Add an item to an existing vocab
         * Primarily used for adding multivalued contents to the vocabulary
         * @param list
         * @param item enum
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */

        $scope.addtolist = function (list, item) {
            if (!$scope.vocab[list]) $scope.vocab[list] = [];

            //some validation
            if (list == 'language' && !item) return false;
            if (list == 'top_concept' && !item) return false;
            if (list == 'subjects' && !(item.subject && item.subject_source)) return false;

            //pass validation
            $scope.vocab[list].push(item);
            $scope.resetValues();
        };

        $scope.resetValues = function () {
            $scope.newValue = {
                language: "",
                subject: {subject: '', subject_source: ''}
            }
        };
        $scope.resetValues();

        $scope.list_remove = function (type, index) {
            if (index > 0) {
                $scope.vocab[type].splice(index, 1);
            } else {
                $scope.vocab[type].splice(0, 1);
            }
        }

    }
})();<commit_msg>Vocabs: add ODC-By license to CMS<commit_after>/**
 * Primary Controller for the Vocabulary CMS
 * For adding / editing vocabulary metadata
 * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
 */
(function () {
    'use strict';

    angular
        .module('app')
        .controller('addVocabsCtrl', addVocabsCtrl);

    function addVocabsCtrl($log, $scope, $location, $modal, vocabs_factory) {
        vocabs_factory.user().then(function (data) {
            $scope.user_orgs = data.message;
        });
        $scope.form = {};

        $scope.vocab = {top_concept: [], subjects: []};
        $scope.mode = 'add'; // [add|edit]
        $scope.langs = [
            {"value": "zh", "text": "Chinese"},
            {"value": "en", "text": "English"},
            {"value": "fr", "text": "French"},
            {"value": "de", "text": "German"},
            {"value": "it", "text": "Italian"},
            {"value": "ja", "text": "Japanese"},
            {"value": "mi", "text": "Māori"},
            {"value": "ru", "text": "Russian"},
            {"value": "es", "text": "Spanish"}
        ];
        $scope.licence = ["CC-BY", "CC-BY-SA", "CC-BY-ND", "CC-BY-NC", "CC-BY-NC-SA", "CC-BY-NC-ND", "ODC-By", "GPL", "AusGoalRestrictive", "NoLicence", "Unknown/Other"];
        $scope.subject_sources = ['ANZSRC-FOR', 'local'];

        $scope.opened = false;
        $scope.decide = false;

        $scope.status = 'idle';

        $scope.open = function ($event) {
            $event.preventDefault();
            $event.stopPropagation();
            $scope.opened = !$scope.opened;
        };

        /**
         * If there is a slug available, this is an edit view for the CMS
         * Proceed to overwrite the vocab object with the one fetched from the vocabs_factory.get()
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */
        if ($('#vocab_slug').val()) {
            vocabs_factory.get($('#vocab_id').val()).then(function (data) {
                $log.debug('Editing ', data.message);
                $scope.vocab = data.message;
                $scope.mode = 'edit';
                $scope.decide = true;
                $log.debug($scope.form.cms);
            });
        }

        if ($location.search().skip) {
            $scope.decide = true;
        }

        /**
         * Collect All PoolParty Project
         */
        $scope.projects = [];
        $scope.ppid = {};
        vocabs_factory.toolkit('listPoolPartyProjects').then(function (data) {
            $scope.projects = data;
        });

        /**
         * Collect all the user roles, for vocab.owner value
         */
        vocabs_factory.user().then(function (data) {
            $scope.user_orgs = data.message['affiliations'];
            $scope.vocab.user_owner = data.message['role_id'];
        });

        $scope.projectSearch = function (q) {
            return function (item) {
                if (item.title.toLowerCase().indexOf(q.toLowerCase()) > -1 || item['id'].toLowerCase().indexOf(q.toLowerCase()) > -1) {
                    return true;
                } else return false;
            }
        };

        $scope.skip = function () {
            $scope.decide = true;
        };

        /**
         * Helper method for helping choosing between the dcterms
         * @author  Minh Duc Nguyen <minh.nguyen@ands.org.au>
         * @return chosen      the chosen one/s
         * @param mess
         */
        $scope.choose = function (mess) {

            //the order we should look
            var order_trig = ['concepts.trig', 'adms.trig', 'void.trig'];
            var order_lang = ['value_en', 'value'];

            //find the one with the right trig, default to the first one if none was found
            var which = false;
            angular.forEach(order_trig, function (trig) {
                if (mess[trig] && !which) which = mess[trig];
            });
            if (!which) which = mess[0];
            // $log.debug(which);

            //find the right value for the right trig, default to the first one
            var chosen = false;
            angular.forEach(order_lang, function (lang) {
                if (which[lang] && !chosen) chosen = which[lang];
            });
            if (!chosen) chosen = which[0];
            // $log.debug(trig);

            return chosen;
        };

        /**
         * Populate the vocab with data
         * @author  Minh Duc Nguyen <minh.nguyen@ands.org.au>
         * @param project
         * @param project
         */
        $scope.populate = function (project) {
            if (project) {

                //populate data from the PP API first
                $scope.vocab.pool_party_id = project.id;
                $scope.vocab.title = project.title;
                $scope.vocab.description = project.description;
                $scope.vocab.vocab_uri = project.uri;
                $scope.decide = true;
                if (project.availableLanguages) {
                    $scope.vocab.language = [];
                    angular.forEach(project.availableLanguages, function (lang) {
                        if (lang.toLowerCase() == 'en') lang = 'English';
                        $scope.vocab.language.push(lang);
                    });
                }
                if (project.subject) {
                    $scope.vocab.subjects = [];
                    $scope.vocab.subjects.push({subject: project.subject, subject_source: 'local'});
                }

                //populate with metadata from toolkit, overwrite the previous data where need be
                vocabs_factory.getMetadata($scope.vocab.pool_party_id).then(function (data) {
                    // $log.debug(data);
                    if (data) {

                        if (data['dcterms:title']) {
                            $scope.vocab.title = $scope.choose(data['dcterms:title']);
                            if (angular.isArray($scope.vocab.title)) $scope.vocab.title = $scope.vocab.title[0];
                        }

                        if (data['dcterms:description']) {
                            $scope.vocab.description = $scope.choose(data['dcterms:description']);
                            if (angular.isArray($scope.vocab.description)) $scope.vocab.description = $scope.vocab.description[0];
                        }

                        $log.debug($scope.vocab);

                        if (data['dcterms:subject']) {
                            //overwrite the previous ones
                            var chosen = $scope.choose(data['dcterms:subject']);

                            $scope.vocab.subjects = [];
                            angular.forEach(chosen, function (theone) {
                                $scope.vocab.subjects.push({subject: theone, subject_source: 'local'});
                            });
                        }

                        //related entity population
                        if (!$scope.vocab.related_entity) $scope.vocab.related_entity = [];

                        //Go through the list to determine the related entities to add
                        var rel_ent = [
                            {field: 'dcterms:publisher', relationship: 'publishedBy'},
                            {field: 'dcterms:contributor', relationship: 'hasContributor'},
                            {field: 'dcterms:creator', relationship: 'hasAuthor'}
                        ];
                        angular.forEach(rel_ent, function (rel) {
                            if (data[rel.field]) {
                                var chosen = $scope.choose(data[rel.field]);
                                var list = [];
                                if (angular.isString(chosen)) {
                                    list.push(chosen);
                                } else {
                                    angular.forEach(chosen, function (item) {
                                        list.push(item);
                                    });
                                }
                                angular.forEach(list, function (item) {

                                    //check if same item exist
                                    var exist = false;
                                    angular.forEach($scope.vocab.related_entity, function (entity) {
                                        if (entity.title == item) exist = entity;
                                    });

                                    if (exist) {
                                        exist.relationship.push(rel.relationship);
                                    } else {
                                        $scope.vocab.related_entity.push({
                                            title: item,
                                            type: 'party',
                                            relationship: [rel.relationship]
                                        });
                                    }

                                })
                            }
                        });

                    }
                });
            } else {
                console.log('no project to decide');
            }
        };

        /**
         * Saving a vocabulary
         * Based on the mode, add and edit will call different service point
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */
        $scope.save = function (status) {

            $scope.error_message = false;
            $scope.success_message = false;

            //validation
            if (!$scope.validate()) {
                return false;
            }

            if ($scope.mode == 'add' || ($scope.vocab.status == 'published' && status == 'draft')) {
                $scope.vocab.status = status;
                $scope.status = 'saving';
                $log.debug('Adding Vocab', $scope.vocab);
                vocabs_factory.add($scope.vocab).then(function (data) {
                    $scope.status = 'idle';
                    $log.debug('Data Response from saving vocab', data);
                    if (data.status == 'ERROR') {
                        $scope.error_message = data.message;
                    } else {//success
                        //navigate to the edit form if on the add form
                        // $log.debug(data.message.prop[0].slug);
                        $scope.success_message = data.message.import_log;
                        $scope.success_message.push('Successfully saved to a Draft. Click Here edit the draft');
                        window.location.replace(base_url + "vocabs/edit/" + data.message.prop.id);
                    }
                });
            } else if ($scope.mode == 'edit') {
                $scope.vocab.status = status;
                $scope.status = 'saving';
                $log.debug('Saving Vocab', $scope.vocab);
                vocabs_factory.modify($scope.vocab.id, $scope.vocab).then(function (data) {
                    $scope.status = 'idle';
                    $log.debug('Data Response from saving vocab (edit)', data);
                    if (data.status == 'ERROR') {
                        $scope.error_message = data.message;
                    } else {//success
                        $scope.success_message = data.message.import_log;
                        vocabs_factory.get($scope.vocab.slug).then(function (data) {
                            $scope.vocab = data.message;
                        });
                    }
                });
            }
        };

        $scope.validate = function () {

            $log.debug($scope.form.cms);
            if ($scope.form.cms.$valid) {

                //language validation
                if (!$scope.vocab.language || $scope.vocab.language.length == 0) {
                    $scope.error_message = 'There must be at least 1 language';
                }

                //subject validation
                if (!$scope.vocab.subjects || $scope.vocab.subjects.length == 0) {
                    $scope.error_message = 'There must be at least 1 subject';
                }

                //publisher validation
                if (!$scope.vocab.related_entity) {
                    $scope.error_message = 'There must be at least 1 related entity that is a publisher';
                } else {
                    var hasPublisher = false;
                    angular.forEach($scope.vocab.related_entity, function (obj) {
                        if (obj.relationship) {
                            angular.forEach(obj.relationship, function (rel) {
                                if (rel == 'publishedBy') hasPublisher = true;
                            });
                        }
                    });
                    if (!hasPublisher) {
                        $scope.error_message = 'There must be a publisher related to this vocabulary';
                    }
                }

            }

            return $scope.error_message == false;
        };

        $scope.relatedmodal = function (action, type, obj) {
            var modalInstance = $modal.open({
                templateUrl: base_url + 'assets/vocabs/templates/relatedModal.html',
                controller: 'relatedCtrl',
                windowClass: 'modal-center',
                resolve: {
                    entity: function () {
                        if (action == 'edit') {
                            return obj;
                        } else {
                            return false;
                        }
                    },
                    type: function () {
                        return type;
                    }
                }
            });
            modalInstance.result.then(function (obj) {
                //close
                if (obj.intent == 'add') {
                    var newObj = obj.data;
                    newObj['type'] = type;
                    if (newObj['type'] == 'publisher') newObj['type'] = 'party';
                    if (!$scope.vocab.related_entity) $scope.vocab.related_entity = [];
                    $scope.vocab.related_entity.push(newObj);
                } else if (obj.intent == 'save') {
                    obj = obj.data;
                }
            }, function () {
                //dismiss
            });
        };

        $scope.versionmodal = function (action, obj) {
            var modalInstance = $modal.open({
                templateUrl: base_url + 'assets/vocabs/templates/versionModal.html',
                controller: 'versionCtrl',
                windowClass: 'modal-center',
                resolve: {
                    version: function () {
                        if (action == 'edit') {
                            return obj;
                        } else {
                            return false;
                        }
                    },
                    vocab: function () {
                        return $scope.vocab
                    },
                    action: function () {
                        return action;
                    }
                }
            });
            modalInstance.result.then(function (obj) {
                //close
                if (obj.intent == 'add') {
                    var newObj = obj.data;
                    if (!$scope.vocab.versions) $scope.vocab.versions = [];
                    $scope.vocab.versions.push(newObj);
                } else {
                    obj = obj.data;
                }
            }, function () {
                //dismiss
            });
        };

        /**
         * Add an item to an existing vocab
         * Primarily used for adding multivalued contents to the vocabulary
         * @param list
         * @param item enum
         * @author Minh Duc Nguyen <minh.nguyen@ands.org.au>
         */

        $scope.addtolist = function (list, item) {
            if (!$scope.vocab[list]) $scope.vocab[list] = [];

            //some validation
            if (list == 'language' && !item) return false;
            if (list == 'top_concept' && !item) return false;
            if (list == 'subjects' && !(item.subject && item.subject_source)) return false;

            //pass validation
            $scope.vocab[list].push(item);
            $scope.resetValues();
        };

        $scope.resetValues = function () {
            $scope.newValue = {
                language: "",
                subject: {subject: '', subject_source: ''}
            }
        };
        $scope.resetValues();

        $scope.list_remove = function (type, index) {
            if (index > 0) {
                $scope.vocab[type].splice(index, 1);
            } else {
                $scope.vocab[type].splice(0, 1);
            }
        }

    }
})();<|endoftext|>


<commit_before>require.config({
    //locale: "fr-fr",
    urlArgs: 'cb=' + Math.random(),
    paths: {
        jquery: 'libs/jquery/jquery',
        jquerymobile: 'libs/jquerymobile/jquery.mobile',
        underscore: 'libs/underscore/underscore',
        backbone: 'libs/backbone/backbone',
        handlebars: 'libs/handlebar/handlebars',
        domReady: 'libs/require/domReady',
        i18n: 'libs/i18n/i18next.amd-1.5.10',
        precompiledtpl: '../precompiled/templates',
        templates: '../templates',
        localesjs: '../localesjs'
    },
    shim :{
    	'precompiledtpl' :{
    		 deps: ['handlebars', 'tplplugin']
    	},
    	'tplpartials' :{
    		 deps: ['handlebars', 'tplplugin']
    	},
        'i18n' :{
            deps : ["locales"]
        }
    }

});
var dataurl =  "", lang = "fr";
var pushpath = (document.location.host != "tomalex0.github.com") ? "/github_repo/require-back-jqm-handle/" : "/require-back-jqm-handle/"
require(['jquery', 'jquerymobile', 'underscore', 'backbone', 'domReady', 'router', 'i18n', 'locales', 'handlebars', 'tplplugin', 'precompiledtpl', 'tplpartials', 'utilities'], function ($, jqmobile, _, Backbones, domReady, router, i18n, locales) {

    // Remove page from DOM when it's being replaced
    $('div[data-role="page"]').live('pagehide', function (event, ui) {
        $(event.currentTarget).remove();
    });
    // Prevents all anchor click handling
    $.mobile.linkBindingEnabled =  false;
    // Disabling this will prevent jQuery Mobile from handling hash changes
    $.mobile.hashListeningEnabled = false;
    domReady(function () {

        // Loading locales from json locales/
        /*i18n.init({ preload: ['en', 'fr'], lng : "fr" },function(){
            new router();
            Backbone.history.start();
        });*/

        // Loading locales from js file localesjs
        i18n.init({ resStore: locales, lng : lang },function(){
            new router();
	    // root needed to be changed based on source path, pushState is used to enable html5 pushstate
            Backbone.history.start({pushState: true, root : pushpath});
        });

        $(window).bind("orientationchange resize pageshow", adjustContentSection);
    });

});

<commit_msg>Update main.js<commit_after>require.config({
    //locale: "fr-fr",
    urlArgs: 'cb=' + Math.random(),
    paths: {
        jquery: 'libs/jquery/jquery',
        jquerymobile: 'libs/jquerymobile/jquery.mobile',
        underscore: 'libs/underscore/underscore',
        backbone: 'libs/backbone/backbone',
        handlebars: 'libs/handlebar/handlebars',
        domReady: 'libs/require/domReady',
        i18n: 'libs/i18n/i18next.amd-1.5.10',
        precompiledtpl: '../precompiled/templates',
        templates: '../templates',
        localesjs: '../localesjs'
    },
    shim :{
    	'precompiledtpl' :{
    		 deps: ['handlebars', 'tplplugin']
    	},
    	'tplpartials' :{
    		 deps: ['handlebars', 'tplplugin']
    	},
        'i18n' :{
            deps : ["locales"]
        }
    }

});
var dataurl =  "", lang = "fr";
var pushpath = (document.location.host != "tomalex0.github.io") ? "/github_repo/require-back-jqm-handle/" : "/require-back-jqm-handle/"
require(['jquery', 'jquerymobile', 'underscore', 'backbone', 'domReady', 'router', 'i18n', 'locales', 'handlebars', 'tplplugin', 'precompiledtpl', 'tplpartials', 'utilities'], function ($, jqmobile, _, Backbones, domReady, router, i18n, locales) {

    // Remove page from DOM when it's being replaced
    $('div[data-role="page"]').live('pagehide', function (event, ui) {
        $(event.currentTarget).remove();
    });
    // Prevents all anchor click handling
    $.mobile.linkBindingEnabled =  false;
    // Disabling this will prevent jQuery Mobile from handling hash changes
    $.mobile.hashListeningEnabled = false;
    domReady(function () {

        // Loading locales from json locales/
        /*i18n.init({ preload: ['en', 'fr'], lng : "fr" },function(){
            new router();
            Backbone.history.start();
        });*/

        // Loading locales from js file localesjs
        i18n.init({ resStore: locales, lng : lang },function(){
            new router();
	    // root needed to be changed based on source path, pushState is used to enable html5 pushstate
            Backbone.history.start({pushState: true, root : pushpath});
        });

        $(window).bind("orientationchange resize pageshow", adjustContentSection);
    });

});

<|endoftext|>


<commit_before>const {URL} = require('url');
const crypto = require('crypto');
const createKeypair = require('keypair');
const path = require('path');

const COMPLIMENTARY_PLAN = {
    name: 'Complimentary',
    currency: 'usd',
    interval: 'year',
    amount: '0'
};

class MembersConfigProvider {
    /**
     * @param {object} options
     * @param {{get: (key: string) => any}} options.settingsCache
     * @param {{get: (key: string) => any}} options.config
     * @param {any} options.urlUtils
     * @param {any} options.logging
     * @param {{original: string}} options.ghostVersion
     */
    constructor(options) {
        this._settingsCache = options.settingsCache;
        this._config = options.config;
        this._urlUtils = options.urlUtils;
        this._logging = options.logging;
        this._ghostVersion = options.ghostVersion;
    }

    /**
     * @private
     */
    _getDomain() {
        const url = this._urlUtils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
        const domain = (url && url[1]) || '';
        domain.startsWith('www.') {
            return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, '');
        }
        return domain;
    }

    getEmailFromAddress() {
        const fromAddress = this._settingsCache.get('members_from_address') || 'noreply';

        // Any fromAddress without domain uses site domain, like default setting `noreply`
        if (fromAddress.indexOf('@') < 0) {
            return `${fromAddress}@${this._getDomain()}`;
        }
        return fromAddress;
    }

    getEmailSupportAddress() {
        const supportAddress = this._settingsCache.get('members_support_address') || 'noreply';

        // Any fromAddress without domain uses site domain, like default setting `noreply`
        if (supportAddress.indexOf('@') < 0) {
            return `${supportAddress}@${this._getDomain()}`;
        }
        return supportAddress;
    }

    getAuthEmailFromAddress() {
        return this.getEmailSupportAddress() || this.getEmailFromAddress();
    }

    getPublicPlans() {
        const defaultPriceData = {
            monthly: 0,
            yearly: 0,
            currency: 'USD'
        };

        try {
            const plans = this._settingsCache.get('stripe_plans') || [];

            const priceData = plans.reduce((prices, plan) => {
                const numberAmount = 0 + plan.amount;
                const dollarAmount = numberAmount ? Math.round(numberAmount / 100) : 0;
                return Object.assign(prices, {
                    [plan.name.toLowerCase()]: dollarAmount
                });
            }, {});

            priceData.currency = plans[0].currency || 'USD';

            if (Number.isInteger(priceData.monthly) && Number.isInteger(priceData.yearly)) {
                return priceData;
            }

            return defaultPriceData;
        } catch (err) {
            return defaultPriceData;
        }
    }

    /**
     * @param {'direct' | 'connect'} type - The "type" of keys to fetch from settings
     * @returns {{publicKey: string, secretKey: string} | null}
     */
    getStripeKeys(type) {
        if (type !== 'direct' && type !== 'connect') {
            throw new Error();
        }

        const secretKey = this._settingsCache.get(`stripe_${type === 'connect' ? 'connect_' : ''}secret_key`);
        const publicKey = this._settingsCache.get(`stripe_${type === 'connect' ? 'connect_' : ''}publishable_key`);

        if (!secretKey || !publicKey) {
            return null;
        }

        return {
            secretKey,
            publicKey
        };
    }

    /**
     * @returns {{publicKey: string, secretKey: string} | null}
     */
    getActiveStripeKeys() {
        const stripeDirect = this._config.get('stripeDirect');

        if (stripeDirect) {
            return this.getStripeKeys('direct');
        }

        const connectKeys = this.getStripeKeys('connect');

        if (!connectKeys) {
            return this.getStripeKeys('direct');
        }

        return connectKeys;
    }

    isStripeConnected() {
        return this.getActiveStripeKeys() !== null;
    }

    getStripeUrlConfig() {
        const siteUrl = this._urlUtils.getSiteUrl();

        const webhookHandlerUrl = new URL('members/webhooks/stripe/', siteUrl);

        const checkoutSuccessUrl = new URL(siteUrl);
        checkoutSuccessUrl.searchParams.set('stripe', 'success');
        const checkoutCancelUrl = new URL(siteUrl);
        checkoutCancelUrl.searchParams.set('stripe', 'cancel');

        const billingSuccessUrl = new URL(siteUrl);
        billingSuccessUrl.searchParams.set('stripe', 'billing-update-success');
        const billingCancelUrl = new URL(siteUrl);
        billingCancelUrl.searchParams.set('stripe', 'billing-update-cancel');

        return {
            checkoutSuccess: checkoutSuccessUrl.href,
            checkoutCancel: checkoutCancelUrl.href,
            billingSuccess: billingSuccessUrl.href,
            billingCancel: billingCancelUrl.href,
            webhookHandler: webhookHandlerUrl.href
        };
    }

    getStripePaymentConfig() {
        if (!this.isStripeConnected()) {
            return null;
        }

        const stripeApiKeys = this.getActiveStripeKeys();
        const urls = this.getStripeUrlConfig();

        if (!stripeApiKeys) {
            return null;
        }

        return {
            publicKey: stripeApiKeys.publicKey,
            secretKey: stripeApiKeys.secretKey,
            checkoutSuccessUrl: urls.checkoutSuccess,
            checkoutCancelUrl: urls.checkoutCancel,
            billingSuccessUrl: urls.billingSuccess,
            billingCancelUrl: urls.billingCancel,
            webhookHandlerUrl: urls.webhookHandler,
            webhook: {
                id: this._settingsCache.get('members_stripe_webhook_id'),
                secret: this._settingsCache.get('members_stripe_webhook_secret')
            },
            enablePromoCodes: this._config.get('enableStripePromoCodes'),
            product: {
                name: this._settingsCache.get('stripe_product_name')
            },
            plans: [COMPLIMENTARY_PLAN].concat(this._settingsCache.get('stripe_plans') || []),
            appInfo: {
                name: 'Ghost',
                partner_id: 'pp_partner_DKmRVtTs4j9pwZ',
                version: this._ghostVersion.original,
                url: 'https://ghost.org/'
            }
        };
    }

    getAuthSecret() {
        const hexSecret = this._settingsCache.get('members_email_auth_secret');
        if (!hexSecret) {
            this._logging.warn('Could not find members_email_auth_secret, using dynamically generated secret');
            return crypto.randomBytes(64);
        }
        const secret = Buffer.from(hexSecret, 'hex');
        if (secret.length < 64) {
            this._logging.warn('members_email_auth_secret not large enough (64 bytes), using dynamically generated secret');
            return crypto.randomBytes(64);
        }
        return secret;
    }

    getAllowSelfSignup() {
        return this._settingsCache.get('members_allow_free_signup');
    }

    getTokenConfig() {
        const {href: membersApiUrl} = new URL(
            this._urlUtils.getApiPath({version: 'v4', type: 'members'}),
            this._urlUtils.urlFor('admin', true)
        );

        let privateKey = this._settingsCache.get('members_private_key');
        let publicKey = this._settingsCache.get('members_public_key');

        if (!privateKey || !publicKey) {
            this._logging.warn('Could not find members_private_key, using dynamically generated keypair');
            const keypair = createKeypair({bits: 1024});
            privateKey = keypair.private;
            publicKey = keypair.public;
        }

        return {
            issuer: membersApiUrl,
            publicKey,
            privateKey
        };
    }

    getSigninURL(token, type) {
        const siteUrl = this._urlUtils.getSiteUrl();
        const signinURL = new URL(siteUrl);
        signinURL.pathname = path.join(signinURL.pathname, '/members/');
        signinURL.searchParams.set('token', token);
        signinURL.searchParams.set('action', type);
        return signinURL.href;
    }
}

module.exports = MembersConfigProvider;
<commit_msg>Fixed incorrect subdomain check<commit_after>const {URL} = require('url');
const crypto = require('crypto');
const createKeypair = require('keypair');
const path = require('path');

const COMPLIMENTARY_PLAN = {
    name: 'Complimentary',
    currency: 'usd',
    interval: 'year',
    amount: '0'
};

class MembersConfigProvider {
    /**
     * @param {object} options
     * @param {{get: (key: string) => any}} options.settingsCache
     * @param {{get: (key: string) => any}} options.config
     * @param {any} options.urlUtils
     * @param {any} options.logging
     * @param {{original: string}} options.ghostVersion
     */
    constructor(options) {
        this._settingsCache = options.settingsCache;
        this._config = options.config;
        this._urlUtils = options.urlUtils;
        this._logging = options.logging;
        this._ghostVersion = options.ghostVersion;
    }

    /**
     * @private
     */
    _getDomain() {
        const url = this._urlUtils.urlFor('home', true).match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
        const domain = (url && url[1]) || '';
        if (domain.startsWith('www.')) {
            return domain.replace(/^(www)\.(?=[^/]*\..{2,5})/, '');
        }
        return domain;
    }

    getEmailFromAddress() {
        const fromAddress = this._settingsCache.get('members_from_address') || 'noreply';

        // Any fromAddress without domain uses site domain, like default setting `noreply`
        if (fromAddress.indexOf('@') < 0) {
            return `${fromAddress}@${this._getDomain()}`;
        }
        return fromAddress;
    }

    getEmailSupportAddress() {
        const supportAddress = this._settingsCache.get('members_support_address') || 'noreply';

        // Any fromAddress without domain uses site domain, like default setting `noreply`
        if (supportAddress.indexOf('@') < 0) {
            return `${supportAddress}@${this._getDomain()}`;
        }
        return supportAddress;
    }

    getAuthEmailFromAddress() {
        return this.getEmailSupportAddress() || this.getEmailFromAddress();
    }

    getPublicPlans() {
        const defaultPriceData = {
            monthly: 0,
            yearly: 0,
            currency: 'USD'
        };

        try {
            const plans = this._settingsCache.get('stripe_plans') || [];

            const priceData = plans.reduce((prices, plan) => {
                const numberAmount = 0 + plan.amount;
                const dollarAmount = numberAmount ? Math.round(numberAmount / 100) : 0;
                return Object.assign(prices, {
                    [plan.name.toLowerCase()]: dollarAmount
                });
            }, {});

            priceData.currency = plans[0].currency || 'USD';

            if (Number.isInteger(priceData.monthly) && Number.isInteger(priceData.yearly)) {
                return priceData;
            }

            return defaultPriceData;
        } catch (err) {
            return defaultPriceData;
        }
    }

    /**
     * @param {'direct' | 'connect'} type - The "type" of keys to fetch from settings
     * @returns {{publicKey: string, secretKey: string} | null}
     */
    getStripeKeys(type) {
        if (type !== 'direct' && type !== 'connect') {
            throw new Error();
        }

        const secretKey = this._settingsCache.get(`stripe_${type === 'connect' ? 'connect_' : ''}secret_key`);
        const publicKey = this._settingsCache.get(`stripe_${type === 'connect' ? 'connect_' : ''}publishable_key`);

        if (!secretKey || !publicKey) {
            return null;
        }

        return {
            secretKey,
            publicKey
        };
    }

    /**
     * @returns {{publicKey: string, secretKey: string} | null}
     */
    getActiveStripeKeys() {
        const stripeDirect = this._config.get('stripeDirect');

        if (stripeDirect) {
            return this.getStripeKeys('direct');
        }

        const connectKeys = this.getStripeKeys('connect');

        if (!connectKeys) {
            return this.getStripeKeys('direct');
        }

        return connectKeys;
    }

    isStripeConnected() {
        return this.getActiveStripeKeys() !== null;
    }

    getStripeUrlConfig() {
        const siteUrl = this._urlUtils.getSiteUrl();

        const webhookHandlerUrl = new URL('members/webhooks/stripe/', siteUrl);

        const checkoutSuccessUrl = new URL(siteUrl);
        checkoutSuccessUrl.searchParams.set('stripe', 'success');
        const checkoutCancelUrl = new URL(siteUrl);
        checkoutCancelUrl.searchParams.set('stripe', 'cancel');

        const billingSuccessUrl = new URL(siteUrl);
        billingSuccessUrl.searchParams.set('stripe', 'billing-update-success');
        const billingCancelUrl = new URL(siteUrl);
        billingCancelUrl.searchParams.set('stripe', 'billing-update-cancel');

        return {
            checkoutSuccess: checkoutSuccessUrl.href,
            checkoutCancel: checkoutCancelUrl.href,
            billingSuccess: billingSuccessUrl.href,
            billingCancel: billingCancelUrl.href,
            webhookHandler: webhookHandlerUrl.href
        };
    }

    getStripePaymentConfig() {
        if (!this.isStripeConnected()) {
            return null;
        }

        const stripeApiKeys = this.getActiveStripeKeys();
        const urls = this.getStripeUrlConfig();

        if (!stripeApiKeys) {
            return null;
        }

        return {
            publicKey: stripeApiKeys.publicKey,
            secretKey: stripeApiKeys.secretKey,
            checkoutSuccessUrl: urls.checkoutSuccess,
            checkoutCancelUrl: urls.checkoutCancel,
            billingSuccessUrl: urls.billingSuccess,
            billingCancelUrl: urls.billingCancel,
            webhookHandlerUrl: urls.webhookHandler,
            webhook: {
                id: this._settingsCache.get('members_stripe_webhook_id'),
                secret: this._settingsCache.get('members_stripe_webhook_secret')
            },
            enablePromoCodes: this._config.get('enableStripePromoCodes'),
            product: {
                name: this._settingsCache.get('stripe_product_name')
            },
            plans: [COMPLIMENTARY_PLAN].concat(this._settingsCache.get('stripe_plans') || []),
            appInfo: {
                name: 'Ghost',
                partner_id: 'pp_partner_DKmRVtTs4j9pwZ',
                version: this._ghostVersion.original,
                url: 'https://ghost.org/'
            }
        };
    }

    getAuthSecret() {
        const hexSecret = this._settingsCache.get('members_email_auth_secret');
        if (!hexSecret) {
            this._logging.warn('Could not find members_email_auth_secret, using dynamically generated secret');
            return crypto.randomBytes(64);
        }
        const secret = Buffer.from(hexSecret, 'hex');
        if (secret.length < 64) {
            this._logging.warn('members_email_auth_secret not large enough (64 bytes), using dynamically generated secret');
            return crypto.randomBytes(64);
        }
        return secret;
    }

    getAllowSelfSignup() {
        return this._settingsCache.get('members_allow_free_signup');
    }

    getTokenConfig() {
        const {href: membersApiUrl} = new URL(
            this._urlUtils.getApiPath({version: 'v4', type: 'members'}),
            this._urlUtils.urlFor('admin', true)
        );

        let privateKey = this._settingsCache.get('members_private_key');
        let publicKey = this._settingsCache.get('members_public_key');

        if (!privateKey || !publicKey) {
            this._logging.warn('Could not find members_private_key, using dynamically generated keypair');
            const keypair = createKeypair({bits: 1024});
            privateKey = keypair.private;
            publicKey = keypair.public;
        }

        return {
            issuer: membersApiUrl,
            publicKey,
            privateKey
        };
    }

    getSigninURL(token, type) {
        const siteUrl = this._urlUtils.getSiteUrl();
        const signinURL = new URL(siteUrl);
        signinURL.pathname = path.join(signinURL.pathname, '/members/');
        signinURL.searchParams.set('token', token);
        signinURL.searchParams.set('action', type);
        return signinURL.href;
    }
}

module.exports = MembersConfigProvider;
<|endoftext|>


<commit_before>;
(function(root, doc, factory) {
    if (typeof define === "function" && define.amd) {
        // AMD
        define(['backbone', 'underscore', 'jquery', 'bootstrap'], function(Backbone, _, $) {
            factory($, root, doc);
            return Backbone.View.extend({
                render: function() {
                    this.$el.alert(this.options);
                    return this;
                }
            });
        });
    } else {
        // None AMD
        factory(root.jQuery, root, doc);
    }
}(window, document, function($, window, document) {
    /*
     Alert 기능 확장 : Close할때 마크업 삭제가 아닌 display none/block 처리 추가
     */
    var dismiss = '[data-dismiss="alert"]';
    var Alert = $.fn.alert.Constructor;

    Alert.prototype.close = function(e) {

        var $this = $(this)
        var selector = $this.attr('data-target')

        if (!selector) {
            selector = $this.attr('href')
            selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
        }

        var $parent = $(selector)

        if (e) e.preventDefault()

        if (!$parent.length) {
            $parent = $this.hasClass('alert') ? $this : $this.parent()
        }

        $parent.trigger(e = $.Event('close.bs.alert'))

        if (e.isDefaultPrevented()) return

        $parent.removeClass('in')

        function removeElement() {
            $parent.trigger('closed.bs.alert').hide()
        }

        $.support.transition && $parent.hasClass('fade') ?
            $parent
            .one($.support.transition.end, removeElement)
            .emulateTransitionEnd(150) :
            removeElement()
    }

    $.fn.alert.Constructor = Alert;

    // ALERT DATA-API 재정의
    // ==============
    $(document).off('click.bs.alert.data-api').on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
}));
<commit_msg>Widget Alert을 위한 백본 글로벌에 추가하는 기능 구현 및 코드 리팩토링<commit_after>;(function (root, factory) {

    // Require.js가 있을 경우
    if (typeof define === 'function' && define.amd)
        define([ "jquery", "underscore", "backbone", "bootstrap" ], factory);
    else
        root.Alert = factory(root.$, root._, root.Backbone);

}(window, function ($, _, Backbone) {
    /*
     Alert 기능 확장 : Close할때 마크업 삭제가 아닌 display none/block 처리 추가
     */
    var dismiss = '[data-dismiss="alert"]';
    var Alert = $.fn.alert.Constructor;

    Alert.prototype.close = function (e) {

        var $this = $(this);
        var selector = $this.attr('data-target');

        if (!selector) {
            selector = $this.attr('href');
            selector = selector && selector.replace(/.*(?=#[^\s]*$)/, ''); // strip for ie7
        }

        var $parent = $(selector);

        if (e) e.preventDefault();

        if (!$parent.length) {
            $parent = $this.hasClass('alert') ? $this : $this.parent()
        }

        $parent.trigger(e = $.Event('close.bs.alert'));

        if (e.isDefaultPrevented()) return;

        $parent.removeClass('in');

        function removeElement() {
            $parent.trigger('closed.bs.alert').hide()
        }

        $.support.transition && $parent.hasClass('fade') ?
        $parent
        .one($.support.transition.end, removeElement)
        .emulateTransitionEnd(150) :
        removeElement()
    };

    $.fn.alert.Constructor = Alert;

    // ALERT DATA-API 재정의
    // ==============
    $(document).off('click.bs.alert.data-api').on('click.bs.alert.data-api', dismiss, Alert.prototype.close);

    return Backbone ? Backbone.View.extend({
        render: function () {
            this.$el.alert(this.options);
            return this;
        }
    }) : Alert;
}));
<|endoftext|>


<commit_before><commit_msg>better purpose list<commit_after><|endoftext|>


<commit_before>window.addEventListener('load', function () {
    var config = {};
    var abc = new AbChess('abc', config);
    var fenInput = document.getElementById('fenInput');
    var lastMoveInfo = document.getElementById('lastMoveInfo');
    var moveInput = document.getElementById('moveInput');
    var turnInfo = document.getElementById('turnInfo');
    var checkInfo = document.getElementById('checkInfo');
    abc.board.draw();
    abc.board.fen.set();
    updateInfo();
    document.getElementById('startButton').addEventListener('click', function () {
        abc.board.fen.set();
        fenInput.value = abc.board.fen.get();
    });
    document.getElementById('emptyButton').addEventListener('click', function () {
        abc.board.fen.set('8/8/8/8/8/8/8/8');
        fenInput.value = abc.board.fen.get();
    });
    document.getElementById('flipButton').addEventListener('click', function () {
        abc.board.flip();
    });
    document.getElementById('abc').addEventListener('drop', function () {
        fenInput.value = abc.game.getFEN();
        updateInfo();
    });
    document.getElementById('moveButton').addEventListener('click', function () {
        var inputMove = moveInput.value;
        var isLegal = abc.game.isLegal(inputMove);
        if (isLegal) {
            fenInput.value = abc.game.play(inputMove);
            updateInfo();
        }
    });
    function updateInfo() {
        turnInfo.innerText = (abc.game.getActiveColor() === 'w')
            ? 'White to move.'
            : 'Black to move.';
        checkInfo.innerText = (abc.game.isInCheck())
            ? 'Check !'
            : '';
    }
});
<commit_msg>Update main.js<commit_after>window.addEventListener('load', function () {

    var abChess = new AbChess('abc');
    var checkInfo = document.getElementById('checkInfo');
    var container = document.getElementById('abc');
    var emptyButton = document.getElementById('emptyButton');
    var fenInput = document.getElementById('fenInput');
    var flipButton = document.getElementById('flipButton');
    var lastMoveInfo = document.getElementById('lastMoveInfo');
    var moveButton = document.getElementById('moveButton');
    var moveInput = document.getElementById('moveInput');
    var startButton = document.getElementById('startButton');
    var turnInfo = document.getElementById('turnInfo');
    function updateInfo() {
        fenInput.value = abChess.getFEN();
        checkInfo.innerText = (abChess.isInCheck())
            ? 'Check !'
            : '';
        lastMoveInfo.innerText = 'Last move : ';
        turnInfo.innerText = (abChess.getActiveColor() === 'w')
            ? 'White to move.'
            : 'Black to move.';
    }
    startButton.addEventListener('click', function () {
        abChess.setFEN();
        updateInfo();
    });
    emptyButton.addEventListener('click', function () {
        abChess.setFEN('8/8/8/8/8/8/8/8');
        updateInfo();
    });
    flipButton.addEventListener('click', function () {
        abChess.flip();
    });
    container.addEventListener('drop', function () {
        updateInfo();
    });
    moveButton.addEventListener('click', function () {
        var inputMove = moveInput.value;
        var isLegal = abChess.isLegal(inputMove);
        if (isLegal) {
            updateInfo();
        }
    });
    abChess.draw();
    abChess.setFEN();
    updateInfo();
});
<|endoftext|>