/*--------------------------------------------------------------------------------------------*\
//
//  validation.js
//  -------------
//
//  v2.3, June 2007
//
//  This script provides generic validation for any web form. For a discussion and example usage 
//  of this script, go to http://www.benjaminkeen.com/software/js_validation
//
//  This script is written by Ben Keen with additional code contributed by Mihai Ionescu and 
//  Nathan Howard. It is free to distribute, to re-write - to do what ever you want with it.
//
//  Before using it, please read the following disclaimer.
//
//  THIS SOFTWARE IS PROVIDED ON AN "AS-IS" BASIS WITHOUT WARRANTY OF ANY KIND. BENJAMINKEEN.COM 
//  SPECIFICALLY DISCLAIMS ANY OTHER WARRANTY, EXPRESS OR IMPLIED, INCLUDING ANY WARRANTY OF 
//  MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL BENJAMINKEEN.COM BE 
//  LIABLE FOR ANY CONSEQUENTIAL, INDIRECT, SPECIAL OR INCIDENTAL DAMAGES, EVEN IF BENJAMINKEEN.COM 
//  HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH POTENTIAL LOSS OR DAMAGE. USER AGREES TO HOLD 
//  BENJAMINKEEN.COM HARMLESS FROM AND AGAINST ANY AND ALL CLAIMS, LOSSES, LIABILITIES AND EXPENSES.
//
//
//var rules = new Array(); // stores the validation rules
//
// standard form fields
//rules.push("required,user_name,This field is required.");
//rules.push("required,email,Please enter your email address.");
//rules.push("valid_email,email,Please enter a valid email address.");
//
// date fields
//rules.push("valid_date,any_date_month,any_date_day,any_date_year,any_date,Please enter a valid date.");
//rules.push("valid_date,later_date_month,later_date_day,later_date_year,later_date,Please enter an date later than today.");
//
// Numbers / alphanumeric fields
//rules.push("required,any_integer,Please enter an integer.");
//rules.push("digits_only,any_integer,This field may only contain digits.");
//rules.push("digits_only,number_range,This field may only contain digits.");
//rules.push("range=1-100,number_range,Please enter a number between 1 and 100.");
//rules.push("range>100,number_range_greater_than,Please enter a number greater than 100.");
//rules.push("range>=100,number_range_greater_than_or_equal,Please enter a number greater than or equal to 100.");
//rules.push("range<100,number_range_less_than,Please enter a number less than 100.");
//rules.push("range<=100,number_range_less_than_or_equal,Please enter a number less than or equal to 100.");
//rules.push("letters_only,letter_field,Please only enter letters (a-Z) in this field.");
//rules.push("required,alpha_field,Please enter an alphanumeric (0-9 a-Z) string.");
//rules.push("is_alpha,alpha_field,Please only enter alphanumeric characters (0-9 a-Z) in this field.");
//rules.push("custom_alpha,custom_alpha_field1,LLL-VVV,Please enter a string of form LLL-VVV - where L is an uppercase letter and V is an uppercase vowel.");
//rules.push("custom_alpha,custom_alpha_field2,DDxxx,Please enter a string of form DDxxx.");
//rules.push("custom_alpha,custom_alpha_field3,EEXX,Please enter a string of form EEXX.");
//rules.push("custom_alpha,custom_alpha_field4,VVvvllFF,Please enter a string of form VVvvllFF.");
//rules.push("custom_alpha,custom_alpha_field5,#XccccCCCC,Please enter a string of form #XccccCCCC.");
//rules.push("reg_exp,reg_exp_field1,^\\s*(red|orange|yellow|green|blue|indigo|violet|pink|white)\\s*$,Please enter your favourite colour in lowercase (e.g. \"red\" or \"blue\")");
//rules.push("required,reg_exp_field2,Please enter your favourite colour (e.g. \"red\" or \"blue\")");
//rules.push("reg_exp,reg_exp_field2,^\\s*(red|orange|yellow|green|blue|indigo|violet|pink|white)\\s*$,i,Please enter your favourite colour (e.g. \"red\" or \"blue\")");
//
// Length of field input
//rules.push("length=2,char_length,Please enter a value that is exactly two characters long.");
//rules.push("length=3-5,char_length_range,Please enter a value that is between 3 and 5 characters in length.");
//rules.push("length>5,char_length_greater_than,Please enter a value that is over 5 characters long.");
//rules.push("length>=5,char_length_greater_than_or_equal,Please enter a value that is at least 5 characters long.");
//rules.push("length<5,char_length_less_than,Please enter a value that is less than 5 characters long.");
//rules.push("length<=5,char_length_less_than_or_equal,Please enter a value that is less than or equal to 5 characters.");
//
// custom functions
//rules.push("function,my_custom_function");
//
// password fields
//rules.push("required,password,Please enter a password.");
//rules.push("same_as,password,password_2,Please ensure the passwords you enter are the same.");
//
// conditional (if-else) fields
//rules.push("required,gender,Please enter your gender.");
//rules.push("if:gender=male,required,male_question,Please enter the name of your favourite Care Bear.");
//rules.push("if:gender=female,required,female_question,Please indicate what max weight you can bench.");
//
//
//
//function my_custom_function() {
//  var prime_nums_str = "1|2|3|5|7|11|13|17|19|23|29|31|37|41|43|47|53|59|61|67|71|73|79|83|89|97";
//  var prime_numbers = prime_nums_str.split("|");
//  
//  var val = document.getElementById("prime_number").value;
//  
//  var is_valid_num = false;
//  for (i=0; i<prime_numbers.length; i++) {
//    if (prime_numbers[i] == val)
//      is_valid_num = true;
//  } 
//  
//  if (!is_valid_num) {
//    alertMessage(document.getElementById("prime_number"), "Please enter a valid prime number under 100.");
//  }
//
//  return is_valid_num;
//}
//
//<form action="" method="post" onsubmit="return validateFields(this, rules)">
//<input type="text" name="user_name" />
//</form>
\*--------------------------------------------------------------------------------------------*/


/*--------------------------------------------------------------------------------------------*\
  Function: validateFields()
  Purpose:  generic form field validation.
  Parameters: form  - the name of the form to validate
              rules - an array of the validation rules. Each rule is a string of the form:

   "[if:FIELDNAME=VALUE,]REQUIREMENT,fieldname[,fieldname2 [,fieldname3, date_flag]],error message"

              if:FIELDNAME=VALUE,   This allows us to only validate a field only if a fieldname 
                       FIELDNAME has a value VALUE. This option allows for nesting; i.e. you can 
                       have multiple if clauses, separated by a comma. They will be examined in the 
                       order in which they appear in the line.

              Valid REQUIREMENT strings are: 
                "required"     - field must be filled in
                "digits_only"  - field must contain digits only
                "is_alpha"     - field must only contain alphanumeric characters (0-9, a-Z)
                "custom_alpha" - field must be of the custom format specified.
                      fieldname:  the name of the field
                      fieldname2: a character or sequence of special characters. These characters are:
                          L   An uppercase Letter.          V   An uppercase Vowel.
                          l   A lowercase letter.           v   A lowercase vowel.
                          D   A letter (upper or lower).    F   A vowel (upper or lower).
                          C   An uppercase Consonant.       x   Any number, 0-9.
                          c   A lowercase consonant.        X   Any number, 1-9.
                          E   A consonant (upper or lower).
                "reg_exp"      - field must match the supplied regular expression.  
                      fieldname:  the name of the field
                      fieldname2: the regular expression
                      fieldname3: (optional) flags for the reg exp (like i for case insensitive
                "letters_only" - field must only contains letters (a-Z)

                "length=X"     - field has to be X characters long
                "length=X-Y"   - field has to be between X and Y (inclusive) characters long
                "length>X"     - field has to be greater than X characters long
                "length>=X"    - field has to be greater than or equal to X characters long
                "length<X"     - field has to be less than X characters long
                "length<=X"    - field has to be less than or equal to X characters long
                
                "valid_email"  - field has to be a valid email address
                "valid_date"   - field has to be a valid date
                      fieldname:  MONTH 
                      fieldname2: DAY 
                      fieldname3: YEAR
                      date_flag:  "later_date" / "any_date"
                "same_as"      - fieldname is the same as fieldname2 (for password comparison)

                "range=X-Y"    - field must be a number between the range of X and Y inclusive
                "range>X"      - field must be a number greater than X
                "range>=X"     - field must be a number greater than or equal to X
                "range<X"      - field must be a number less than X
                "range<=X"     - field must be a number less than or equal to X

  Comments:   With both digits_only, is_alpha, letters_only and valid_email options, if the empty 
              string is passed in it won't generate an error, thus allowing validation of 
              non-required fields. So, for example, if you want a field to be a valid email address, 
              provide validation for both "required" and "valid_email".
\*------------------------------------------------------------------------------------------------*/
function validateFields(form, rules)
{
  // loop through rules
  for (var i=0; i<rules.length; i++)
  {
    // split row into component parts 
    var row = rules[i].split(",");

    // while the row begins with "if:..." test the condition. If true, strip the
    // if:..., part and continue evaluating the rest of the line. Keep repeating 
    // this while the line begins with an if-condition. If it fails any of the 
    // conditions, don't bother validating the rest of the line.
    var satisfiesIfConditions = true;
    while (row[0].match("^if:"))
    {
      var condition = row[0];
      condition = condition.replace("if:", "");

      // check if it's a = or != test
      var comparison = "equal";
      var parts = new Array();
      if (condition.search("!=") != -1)
      {
        parts = condition.split("!=");
        comparison = "not_equal";
      }
      else
        parts = condition.split("=");
    
      var fieldToCheck = parts[0];
      var valueToCheck = parts[1];
      
      // find value of FIELDNAME for conditional check
      var fieldnameValue = "";
      if (form[fieldToCheck].type == undefined) // RADIO
      {
        for (var j=0; j<form[fieldToCheck].length; j++)
        {
          if (form[fieldToCheck][j].checked)
            fieldnameValue = form[fieldToCheck][j].value;
        }
      }
      // single checkbox      
      else if (form[fieldToCheck].type == "checkbox")
      {
        if (form[fieldToCheck].checked)
          fieldnameValue = form[parts[0]].value;
      }      
      // all other field types
      else
        fieldnameValue = form[parts[0]].value;

      // if the VALUE is NOT the same, we don't need to validate this field. Return.
      if (comparison == "equal" &&  fieldnameValue != valueToCheck)
      {
        satisfiesIfConditions = false;
        break;
      }
      else if (comparison == "not_equal" && fieldnameValue == valueToCheck)
      {
        satisfiesIfConditions = false;
        break;      
      }
      else
        row.shift();    // remove this if-condition from line, and continue validating line
    }

    if (!satisfiesIfConditions)
      continue;


    var requirement = row[0];
    var fieldName   = row[1];

    // depending on the validation test, store the incoming strings for use later...
    if (row.length == 6)        // valid_date
    {
      var fieldName2   = row[2];
      var fieldName3   = row[3];
      var date_flag    = row[4];
      var errorMessage = row[5];
    }
    else if (row.length == 5)     // reg_exp (WITH flags like g, i, m)
    {
      var fieldName2   = row[2];
      var fieldName3   = row[3];
      var errorMessage = row[4];
    }
    else if (row.length == 4)     // same_as, custom_alpha, reg_exp (without flags like g, i, m)
    {
      var fieldName2   = row[2];
      var errorMessage = row[3];
    }
    else
      var errorMessage = row[2];    // everything else!


    // if the requirement is "length...", rename requirement to "length" for switch statement
    if (requirement.match("^length"))
    {
      var lengthRequirements = requirement;
      requirement = "length";
    }

    // if the requirement is "range=...", rename requirement to "range" for switch statement
    if (requirement.match("^range"))
    {
      var rangeRequirements = requirement;
      requirement = "range";
    }


    // now, validate whatever is required of the field
    switch (requirement)
    {
      case "required":
     
        // if radio buttons or multiple checkboxes:
        if (form[fieldName].type == undefined)
        {
          var oneIsChecked = false;
          for (var j=0; j<form[fieldName].length; j++)
          {
            if (form[fieldName][j].checked)
              oneIsChecked = true;
          }
          if (!oneIsChecked)
          {
            alertMessage(form[fieldName], errorMessage);
            return false;           
          }
        }
        else if (form[fieldName].type == "select-multiple")
        {          
          var oneIsSelected = false;
          for (k=0; k<form[fieldName].length; k++)
          {
            if (form[fieldName][k].selected)
              oneIsSelected = true;
          }

          // if no options have been selected, or if there ARE no options in the multi-select 
          // dropdown, return false
          if (!oneIsSelected || form[fieldName].length == 0)
          {
            alertMessage(form[fieldName], errorMessage);
            return false;          
          }
        }
        // a single checkbox
        else if (form[fieldName].type == "checkbox")
        {
          if (!form[fieldName].checked)
          {
            alertMessage(form[fieldName], errorMessage);
            return false;           
          }
        }
        // otherwise, just perform ordinary "required" check.
        else if (!form[fieldName].value)
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }
        break;

      case "digits_only":       
        if (form[fieldName].value && form[fieldName].value.match(/\D/))
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }
        break;

      case "letters_only": 
        if (form[fieldName].value && form[fieldName].value.match(/[^a-zA-Z]/))
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }
        break;

      case "is_alpha": 
        if (form[fieldName].value && form[fieldName].value.match(/\W/))
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }
        break;

      case "custom_alpha":
        var conversion = {
          "L": "[A-Z]",
          "V": "[AEIOU]",
          "l": "[a-z]",
          "v": "[aeiou]",
          "D": "[a-zA-Z]",
          "F": "[aeiouAEIOU]",
          "C": "[BCDFGHJKLMNPQRSTVWXYZ]",
          "x": "[0-9]",
          "c": "[bcdfghjklmnpqrstvwxyz]",
          "X": "[1-9]",
          "E": "[bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ]"
            };

        var reg_exp_str = "";
        for (j=0; j<fieldName2.length; j++)
        {
          if (conversion[fieldName2.charAt(j)])
            reg_exp_str += conversion[fieldName2.charAt(j)];
          else
            reg_exp_str += fieldName2.charAt(j);
        }
        var reg_exp = new RegExp(reg_exp_str);

        if (form[fieldName].value && reg_exp.exec(form[fieldName].value) == null)
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }        
        break;

      case "reg_exp":
        var reg_exp_str = fieldName2;

        // rather crumby, but...
        if (row.length == 5)
          var reg_exp = new RegExp(reg_exp_str, fieldName3);
        else
          var reg_exp = new RegExp(reg_exp_str);

        if (form[fieldName].value && reg_exp.exec(form[fieldName].value) == null)
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }        
        break;

      case "length":
        comparison_rule = "";
        rule_string = "";

        // if-else order is important here: needs to check for >= before >
        if      (lengthRequirements.match(/length=/))
        { 
          comparison_rule = "equal"; 
          rule_string = lengthRequirements.replace("length=", ""); 
        }
        else if (lengthRequirements.match(/length>=/))
        {
          comparison_rule = "greater_than_or_equal"; 
          rule_string = lengthRequirements.replace("length>=", "");
        }
        else if (lengthRequirements.match(/length>/))
        {
          comparison_rule = "greater_than"; 
          rule_string = lengthRequirements.replace("length>", "");
        }
        else if (lengthRequirements.match(/length<=/))
        {
          comparison_rule = "less_than_or_equal"; 
          rule_string = lengthRequirements.replace("length<=", "");
        }        
        else if (lengthRequirements.match(/length</))
        {
          comparison_rule = "less_than"; 
          rule_string = lengthRequirements.replace("length<", "");
        }

        // now perform the appropriate validation
        switch (comparison_rule)
        {
          case "greater_than_or_equal":
            if (!(form[fieldName].value.length >= parseInt(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "greater_than":
            if (!(form[fieldName].value.length > parseInt(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "less_than_or_equal":
            if (!(form[fieldName].value.length <= parseInt(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "less_than":
            if (!(form[fieldName].value.length < parseInt(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "equal":
            var range_or_exact_number = rule_string.match(/[^_]+/);
            var fieldCount = range_or_exact_number[0].split("-");
    
            // if the user supplied two length fields, make sure the field is within that range
            if (fieldCount.length == 2)
            {
              if (form[fieldName].value.length < fieldCount[0] || form[fieldName].value.length > fieldCount[1])
              {
                alertMessage(form[fieldName], errorMessage);
                return false;
              }
            }
    
            // otherwise, check it's EXACTLY the size the user specified 
            else
            {
              if (form[fieldName].value.length != fieldCount[0])
              {
                alertMessage(form[fieldName], errorMessage);
                return false;
              }
            }     

            break;
        }
        break;

      // this is also true if field is empty [should be same for digits_only]
      case "valid_email":
        if (form[fieldName].value && !isValidEmail(form[fieldName].value))
        {
          alertMessage(form[fieldName], errorMessage);
          return false;         
        }
        break;

      case "valid_date":

        // this is written for future extensibility of isValidDate function to allow 
        // checking for dates BEFORE today, AFTER today, IS today and ANY day.
        var isLaterDate = false;
        if    (date_flag == "later_date")
          isLaterDate = true;
        else if (date_flag == "any_date")
          isLaterDate = false;

        if (!isValidDate(form[fieldName].value, form[fieldName2].value, form[fieldName3].value, isLaterDate))
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }
        break;

      case "same_as":
        if (form[fieldName].value != form[fieldName2].value)
        {
          alertMessage(form[fieldName], errorMessage);
          return false;
        }       
        break;

      case "range":
     
        comparison_rule = "";
        rule_string = "";

        // if-else order is important here: needs to check for >= before >
        if      (rangeRequirements.match(/range=/))
        { 
          comparison_rule = "equal";
          rule_string = rangeRequirements.replace("range=", ""); 
        }
        else if (rangeRequirements.match(/range>=/))
        {
          comparison_rule = "greater_than_or_equal";
          rule_string = rangeRequirements.replace("range>=", "");
        }
        else if (rangeRequirements.match(/range>/))
        {
          comparison_rule = "greater_than";
          rule_string = rangeRequirements.replace("range>", "");
        }
        else if (rangeRequirements.match(/range<=/))
        {
          comparison_rule = "less_than_or_equal";
          rule_string = rangeRequirements.replace("range<=", "");
        }        
        else if (rangeRequirements.match(/range</))
        {
          comparison_rule = "less_than";
          rule_string = rangeRequirements.replace("range<", "");
        }

        // now perform the appropriate validation
        switch (comparison_rule)
        {
          case "greater_than_or_equal":
            if (!(form[fieldName].value >= Number(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "greater_than":
            if (!(form[fieldName].value > Number(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "less_than_or_equal":
            if (!(form[fieldName].value <= Number(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "less_than":
            if (!(form[fieldName].value < Number(rule_string)))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;

          case "equal":
            var rangeValues = rule_string.split("-");
            
            // if the user supplied two length fields, make sure the field is within that range
            if ((form[fieldName].value < Number(rangeValues[0])) || (form[fieldName].value > Number(rangeValues[1])))
            {
              alertMessage(form[fieldName], errorMessage);
              return false;
            }
            break;
        }
        break;

      case "function":
        custom_function = fieldName;
        if (!(eval(custom_function + "()")))
          return false;
        break;

      default:
        alert("Unknown requirement flag in validateFields(): " + requirement);
        return false;
    }
  }
  
  return true;
}


/*--------------------------------------------------------------------------------------------*\
  Function: alertMessage()
  Purpose:  simple helper function which alerts a message, then focuses on and highlights 
            a particular field.
\*--------------------------------------------------------------------------------------------*/
function alertMessage(obj, message)
{ 
  var backgroundColor = "#F2F9FF";

  alert(message);

  // if "obj" is an array: it's a radio button. Focus on the first element.
  if (obj.type == undefined)
    obj[0].focus();
  else
  {
    obj.style.background = backgroundColor;
    obj.focus();
  }
  return false;
}


/*--------------------------------------------------------------------------------------------*\
  Function: isValidEmail
  Purpose:  tests a string is a valid email
\*--------------------------------------------------------------------------------------------*/
function isValidEmail(str)
{
  // trim starting / ending whitespace
  str = str.replace(/^\s*/, "");
  str = str.replace(/\s*$/, "");

  var at="@"
  var dot="."
  var lat=str.indexOf(at)
  var lstr=str.length
  var ldot=str.indexOf(dot)

  if (str.indexOf(at)==-1)
    return false
  
  if (str.indexOf(at)==-1 || str.indexOf(at)==0 || str.indexOf(at)==lstr)
    return false
  
  if (str.indexOf(dot)==-1 || str.indexOf(dot)==0 || str.indexOf(dot)==lstr)
    return false

  if (str.indexOf(at,(lat+1))!=-1)
    return false

  if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot)
    return false

  if (str.indexOf(dot,(lat+2))==-1)
    return false

  if (str.indexOf(" ")!=-1)
    return false

  return true;
}


// helper function to check to see if a string is empty
function isEmpty(str)
{  
  return ((str == null) || (str.length == 0));
}


/*--------------------------------------------------------------------------------------------*\
  Function: isWhitespace()
  Purpose:  Returns true if string parameter is empty or whitespace characters only.
\*--------------------------------------------------------------------------------------------*/
function isWhitespace(s)
{
  var i;

  // Is s empty?
  if (isEmpty(s)) return true;

  for (var i=0; i<s.length; i++)
  {   
    var c = s.charAt(i);
    if (whitespace.indexOf(c) == -1)
      return false;
  }

  return true;
}


/*----------------------------------------------------------------------------*\
  Function:   isValidDate()
  Purpose:    to check an incoming date is valid. If any of the date parameters  
              fail, it returns a string message denoting the problem.
  Parameters: month       - an integer between 1 and 12
              day         - an integer between 1 and 31 (depending on month)
              year        - a 4-digit integer value
              isLaterDate - a boolean value. If true, the function verifies the 
                            date being passed in is LATER than the current date.
\*----------------------------------------------------------------------------*/
function isValidDate(month, day, year, isLaterDate)
{
  // depending on the year, calculate the number of days in the month
  if (year % 4 == 0)      // LEAP YEAR 
    var daysInMonth = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
  else
    var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);


  // first, check the incoming month and year are valid. 
  if (!month || !day || !year)          return false;
  if (1 > month || month > 12)          return false;
  if (year < 0)                         return false;
  if (1 > day || day > daysInMonth[month-1]) return false;


  // if required, verify the incoming date is LATER than the current date.
  if (isLaterDate)
  {
    // get current date
    var today = new Date();
    var currMonth = today.getMonth() + 1; // since returns 0-11
    var currDay   = today.getDate();
    var currYear  = today.getFullYear();

    // zero-pad today's month & day
    if (String(currMonth).length == 1)  currMonth = "0" + currMonth;
    if (String(currDay).length == 1)  currDay   = "0" + currDay;    
    currDate = String(currYear) + String(currMonth) + String(currDay);
    
    // zero-pad incoming month & day
    if (String(month).length == 1)  month = "0" + month;
    if (String(day).length == 1)  day   = "0" + day;
    incomingDate = String(year) + String(month) + String(day);

    if (Number(currDate) > Number(incomingDate))
      return false;
  }
  
  return true;
}
