(function (window) { if (!window.GoogleAnalytics) { window.GoogleAnalytics = {}; } GoogleAnalytics.init = init; function init(i, s, o, g, r, a, m) { i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () { (i[r].q = i[r].q || []).push(arguments); }, i[r].l = 1 * new Date(); a = s.createElement(o), m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m); } })(window);/* * password.gen.js * This file contains shared functions for password restriction validation and * password generation between CAST and web client */ /* * Function to return random sequence of 8th int values. */ function getSequence() { var sequence = new Array(); sequence[0] = 0; sequence[1] = 1; sequence[2] = 2; sequence[3] = 3; sequence[4] = 4; sequence[5] = 5; sequence[6] = 6; sequence[7] = 7; var rank = sequence.length; var ind; for (var i = 0; i < rank; i++) { do { ind = parseInt(Math.random() * rank); } while ((ind == i)); var t = sequence[i]; sequence[i] = sequence[ind]; sequence[ind] = t; } return sequence; } /* * Generates new trader password */ function GeneratePassword() { var symbolsNumber = new Array(); symbolsNumber[0] = 2; symbolsNumber[1] = 2; symbolsNumber[2] = 2; symbolsNumber[3] = 2; var sequence = getSequence(); var table = new Array(); table[0] = "abcdefghijkmnopqrstuvwxyz"; table[1] = "ABCDEFGHIJKLMNPQRSTUVWXYZ"; table[2] = "23456789"; table[3] = "!@#$_"; var tableElementsCount = table.length; var result = " "; var symNum = 0; for (var i = 0; i < tableElementsCount; i++) { for (var j = 0; j < Number(symbolsNumber[i]); j++) { var rndValue = parseInt(Math.random() * table[i].length); var rndSymbol = table[i].charAt(rndValue); var firstSubstring = result.substring(0, sequence[symNum]); var secondSubstring = result.substring(sequence[symNum] + 1, result.length); result = firstSubstring + rndSymbol + secondSubstring; symNum++; } } return result; } /* * Validates trader password according given restriction */ function DoValidatePassword(password, restriction) { var regexp = new RegExp(restriction); return regexp.test(password); } /* * Validates trader password according given restrictions and return * list of failed restrictions. * \param restrictions should be an array of objects with * RegExp and Description string fields */ function DoValidatePasswordEx(password, restrictions) { var errors = new Array(); for (var i = 0; i < restrictions.length; i++) { if (!DoValidatePassword(password, restrictions[i].RegExp)) { var ind = errors.length; errors[ind] = restrictions[i].Description; } } return errors; } /* * Validates trader password according given restrictions (list of xml nodes) and returns * error message containing list of failed restrictions. * \param password should be a string * \param restrictionsNodes should be an array of xml nodes with * \param captionText is optional paramater - header text of error message (harcoded by default). * ValidationRegexpJScript and Description attributes */ function DoValidatePasswordExXML(password, restrictionsNodes, captionText) { var restrictions = new Array(); var currentRestriction = new Object(); captionText = ((captionText == null) || (captionText == undefined))? "Password doesn't meet following restrictions" : captionText; for (var i = 0; i < restrictionsNodes.length; i++) { var currentRestriction = new Object(); currentRestriction.RegExp = restrictionsNodes[i].getAttribute("ValidationRegexpJScript"); currentRestriction.Description = restrictionsNodes[i].getAttribute("Description"); restrictions[i] = currentRestriction; } var errors = DoValidatePasswordEx(password, restrictions); var errorMessage = null; if (errors.length > 0) { errorMessage = captionText + ":\n"; for (var i = 0; i < errors.length; i++) { errorMessage += errors[i] + ",\n"; } errorMessage = errorMessage.substring(0, errorMessage.length-2) + "." } return errorMessage; }// This file contains calls of server-side translate() function and should be used // in files that include Translation.inc (or Global.inc in CAST). function decimalSeparatorLocal() { var value = ""; if (value == "") { value = "."; } return value; } function decimalDigitCountLocal() { var value = new Number(""); if (isNaN(value)) { value = 2; } return value; } function groupSeparatorLocal() { return ""; } function groupDigitCountLocal() { return ""; } function dateFormatLocal() { return ""; } function time12FormatLocal() { var value = ""; return (value == "true"); } function is12HourFormat(time) { /// /// Gets a value indicating whether 12-hour format is used. /// /// Time value to check for 12-hour format. /// A value indicating whether 12-hour format shall be used. var value = trim(time); return (/(a|p)m$/i).test(value); } var SynStrategyDecimalDigits = 8; /* Converts float to string according to local CAST settings. Parameters: value: Number for conversion. decimalDigitCount: Optional. Number of digits after the decimal point. If decimalDigitCount is not supplied or undefined, function assumes the value is decimalDigitCountLocal(). Result: Returns a string representing a number for local CAST settings. */ function formatFloatLocal(value, decimalDigitCount) { var MAX_DECIMAL_DIGIT_COUNT = 12; var number = new Number(value); if (isNaN(number)) { number = 0; } decimalDigitCount = new Number(decimalDigitCount); if (isNaN(decimalDigitCount)) { decimalDigitCount = decimalDigitCountLocal(); } else if (decimalDigitCount >= MAX_DECIMAL_DIGIT_COUNT) { // Try to find decimal separator position. var absValue = Math.abs(number); var strValue = toDecimal(absValue).toString(); var separatorIndex = strValue.indexOf("."); if (separatorIndex < 0) { // Just to make sure for case when local decimal separator is present. separatorIndex = strValue.indexOf(decimalSeparatorLocal()); } if (separatorIndex > 0) { // Get real decimal digits count. var decimalCount = strValue.length - separatorIndex - 1; decimalDigitCount = Math.max(decimalCount, decimalDigitCountLocal()); } else { // When number without decimal separator. decimalDigitCount = 0; } } return roundToNDigits(number, decimalDigitCount); } /* Inserts the group delimiters into a positive integer number. intNumberString - a string containing only digits 0-9 groupSeparator - a string containing what will be between the groups digitsGrouping - a string which determines how the groups will be split. Tests: insertGroupDelimiters("0" , ",", "3;0") == "0" insertGroupDelimiters("123" , ",", "3;0") == "123" insertGroupDelimiters("123456" , ",", "3;0") == "123,456" insertGroupDelimiters("123456789", " ", "3;0") == "123 456 789" */ function insertGroupDelimiters(intNumberString, groupSeparator, digitsGrouping) { var result = ""; if (groupSeparator != undefined && groupSeparator.length > 0 && digitsGrouping != undefined && digitsGrouping.length > 0) { var arr = digitsGrouping.split(";"); if (arr.length > 0) { var intNumberStr = intNumberString; var s = ""; var i = 0; var count = 3; while (intNumberStr.length > 0) { if (i < arr.length) { if (Number(arr[i]) > 0) { count = Number(arr[i]); i++; } } else { count = intNumberStr.length; } s = intNumberStr.slice(-count) + (s != "" ? groupSeparator + s : ""); intNumberStr = intNumberStr.substring(0, intNumberStr.length - count); } result = s; } } if (result == "") { result = intNumberString; } return result; } /* Parses float from a string according to local CAST settings. Parameters: value: String that represents a number. decimalDigitCount: Optional. Number of digits after the decimal point. If decimalDigitCount is not supplied or undefined, function assumes the value is decimalDigitCountLocal(). If value has more digits after the decimal point then decimalDigitCount, result will be NaN. Result: Returns a number that was read from value. If value cannot be parsed returns NaN. */ function unformatFloatLocal(value, decimalDigitCount) { decimalDigitCount = new Number(decimalDigitCount); if (isNaN(decimalDigitCount)) { decimalDigitCount = decimalDigitCountLocal(); } return unformatFloat(value, decimalSeparatorLocal(), decimalDigitCount, groupSeparatorLocal(), groupDigitCountLocal()); } /* Parses float from a string according to supplied parameters. Parameters: value: String that represents a number. decimalSeparator: Optional. Decimal symbol. If decimalSeparator is not supplied or undefined, function assumes that the value should not have digits after decimal point. decimalDigitCount: Optional. Number of digits after the decimal point. If decimalDigitCount is not supplied or undefined, function assumes the value is 0. If value has more digits after the decimal point then decimalDigitCount, result will be NaN. groupSeparator: Optional. Digit grouping symbol. If groupSeparator is not supplied or undefined, function assumes that the value should not have digit grouping symbols. digitsGrouping: Optional. Sizes for each group of digits to the left of the decimal (for instance: "3;0"). If digitsGrouping is not supplied or undefined or 0, function assumes that the value should not have digit grouping symbols. Result: Returns a number that was read from value. If value cannot be parsed returns NaN. */ function unformatFloat(value, decimalSeparator, decimalDigitCount, groupSeparator, digitsGrouping) { if ((groupSeparator != undefined) && (groupSeparator.length > 0) && (digitsGrouping != undefined) && (digitsGrouping.length > 0)) { value = value.replace(new RegExp("\\"+groupSeparator, "g"), ""); } // Defect 195636238 Allow expressions like ".5", "-.5", "5.": if (value == "-" + decimalSeparator) { return NaN; // We do not extend "-." to "-0.0" } if (value.length > 1) // We do not extend values containing 0 or 1 chars. { if (value.charAt(0) == decimalSeparator) { value = "0" + value; } else if (value.charAt(0) == '-' && value.charAt(1) == decimalSeparator) { value = "-0" + value.slice(1); } if (value.charAt(value.length-1) == decimalSeparator) { value += "0"; } } var groupDigitExp = "\\d+"; var decimalExp = ""; if ((decimalSeparator != undefined) && (decimalSeparator.length > 0) && !isNaN(decimalDigitCount) && (decimalDigitCount > 0)) { decimalExp = "(\\"+decimalSeparator+"\\d{1," + decimalDigitCount + "}|\\d?)"; } var rx = new RegExp("^(\\-)?" + groupDigitExp + decimalExp + "$"); //the replace part is to trim insignificant leading/trailing spaces if (!rx.test(value.replace(/^\s*|\s*$/,""))) { return NaN; } value = value.replace(new RegExp("\\"+decimalSeparator, "g"), "."); return parseFloat(value); } /* Converts date to string according to local CAST settings. Parameters: value: Date for conversion. Result: Returns a string representing a date for local CAST settings. */ function formatDateLocal(value) { return formatDate(value, dateFormatLocal()); } /* Converts date to string according in "MM/dd/yyyy" format. Parameters: value: Date for conversion. Result: Returns a string representing a date in "MM/dd/yyyy" format. */ function formatDateUSA(value) { return formatDate(value, "MM/dd/yyyy"); } /* Converts date to string according to supplied parameters. Parameters: value: Date for conversion. format: String containing a format for date conversion. It should contain following parts: yyyy - for 4-digit year value MM - month value with lead zero; M - month value dd - day value with lead zero; d - day value Result: Returns a string representing a date. Remarks: Warning! This code is copy-pasted to Master\Accounts\Statements\AccountSummary.cli.js.asp. Please, keep it identical. */ function formatDate(value, format) { var date = new Date(value); if (isNaN(date)) { return ""; } var result = format.replace("yyyy", date.getFullYear()).replace("yy", date.getFullYear()); result = result.replace("MM", padl(String(date.getMonth() + 1), 2, "0")); result = result.replace("M", String(date.getMonth() + 1)); result = result.replace("dd", padl(String(date.getDate()), 2, "0")); result = result.replace("d", String(date.getDate())); return result; } /* Parses date from a string according to local CAST settings. Parameters: value: String that represents a date. Result: Returns a date that was read from value. If value cannot be parsed returns 'undefined'. */ function parseDateLocal(value) { return parseDate(value, dateFormatLocal()); } /* Assign time part to a given date. Parameters: datepart: date that will be used to generate result. timepart: time that will be used to generate result. Result: Returns a date that was combined from date of datepart and time of timepart. */ function concatDateAndTime(datepart, timepart) { if (datepart != undefined && timepart != undefined) { return new Date(datepart.getFullYear(), datepart.getMonth(), datepart.getDate(), timepart.getHours(), timepart.getMinutes(), timepart.getSeconds()); } return undefined; } /* Parses date from a string according to supplied format. Parameters: value: String that represents a date. format: String containing a format for date conversion. It should contain following parts: yyyy - for 4-digit year value MM - month value with lead zero; M - month value dd - day value with lead zero; d - day value Result: Returns a date that was read from value. If value cannot be parsed returns 'undefined'. */ function parseDate(value, format) { var exp = format.replace("dd", "(\\##{2})").replace("d", "(\\##{1,2})").replace("##", "d"); exp = exp.replace("MM", "(\\d{2})").replace("M", "(\\d{1,2})"); exp = exp.replace("yyyy", "(\\d{4})").replace("yy", "(\\d{4})"); var rx = new RegExp("^" + exp + "$"); if (!rx.test(value)) { return undefined; } var indexYear = format.indexOf("yyyy"); if (indexYear < 0) indexYear = format.indexOf("yy"); var indexMonth = format.indexOf("M"); var indexDay = format.indexOf("d"); var indexFirst; var indexSecond; if (indexYear == Math.min(indexYear, indexMonth, indexDay)) { indexYear = 1; indexFirst = 2; indexSecond = 3; } else if (indexYear == Math.max(indexYear, indexMonth, indexDay)) { indexYear = 3; indexFirst = 1; indexSecond = 2; } else { indexYear = 2; indexFirst = 1; indexSecond = 3; } if (indexMonth < indexDay) { indexMonth = indexFirst; indexDay = indexSecond; } else { indexMonth = indexSecond; indexDay = indexFirst; } var arr = rx.exec(value); var year = new Number(arr[indexYear]); var month = new Number(arr[indexMonth]) - 1; var day = new Number(arr[indexDay]); var result = new Date(year, month, day); if (year != result.getFullYear() || month != result.getMonth() || day != result.getDate()) { result = undefined; } return result; } /* Returns UTC date-time value from supplied local date-time. Remarks: Warning! This code is copy-pasted to Master\Accounts\Statements\AccountSummary.cli.js.asp. Please, keep it identical. */ function convertLocalToUTCDate(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); } /* Returns local date-time value from supplied UTC date-time. */ function convertUTCtoLocalDate(date) { return new Date(formatDateTimeUSA(date, true) + " UTC"); } /* Converts time to string according to local CAST settings. Parameters: value: time for conversion. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. Result: Returns a string representing a time for local CAST settings. */ function formatTimeLocal(time, withSeconds) { return formatTime(time, time12FormatLocal(), withSeconds); } /* Converts time to string according to supplied parameters. Parameters: value: time for conversion. use12HRFormat: Boolean. If true then use 12-hour format. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. Result: Returns a string representing a time. Remarks: Warning! This code is copy-pasted to Master\Accounts\Statements\AccountSummary.cli.js.asp. Please, keep it identical. */ function formatTime(time, use12HRFormat, withSeconds) { var date = new Date(time); if (isNaN(date)) { return ""; } var iHours = date.getHours(); var str12 = ""; if (use12HRFormat == true) { if (iHours < 13) { str12 = (iHours == 12 ? " PM" : " AM"); //correct for midnight & noon if (iHours == 0) { iHours = 12; } } else { iHours -= 12; str12 = " PM"; } } return (padl(String(iHours), 2, "0") + ":" + padl(String(date.getMinutes()), 2, "0") + (withSeconds == true ? ":" + padl(String(date.getSeconds()), 2, "0") : "")) + str12; } function parseTimeLocal(time, withSeconds, checkFor12HourFormat) { /// /// Parses time from a string according to local CAST settings. /// /// A value representing time. /// A value indicating whether seconds will be presented in a result. /// A value indicating whether time shall be checked for 12-hour format. /// Parsed time. var use12HourFormat = checkFor12HourFormat ? is12HourFormat(time) : time12FormatLocal(); return parseTime(time, use12HourFormat, withSeconds); } /* Parses time from a string according to supplied format. Parameters: value: String that represents a time. use12HRFormat: Boolean. If true then use 12-hour format. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. Result: Returns a time that was read from value. If value cannot be parsed returns 'undefined'. */ function parseTime(time, use12HRFormat, withSeconds) { var exp; if (use12HRFormat == true) { // format HH:MM AM or HH:MM PM (if no seconds expected) or HH:MM:SS AM or HH:MM:SS PM (if seconds expected) // 1<=HH <=12, 0<=MM<=59 // example: 1:29 AM, 03:54 PM, 12:59:36 AM exp = "([1-9]|1[0-2]|0[1-9]){1}(:[0-5][0-9]){1}" + (withSeconds == true ? "(:([0-5][0-9])){1}" : "") + " ([aApP][mM]){1}"; } else { // format HH:MM (if no seconds expected) or HH:MM:SS (if seconds expected) // 0<=HH<=23, 0<=MM<=59 // example: 00:01, 01:29, 15:54, 23:59:36 exp = "([0-9]|1[0-9]|0[0-9]|2[0-3]){1}(:[0-5][0-9]){1}" + (withSeconds == true ? "(:([0-5][0-9])){1}" : ""); } var rx = new RegExp("^" + exp + "$"); if (!rx.test(time)) { return undefined; } var hourSeparatorIndex = time.indexOf(":"); var hour = new Number(time.substr(0, hourSeparatorIndex)); var minute = new Number(time.substr(hourSeparatorIndex + 1, 2)); var second = 0; var dpPos = hourSeparatorIndex + 4; if (withSeconds == true) { second = new Number(time.substr(dpPos, 2)); dpPos += 3; } if (use12HRFormat == true) { var isAM = (time.substr(dpPos, 2).toUpperCase() == "AM"); if (isAM && hour == 12) { hour = 0; } else if (!isAM && hour < 12) { hour += 12; } } return new Date(0, 0, 0, hour, minute, second) } /* Parses supplied date and time strings according to local CAST settings and returns datetime value. Parameters: dateString: String that represents a date. timeString: String that represents a time. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. checkFor12HourFormat: Optional. Boolean. A value indicating whether time shall be checked for 12-hour format. Result: Returns datetime value. */ function parseDatetimeFromDateAndTime(dateString, timeString, withSeconds, checkFor12HourFormat) { var date = parseDateLocal(dateString); var time = parseTimeLocal(timeString, withSeconds, checkFor12HourFormat); var result; if (date != undefined && time != undefined) { result = new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes(), time.getSeconds()); } return result; } /* Converts date and time to string according to local CAST settings. Parameters: value: Date (with time) for conversion. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. Result: Returns a string representing a date with time for local CAST settings. */ function formatDateTimeLocal(value, withSeconds) { return formatDateLocal(value) + " " + formatTimeLocal(value, withSeconds); } /* Converts date and time to string in "MM/dd/yyyy HH:mm" format. Parameters: value: Date (with time) for conversion. withSeconds: Optional. Boolean. If true then seconds will be presented in a result. Default: false. Result: Returns a string representing a date with time in "MM/dd/yyyy HH:mm" format. */ function formatDateTimeUSA(value, withSeconds) { return formatDateUSA(value) + " " + formatTime(value, false, withSeconds); } /* Returns a string from str, padded with characters to a specified length on the right sides. str: A string for padding. len: Specifies the total number of characters in the expression after it is padded. ch: Specifies the value to use for padding. */ function padr(str, len, ch) { var lenStr = str.length; for (var inpIndex = lenStr; inpIndex < len; inpIndex++) { str += ch; } return str; } /* Returns a string from str, padded with characters to a specified length on the left sides. str: A string for padding. len: Specifies the total number of characters in the expression after it is padded. ch: Specifies the value to use for padding. Remarks: Warning! This code is copy-pasted to Master\Accounts\Statements\AccountSummary.cli.js.asp. Please, keep it identical. */ function padl(str, len, ch) { var lenStr = str.length; for (var inpIndex = lenStr; inpIndex < len; inpIndex++) { str = ch + str; } return str; } /* Removes the last symbol from a given string. str - the string to truncate. Must not be empty string. */ function removeLastChar(str) { return str.substring(0, str.length-1); } /* Checks value in textInput control for matching local CAST currency amount format. Parameters: textInput: Input control object. message: Optional. Custom message that will be displayed in case of wrong value. minValue: Optional. If it's supplied, there will be additional control to minimal value. maxValue: Optional. If it's supplied, there will be additional control to maximal value. Result: Returns true if textInput value matches local currency amount format conditions. Format textInput value according to standards. */ function checkUserInputCurrency(textInput, message, minValue, maxValue) { return checkUserInputFloat(textInput, true, undefined, message, minValue, maxValue); } /* Checks value in textInput control for matching CAST price format. Parameters: textInput: Input control object. isEmptyValueDisallowed: Optional. Boolean. If true then supposed value is not empty. errorMessage: Optional. Custom message that will be displayed in case of wrong value. minValue: Optional. If it's supplied, there will be additional control to minimal value. maxValue: Optional. If it's supplied, there will be additional control to maximal value. Result: Returns true if textInput value matches price format conditions. Format textInput value according to standards. */ function checkUserInputPrice(textInput, isEmptyValueDisallowed, errorMessage, minValue, maxValue) { var number = checkFloatValue(textInput, 0, minValue, maxValue); if (isNaN(number)) { var value = trim(textInput.value); if ((value.length == 0) && (!isEmptyValueDisallowed)) { return true; } if (errorMessage == undefined) { errorMessage = "Please enter a valid value."; } alert (errorMessage); textInput.select(); if (textInput.disabled != true) textInput.focus(); return false; } textInput.value = formatDisplayPriceLocal(number); return true; } function checkFloatValue(textInput, decimalDigitCount, minValue, maxValue) { var number; if (textInput == undefined) { number = NaN; } else { var value = trim(textInput.value); if (value.length == 0) { number = NaN; } else { number = unformatFloatLocal(value, decimalDigitCount); minValue = new Number(minValue); maxValue = new Number(maxValue); if ((!isNaN(minValue) && (number < minValue)) || (!isNaN(maxValue) && (number > maxValue))) { number = NaN; } } } return number; } /* Checks value in textInput control for matching local CAST float format. Parameters: textInput: Input control object. isEmptyValueAllowed: Optional. Boolean. If true then supposed value is not empty. decimalDigitCount: Optional. Integer. Maximal number of digits after decimal point. errorMessage: Optional. Custom message that will be displayed in case of wrong value. minValue: Optional. If it's supplied, there will be additional control to minimal value. maxValue: Optional. If it's supplied, there will be additional control to maximal value. Result: Returns true if textInput value matches local float format conditions. Format textInput value according to standards. */ function checkUserInputFloat(textInput, isEmptyValueDisallowed, decimalDigitCount, errorMessage, minValue, maxValue) { var number = checkFloatValue(textInput, decimalDigitCount, minValue, maxValue); if (isNaN(number)) { var value = trim(textInput.value); if ((value.length == 0) && (!isEmptyValueDisallowed)) { return true; } if (errorMessage == undefined) { errorMessage = "Please enter a valid value."; } alert (errorMessage); textInput.select(); if (textInput.disabled != true) textInput.focus(); return false; } textInput.value = formatFloatLocal(number, decimalDigitCount); return true; } /* Checks value in textInput control for matching local CAST date format. Parameters: textInput: Input control object. required: Optional. Boolean. If true then supposed value is not empty. message: Optional. Custom message that will be displayed in case of wrong value. Result: Returns true if textInput value matches local date format conditions. Format textInput value according to standards. */ function checkUserInputDate(textInput, required, message) { var value = trim(textInput.value); var date; if (value.length == 0) { if (required == true) { date = undefined; } else { return true; } } else { date = parseDateLocal(value); } if (date == undefined) { if (message == undefined) { message = "Please enter a valid value."; } alert (message); textInput.select(); if (textInput.disabled != true) textInput.focus(); return false; } textInput.value = formatDateLocal(date); return true; } function checkUserInputTime(textInput, required, message, withSeconds, checkFor12HourFormat) { /// /// Checks value in textInput control for matching local CAST time format. /// /// Input control object. /// A value indicating whether value supposed to be not empty. /// Custom message that will be displayed in case of wrong value. /// A value indicating whether seconds will be presented in a result. /// A value indicating whether time shall be checked for 12-hour format. /// A value indicating whether input contains valid time. var value = trim(textInput.value); var use12HourFormat; var date; if (value.length == 0) { if (required == true) { date = undefined; } else { return true; } } else { use12HourFormat = checkFor12HourFormat ? is12HourFormat(value) : time12FormatLocal(); date = parseTime(value, use12HourFormat, withSeconds); } if (date == undefined) { if (message == undefined) { message = "Please enter a valid value."; } alert (message); textInput.select(); if (textInput.disabled != true) textInput.focus(); return false; } textInput.value = formatTime(date, use12HourFormat, withSeconds) return true; } /* * Returns formatted string (replaces all "{i}" by passed argument in template string) * Warning: it is a duplicate of function from Translation.inc - please, apply the same * changes for both functions for correct work */ function formatString(template) { for(var i = 1; i < arguments.length; i++) { template = template.replace(new RegExp("\\{" + (i - 1) + "\\}", "g"), arguments[i]); } return template; } /* Converts price to string according to CAST standard - integer without group separator Parameters: value: number for conversion. Result: Returns a string representing a price. */ function formatDisplayPriceLocal(value) { var intValue = Math.floor(value); return intValue.toString(); } /* Converts the float number to string, mathematically rounding to N digits after decimal separator. Tests (assuming US locale is used): roundToNDigits(1e21 , 2) == "1,000,000,000,000,000,000,000.00" roundToNDigits(12.3456 , 2) == "12.35" roundToNDigits(12.344 , 2) == "12.34" roundToNDigits(1234 , 3) == "1,234.000" roundToNDigits(1.1 , 0) == "1" roundToNDigits(0.1 , 1) == "0.1" roundToNDigits(0.01 , 2) == "0.01" roundToNDigits(0.001 , 3) == "0.001" roundToNDigits(0.0001 , 4) == "0.0001" roundToNDigits(0.00001 , 5) == "0.00001" roundToNDigits(0.000001 , 6) == "0.000001" roundToNDigits(0.0000001 , 7) == "0.0000001" roundToNDigits(0.00000001 , 8) == "0.00000001" roundToNDigits(1e-10 ,10) == "0.0000000001" roundToNDigits(1.00000001 , 8) == "1.00000001" roundToNDigits(0.001 , 2) == "0.00" roundToNDigits(0 , 8) == "0.00000000" roundToNDigits(-1e21 , 2) == "-1,000,000,000,000,000,000,000.00" roundToNDigits(-12.3456 , 2) == "-12.35" roundToNDigits(-12.344 , 2) == "-12.34" roundToNDigits(-1234 , 3) == "-1,234.000" roundToNDigits(-1.1 , 0) == "-1" roundToNDigits(-0.1 , 1) == "-0.1" roundToNDigits(-0.01 , 2) == "-0.01" roundToNDigits(-0.001 , 3) == "-0.001" roundToNDigits(-0.0001 , 4) == "-0.0001" roundToNDigits(-0.00001 , 5) == "-0.00001" roundToNDigits(-0.000001 , 6) == "-0.000001" roundToNDigits(-0.0000001 , 7) == "-0.0000001" roundToNDigits(-0.00000001, 8) == "-0.00000001" roundToNDigits(-1.00000001, 8) == "-1.00000001" roundToNDigits(-1e-10 ,10) == "-0.0000000001" roundToNDigits(-0.001 , 2) == "0.00" Warning: do not pass string data to this function! Remember that XML attributes are always string values. */ function roundToNDigits(number, n) { // We multiply by ten's power to insert the delimiters (such as '.') afterwards: var bigNumber = Math.round(number * Math.pow(10, n)); // This variable is true if the rounded number is negative // (i.e. if we want to represent -0.001 number with 2-digits precision, this must be FALSE): var isNegative = bigNumber < 0; bigNumber = Math.abs(bigNumber); // In case when we have 0.007 * 1000 = "7", we want it to become "0007" for further point insertion, // so pad it with zeroes: var sBigNumber = padl(toDecimal(bigNumber), n+1, '0'); return (isNegative ? "-" : "") + insertGroupDelimiters(sBigNumber.substring(0,sBigNumber.length-n), groupSeparatorLocal(), groupDigitCountLocal()) + (n == 0 ? "" : decimalSeparatorLocal()) + sBigNumber.substring(sBigNumber.length-n, sBigNumber.length); } function toDecimal(number) { /// Converts given number to string without using of scientific notation. /// Number for conversation. /// A string representation of the specified number. /// /// JS use scientific notation if the number is Math.abs(number) >= 1e+21 or Math.abs(number) <= 1e-7). /// This function parses scientific notation and converts number to string. /// var power = Math.abs(getPower(number)); if (!power) { return number.toString(); } var sign = (number < 0) ? "-" : ""; number = Math.abs(number); if (number < 1.0) { // Case for small numbers. // To minimize precision error we do a calculation in a loop. for (var i = 0; i < power - 1; ++i) { number *= 10; } var str = number.toString().substring(2); return sign + "0." + padl(str, str.length + power - 1, "0"); } // Case for big numbers. power -= 19; // To minimize precision error we do a calculation in a loop. for (var i = 0; i < power; ++i) { number /= 10; } var str = number.toString(); return sign + padr(str, str.length + power, "0"); } function getPower(number) { /// /// Gets number power if string representation of number use scientific notation, /// otherwise - returns NaN. /// var str = number.toString().toLowerCase(); var powerIndex = str.indexOf("e"); if (powerIndex < 0) { return NaN; } var power = parseInt(str.substring(powerIndex + 1)); if (!power) { return NaN; } return power; } /* Converts Correct price to a string. Parameters: value: number for conversion. Result: Returns a string representing a price. */ function formatCorrectPriceLocal(value) { // Requirement 194125936: // Synthetic spread prices shown on CAST Order Details page in Correct format // should be localized. If the localization settings don't allow showing all // meaning digits, CAST should show up to 8 meaning digits after the decimal separator. var number = new Number(value); if (isNaN(number)) { number = 0; } var simplyRoundedValue = roundToNDigits(number, decimalDigitCountLocal()); var smartlyRoundedValue = roundToNDigits(number, SynStrategyDecimalDigits); // we remove all insignificant zeros: while (smartlyRoundedValue.length > 0 && smartlyRoundedValue.charAt(smartlyRoundedValue.length-1) == '0') { smartlyRoundedValue = removeLastChar(smartlyRoundedValue); } // the decimal separator is also removed, if the number appears to be integer: if (smartlyRoundedValue.length > 0 && smartlyRoundedValue.charAt(smartlyRoundedValue.length-1) == decimalSeparatorLocal()) { smartlyRoundedValue = removeLastChar(smartlyRoundedValue); } // choose the most precise of two: return smartlyRoundedValue.length < simplyRoundedValue.length ? simplyRoundedValue : smartlyRoundedValue; } // Returns the localized sum with the $ sign. // If sum is negative, then the - sign goes before $ sign. function formatWithDollarSign(sum) { var result = ""; var num = parseFloat(sum); if (num < 0) { num = -num; result = "-"; } return result + "$" + formatFloatLocal(num); }/* json2.js 2012-10-08 Public Domain. See http://www.JSON.org/js.html */ if (typeof JSON !== "object") { JSON = {} } (function () { function f(n) { return n < 10 ? "0" + n : n } if (typeof Date.prototype.toJSON !== "function") { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z" : null }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { return this.valueOf() } } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { "\b": "\\b", "\t": "\\t", "\n": "\\n", "\f": "\\f", "\r": "\\r", '"': '\\"', "\\": "\\\\" }, rep; function quote(string) { escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === "string" ? c : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) }) + '"' : '"' + string + '"' } function str(key, holder) { var i, k, v, length, mind = gap, partial, value = holder[key]; if (value && typeof value === "object" && typeof value.toJSON === "function") { value = value.toJSON(key) } if (typeof rep === "function") { value = rep.call(holder, key, value) } switch (typeof value) { case "string": return quote(value); case "number": return isFinite(value) ? String(value) : "null"; case "boolean": case "null": return String(value); case "object": if (!value) { return "null" } gap += indent; partial = []; if (Object.prototype.toString.apply(value) === "[object Array]") { length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || "null" } v = partial.length === 0 ? "[]" : gap ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]" : "[" + partial.join(",") + "]"; gap = mind; return v } if (rep && typeof rep === "object") { length = rep.length; for (i = 0; i < length; i += 1) { if (typeof rep[i] === "string") { k = rep[i]; v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v) } } } } else { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ": " : ":") + v) } } } } v = partial.length === 0 ? "{}" : gap ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}" : "{" + partial.join(",") + "}"; gap = mind; return v } } if (typeof JSON.stringify !== "function") { JSON.stringify = function (value, replacer, space) { var i; gap = ""; indent = ""; if (typeof space === "number") { for (i = 0; i < space; i += 1) { indent += " " } } else { if (typeof space === "string") { indent = space } } rep = replacer; if (replacer && typeof replacer !== "function" && (typeof replacer !== "object" || typeof replacer.length !== "number")) { throw new Error("JSON.stringify") } return str("", { "": value }) } } if (typeof JSON.parse !== "function") { JSON.parse = function (text, reviver) { var j; function walk(holder, key) { var k, v, value = holder[key]; if (value && typeof value === "object") { for (k in value) { if (Object.prototype.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v } else { delete value[k] } } } } return reviver.call(holder, key, value) } text = String(text); cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4) }) } if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) { j = eval("(" + text + ")"); return typeof reviver === "function" ? walk({ "": j }, "") : j } throw new SyntaxError("JSON.parse") } } }()); Object.extend = function(destination, source) { /// Object.extend(destination, source) -> Object /// The object to receive the new properties. /// The object whose properties will be duplicated. /// https://github.com/sstephenson/prototype/blob/ecacc02/src/prototype/lang/object.js#L88 for (var property in source) { destination[property] = source[property]; } return destination; }; String.prototype.format = function() { ///Similar to .Net String.Format() method. ///Can be used like: "...{0}...".format(parameter1) var s = this; var i = arguments.length; while (i--) { s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]); } return s; }; if (!String.prototype.includes) { String.prototype.includes = function() { 'use strict'; return String.prototype.indexOf.apply(this, arguments) !== -1; }; } if (!String.prototype.trim) { String.prototype.trim = function () { /// Removes whitespace from both ends of the string. /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim return this.replace(/^\s+|\s+$/g, ''); }; } if (!Array.prototype.filter) { Array.prototype.filter = function(predicate) { /// Filter current array and return new array with filtered items. /// Predicate to test each object of the array. /// New array with filtered items. var len = this.length; var result = []; for (var i = 0; i < len; i++) { var val = this[i]; // in case predicate mutates this if (predicate(val, i)) { result.push(val); } } return result; }; } if (!Array.prototype.forEach) { Array.prototype.forEach = function(callback) { /// Iterates current array and call given function for each array item. /// Function that will be called for each array item. var len = this.length; for (var i = 0; i < len; i++) { var val = this[i]; // in case callback mutates this callback(val, i); } }; } Array.prototype.distinct = function () { /// Returns distinct elements from a sequence. /// Array containing distinct elements from a sequence. var result = []; for(var i = 0, l = this.length; i < l; ++i) { if (!result.contains(this[i])) { result.push(this[i]); } } return result; }; Array.prototype.contains = function(obj) { /// This function is static and can be invoked without creating an instance of the object. /// The object to find in the array. /// True if the specified object exists as an element in the array; otherwise, false. var i = this.length; while (i--) { if (this[i] === obj) { return true; } } return false; }; if (!Array.prototype.map) { Array.prototype.map = function(callback) { /// Projects each element of the current array into a new array. /// A transform function to apply to each element. var result = []; var len = this.length; for (var i = 0; i < len; i++) { var val = this[i]; // in case callback mutates this result.push(callback(val, i)); } return result; }; } // Production steps of ECMA-262, Edition 5, 15.4.4.14 // Reference: http://es5.github.io/#x15.4.4.14 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { var k; // 1. Let O be the result of calling ToObject passing // the this value as the argument. if (this == null) { throw new TypeError('"this" is null or not defined'); } var O = Object(this); // 2. Let lenValue be the result of calling the Get // internal method of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If len is 0, return -1. if (len === 0) { return -1; } // 5. If argument fromIndex was passed let n be // ToInteger(fromIndex); else let n be 0. var n = +fromIndex || 0; if (Math.abs(n) === Infinity) { n = 0; } // 6. If n >= len, return -1. if (n >= len) { return -1; } // 7. If n >= 0, then Let k be n. // 8. Else, n<0, Let k be len - abs(n). // If k is less than 0, then let k be 0. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); // 9. Repeat, while k < len while (k < len) { // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the // HasProperty internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then // i. Let elementK be the result of calling the Get // internal method of O with the argument ToString(k). // ii. Let same be the result of applying the // Strict Equality Comparison Algorithm to // searchElement and elementK. // iii. If same is true, return k. if (k in O && O[k] === searchElement) { return k; } k++; } return -1; }; } // The find() method returns a value in the array, if an element in the array // satisfies the provided testing function. Otherwise undefined is returned. if (!Array.prototype.find) { Array.prototype.find = function(predicate) { if (this === null) { throw new TypeError('Array.prototype.find called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return value; } } return undefined; }; } // The findIndex() method returns an index in the array, if an element in // the array satisfies the provided testing function. Otherwise -1 is returned. if (!Array.prototype.findIndex) { Array.prototype.findIndex = function(predicate) { if (this === null) { throw new TypeError('Array.prototype.findIndex called on null or undefined'); } if (typeof predicate !== 'function') { throw new TypeError('predicate must be a function'); } var list = Object(this); var length = list.length >>> 0; var thisArg = arguments[1]; var value; for (var i = 0; i < length; i++) { value = list[i]; if (predicate.call(thisArg, value, i, list)) { return i; } } return -1; }; } // Production steps of ECMA-262, Edition 6, 22.1.2.1 // Reference: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from if (!Array.from) { Array.from = (function () { var toStr = Object.prototype.toString; var isCallable = function (fn) { return typeof fn === 'function' || toStr.call(fn) === '[object Function]'; }; var toInteger = function (value) { var number = Number(value); if (isNaN(number)) { return 0; } if (number === 0 || !isFinite(number)) { return number; } return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); }; var maxSafeInteger = Math.pow(2, 53) - 1; var toLength = function (value) { var len = toInteger(value); return Math.min(Math.max(len, 0), maxSafeInteger); }; // The length property of the from method is 1. return function from(arrayLike/*, mapFn, thisArg */) { // 1. Let C be the this value. var C = this; // 2. Let items be ToObject(arrayLike). var items = Object(arrayLike); // 3. ReturnIfAbrupt(items). if (arrayLike == null) { throw new TypeError("Array.from requires an array-like object - not null or undefined"); } // 4. If mapfn is undefined, then let mapping be false. var mapFn = arguments.length > 1 ? arguments[1] : void undefined; var T; if (typeof mapFn !== 'undefined') { // 5. else // 5. a If IsCallable(mapfn) is false, throw a TypeError exception. if (!isCallable(mapFn)) { throw new TypeError('Array.from: when provided, the second argument must be a function'); } // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 2) { T = arguments[2]; } } // 10. Let lenValue be Get(items, "length"). // 11. Let len be ToLength(lenValue). var len = toLength(items.length); // 13. If IsConstructor(C) is true, then // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len. // 14. a. Else, Let A be ArrayCreate(len). var A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Let k be 0. var k = 0; // 17. Repeat, while k < len… (also steps a - h) var kValue; while (k < len) { kValue = items[k]; if (mapFn) { A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); } else { A[k] = kValue; } k += 1; } // 18. Let putStatus be Put(A, "length", len, true). A.length = len; // 20. Return A. return A; }; }()); } // The every() method tests whether all elements in the array pass the test // implemented by the provided function. if (!Array.prototype.every) { Array.prototype.every = function(callbackfn, thisArg) { 'use strict'; var T, k; if (this == null) { throw new TypeError('this is null or not defined'); } // 1. Let O be the result of calling ToObject passing the this // value as the argument. var O = Object(this); // 2. Let lenValue be the result of calling the Get internal method // of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If IsCallable(callbackfn) is false, throw a TypeError exception. if (typeof callbackfn !== 'function') { throw new TypeError(); } // 5. If thisArg was supplied, let T be thisArg; else let T be undefined. if (arguments.length > 1) { T = thisArg; } // 6. Let k be 0. k = 0; // 7. Repeat, while k < len while (k < len) { var kValue; // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the HasProperty internal // method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then if (k in O) { // i. Let kValue be the result of calling the Get internal method // of O with argument Pk. kValue = O[k]; // ii. Let testResult be the result of calling the Call internal method // of callbackfn with T as the this value and argument list // containing kValue, k, and O. var testResult = callbackfn.call(T, kValue, k, O); // iii. If ToBoolean(testResult) is false, return false. if (!testResult) { return false; } } k++; } return true; }; } // The some() method tests whether some element in the array passes the // test implemented by the provided function. if (!Array.prototype.some) { Array.prototype.some = function(fun/*, thisArg*/) { 'use strict'; if (this == null) { throw new TypeError('Array.prototype.some called on null or undefined'); } if (typeof fun !== 'function') { throw new TypeError(); } var t = Object(this); var len = t.length >>> 0; var thisArg = arguments.length >= 2 ? arguments[1] : void 0; for (var i = 0; i < len; i++) { if (i in t && fun.call(thisArg, t[i], i, t)) { return true; } } return false; }; } function trim(str) { var refront = /^[ ]+/; var reback = /[ ]+$/; return new String (str).replace(refront,"").replace(reback,""); } function rtrim(str) { var reback = /[ ]+$/; return new String (str).replace(reback,""); } function ltrim(str) { var refront = /^[ ]+/; return new String (str).replace(refront,""); } Array.prototype.toXml = function(xmlNode) { /// Serializes array objects to xml. /// String represented main xml node or XMLDOM instance. /// Xml node. if (typeof xmlNode == "string") { var xml = new ActiveXObject("Microsoft.XMLDOM"); return this.toXml(xml.createElement(xmlNode)); } else { var len = this.length; for (var i = 0; i < len; i++) { var element = this[i]; if (element.toXml) { element.toXml(xmlNode); } } } return xmlNode; }; Array.prototype.first = Array.prototype.find; String.isNullOrEmpty = function(value) { return ((value== null) || (value == "")); }; String.prototype.upperCaseFirst = function() { /// Uppercase first letter. return this.charAt(0).toUpperCase() + this.slice(1); }; if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { ///Determines whether the beginning of the string matches a specified string. position = position || 0; return this.lastIndexOf(searchString, position) === position; }; } Boolean.toInt = function(value) { /// Represent booleans as "true"/"false" strings in new code. See Boolean.toString/fromString. /// /// Converts boolean value to int. /// /// Boolean to convert. /// int value. return value ? 1 : 0; }; Boolean.fromString = function (value, allowNull) { /// Converts string to boolean. /// String to convert. /// /// Determines whether value can be null. /// /// boolean value. if (typeof value != "string" && !(value instanceof String)) { throw new TypeError(); } switch(value.toString()) { case "true": return true; case "false": return false; case "null": if (allowNull) { return null; } throw new RangeError(); default: throw new RangeError(); } }; Boolean.toString = function(value) { /// Converts boolean to string. /// Boolean to convert. /// string value. if (typeof value != "boolean" && !(value instanceof Boolean)) { throw new TypeError(); } return value.toString(); }; function isInteger(value) { /// Checks whether the given value is an integer value. /// True if the given value is integer, otherwise - false. return (isNumber(value) && value % 1 === 0) } function isNumber(value) { /// Checks whether the given value is a number. /// True if the given value is number, otherwise - false. return (!isNaN(parseFloat(value)) && isFinite(value)); } function parseBoolean(value) { /// Use Boolean.fromString for new code. /// Parses boolean value from the given string. /// String value. /// true if the given string is "true", otherwise - false. return value == "true"; } function boolToIntString(value) { /// Converts given boolean value to string "0" or "1". /// Boolean value. /// Returns "1" if given boolean value is true; otherwise - "0". return value ? "1" : "0"; } function normalizeXmlQuotes(xmlString) { /// Replaces double quotes in attributes to single ones. /// Xml with single quotes. return xmlString.replace(/"/g, "\'"); } // Returns true, if value & bit == bit. function bitAnd(value, bit) { return (value & bit) == bit; } function htmlEncode(string) { // Similar to CastCommon htmlEncode() function. // String to encode. // HTML-encoded string. return String(string) .replace(/&/g, "&") .replace(/"/g, """) .replace(/'/g, "'") .replace(//g, ">"); } (function() { // Create namespace for Cast objects. if (!window.Cast) { window.Cast = {}; } var cast = window.Cast; window.DECLARE = function(namespaceName, className, thisClass, baseClass) { /// Declare class in the specified namespace. /// Javascript namespace name (e.g. "Cast.Controls") where new class will be added. /// Class name (e.g. "Checkbox"). /// Class to declare. /// Base class. cast.getNamespace(namespaceName)[className] = thisClass; if (baseClass) { EXTEND(thisClass, baseClass); } }; window.EXTEND = function(thisClass, baseClass) { /// Makes class inherited from base class. /// Class to extend. /// Base class. var F = function() { }; F.prototype = baseClass.prototype; thisClass.prototype = new F(); thisClass.prototype.constructor = thisClass; }; cast.getNamespace = function(namespaceName) { /// Creates JavaScript namespace if not exists and returns namespace object. /// Namespace name (e.g. 'Cast.Controls'). /// JavaScript namespace object. var names = namespaceName.split("."); var current = window; for (var i = 0; i < names.length; ++i) { var name = names[i]; if (current[name] == undefined) { current[name] = {}; } current = current[name]; } return current; }; })(); (function() { var Logging = Cast.getNamespace("Cast.Logging"); var ErrorHandling = Cast.getNamespace("Cast.ErrorHandling"); ErrorHandling.redirectToErrorScreen = function() { /// Redirects user to error screen. window.location = Cast.Configuration.UnexpectedErrorUrl; }; ErrorHandling.onErrorHandler = function(message, url, lineNumber) { /// JavaScript error handler. /// JavaScript error message. /// Resource url where a JavaScript error was occured. /// Line number where a JavaScript error was occured. /// Returns false to let browser to show a default error dialog. Logging.logException({ message: message, fileName: url, lineNumber: lineNumber }); }; Logging.logException = function(e, messagePrefix) { /// Logs JavaScript exception. /// Exception to log. var errorInfo = { pageUrl: document.URL, message: (messagePrefix || '') + e.message, url: e.fileName || document.URL, lineNumber: e.lineNumber }; try { console.error(e); } catch (exception) { // Can't handle problems with console.error. } try { // Post data. var xhr = new XMLHttpRequest(); xhr.open("POST", Cast.Configuration.LoggerUrl, true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.setRequestHeader("Accept", "application/json"); xhr.setRequestHeader("__RequestVerificationToken", getCSRFtoken()); xhr.send(getFormUrlEncodedData(errorInfo)); } catch (exception) { // If logging failed we can't handle it. } }; Logging.logErrorMessage = function(message) { /// Logs error message. /// Message to log. Logging.logException({ message: message }); }; function getFormUrlEncodedData(obj) { var args = []; for (var name in obj) { var value = obj[name]; if (obj.hasOwnProperty(name) && typeof value != "undefined") { args.push(encodeURIComponent(name) + "=" + encodeURIComponent(value)); } } return args.join("&"); } function getCSRFtoken() { // If you are changing this method, make sure that similar method `addTokenToRequestHeaders` in RequestManager.js file is working. // RequestVerificationToken hidden input is injected in html pages from PageLayout.html. var token = $("[name=__RequestVerificationToken]").val(); if (token != null) { return token; } if (Cast.TopWindow && Cast.TopWindow.masthead && Cast.TopWindow.masthead.document && Cast.TopWindow.masthead.document.getElementById("CSRFtoken")) { // CSRFtoken hidden input is injected in masthead.asp page. var csrfToken = Cast.TopWindow.masthead.document.getElementById("CSRFtoken").value; if (csrfToken != null) { return csrfToken; } } if (window.document.getElementById("CSRFtoken")) { // CSRFtoken hidden input is injected in logon.asp page. var csrfToken = window.document.getElementById("CSRFtoken").value; if (csrfToken != null) { return csrfToken; } } return null; } })(); (function() { var PageState = Cast.getNamespace("Cast.PageState"); Object.extend(PageState, { // Page-related modifiable states. NO_LOCK_REQUIRED: new State("NO_LOCK_REQUIRED", true), // User-related modifiable states. LOCK_TAKEN: new State("LOCK_TAKEN", true), // Entity-related readonly states. ENTITY_REMOVED: new State("ENTITY_REMOVED"), ACCOUNT_ACTIVE_MIGRATION: new State("ACCOUNT_ACTIVE_MIGRATION"), // User-related readonly states. LOCKED_BY_ANOTHER_USER: new State("LOCKED_BY_ANOTHER_USER"), LOCK_EXPIRED: new State("LOCK_EXPIRED"), NO_MODIFY_PERMISSION: new State("NO_MODIFY_PERMISSION"), // General readonly states. READONLY: new State("READONLY"), // Default state. INVALID_LOCK: new State("INVALID_LOCK") }); var currentState = PageState.NO_LOCK_REQUIRED; PageState.getCurrent = function() { return currentState; }; PageState.setCurrent = function(state) { currentState = state; }; PageState.parseFromTtl = function(ttl) { if (ttl > 0) { return PageState.LOCK_TAKEN; } switch(ttl) { case -11: return PageState.NO_LOCK_REQUIRED; case -10: return PageState.READONLY; case -3: return PageState.ACCOUNT_ACTIVE_MIGRATION; case -2: return PageState.NO_MODIFY_PERMISSION; case -1: return PageState.LOCKED_BY_ANOTHER_USER; } // Invalid permission or lock was requested. return PageState.INVALID_LOCK; }; function State(name, isModifiable) { this.name = name; this._isModifiable = isModifiable; } State.prototype.isModifiable = function() { return this._isModifiable; }; State.prototype.isReadonly = function() { return !this.isModifiable(); }; })(); (function () { Cast.PageStateView = Cast.getNamespace("Cast.PageStateView"); var pageExpirationTimer = null; Cast.PageStateView.initialize = function(doTranslation, disableElementsOnReadonlyPage) { /// Initializes page state and shows message in page status bar. /// Indicates whether page requires translation. /// Indicates whether readonly page shouldn't be disabled automatically. // Clear previous timer. window.clearTimeout(pageExpirationTimer); // If page don't have SLOL then it don't require lock at all. var state = Cast.PageState.NO_LOCK_REQUIRED; var lockTime; var lockUserId; // Parse SLOL if it exists. if (window.SLOL && window.SLOL.ttl != "") { var ttl = parseInt(window.SLOL.ttl, 10); state = Cast.PageState.parseFromTtl(ttl); if (state == Cast.PageState.LOCK_TAKEN) { lockTime = ttl * 1000; } if (state == Cast.PageState.LOCKED_BY_ANOTHER_USER) { lockUserId = window.SLOL.lockUserId; } } // Save lock state to global object. Cast.PageState.setCurrent(state); // Update user interface. setStatusBarText(getStatusBarText(doTranslation, state, lockTime, lockUserId)); if (state == Cast.PageState.ACCOUNT_ACTIVE_MIGRATION) { // For account migration we also need to mention it in title. var title = "{0}" .format(doTranslation ? "(in migration)" : "(in migration)"); appendFrameTitleHtml(title); } // For readonly states page is disabled at load. if (state.isReadonly()) { disablePage(disableElementsOnReadonlyPage); return; } // For pages with taken lock we disable page and update user interface right after expiration. if (state == Cast.PageState.LOCK_TAKEN) { pageExpirationTimer = window.setTimeout(function() { state = Cast.PageState.LOCK_EXPIRED; Cast.PageState.setCurrent(state); disablePage(true); setStatusBarText(getStatusBarText(doTranslation, state)); }, lockTime); } }; function setStatusBarText(text) { if (!window.statusBar) { return; } window.statusBar.innerText = text; } function appendFrameTitleHtml(html) { if (!window.xmlContainer) { return; } var frameTitle = window.xmlContainer.getElementsByTagName(Cast.OldSchoolPage ? "span" : "h1")[0]; if (!frameTitle) { return; } frameTitle.innerHTML += html; } function getStatusBarText(doTranslation, state, lockTime, lockUserId) { if (state == Cast.PageState.LOCK_TAKEN) { var text = doTranslation ? "Page Expires At: " : "Page Expires At: "; var expiration = new Date(new Date().valueOf() + lockTime); return text + formatDateTimeLocal(expiration, true) + "."; } if (state == Cast.PageState.LOCK_EXPIRED) { return doTranslation ? "Page has expired." : "Page has expired."; } if (state == Cast.PageState.NO_MODIFY_PERMISSION) { return doTranslation ? "You don't have write access to this page." : "You don't have write access to this page."; } if (state == Cast.PageState.LOCKED_BY_ANOTHER_USER) { if (!String.isNullOrEmpty(lockUserId)) { return (doTranslation ? "Page is locked by another user (User ID = {0})." : "Page is locked by another user (User ID = {0})." ).format(lockUserId); } return doTranslation ? "Page is locked by another user." : "Page is locked by another user."; } if (state == Cast.PageState.ACCOUNT_ACTIVE_MIGRATION) { return doTranslation ? "Account has active migration." : "Account has active migration."; } return ""; } function disablePage(disablePageControls) { try { // Disable save, remove and restore buttons. document.getElementById("saveButton").disabled = true; if (document.getElementById("removeButton")) { document.getElementById("removeButton").disabled = true; } // Disable all controls on page if it was requested (some pages disable controls by themselves in template). // Not all pages inherit Shared/Page.js, so we need undefined check. var page = Cast.contentObject; var disableOnExpire = (page == null || page.disableOnExpire || page.disableOnExpire === undefined); if (disablePageControls && disableOnExpire) { disableControlsHierarchy(xmlContainer); } // Raise 'pageExpired' event if we can. if (Cast.raiseEvent) { Cast.raiseEvent(Cast.events.pageExpired); } } catch (e){} } })(); var KeyCode = { ENTER: 13, ESCAPE: 27 }; var INSTRUMENT_TYPE_GROUP = { FUTURES: 1, OPTIONS: 2 }; // Use this enum only in exceptional cases // due to we try to avoid using hardcoded system type identifiers in code. var AUTHENTICATION_SYSTEM_TYPE = { INTERNAL_GW : 1, CQG_OTP: 5 }; function getControllerActionUrl(domain, controller, action) { /// Gets controllers action url. /// Controller's domain. /// Controller name. /// Controller's action. return ("/{0}/{1}/{2}.mvc/{3}").format("CAST", domain, controller, action); } (function() { Cast.OldSchoolPage = typeof Cast.OldSchoolPage == "undefined" ? true : Cast.OldSchoolPage; Cast.PageConfig = { questionLoseChanges: true } // Basic configuration is different on non-mvc and mvc pages. // Configuration for non-mvc pages is set here, CastMain.cshtml handles it for mvc pages. if (Cast.OldSchoolPage) { Cast.Configuration = { RootUrl: "/CAST/", LoggerUrl: getControllerActionUrl("Common", "Log", "LogJavaScriptError"), UnexpectedErrorUrl: getControllerActionUrl("Common", "Exception", "UnexpectedError") }; } // Common configuration is always set here. Object.extend(Cast.Configuration, { IsBootstrapLoaded: !!(window.jQuery && window.jQuery.fn.affix) }); })(); (function () { Cast.Url = Cast.getNamespace("Cast.Url"); Cast.Url.content = function(path) { /// Converts a virtual (relative) path to an application absolute path. return path.replace(/^~/, Cast.Configuration.RootUrl); }; })(); (function () { if (!Cast.TopWindow) { Cast.TopWindow = window.parent.Cast.TopWindow; } })(); var loadError = 0; var SearchWindow; var GoogleAnalyticsTrackingId = 'G-829N0K2W2N'; var remove = "Remove"; var restore = "Restore"; var removeEN = "Remove"; var restoreEN = "Restore"; // Trader's Billing Options. var BillingOption = { Default: "0", Transactional: "1", FixedRate: "2" }; var USER_TYPE = { CAST_USER : 0, TRADER : 1 }; if (GoogleAnalyticsTrackingId != '') { GoogleAnalytics.init(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga'); } if (!window.onerror) { window.onerror = function(message, url, lineNumber) { /// JavaScript error handler /// JavaScript error message. /// Content url where a JavaScript error was occured. /// File line number where a JavaScript error was occured. /// Returns false to let browser to show a default error dialog. /// This function should be synchronized with the similar function in CastMain.aspx. Cast.ErrorHandling.onErrorHandler(message, url, lineNumber); // Let browser to show a default error dialog. return false; }; } function globalInits() { initGoogleAnalytics(); // ANY CHANGES in this function should be mirrored to .NET pages: // 1. FCM\BackOfficeConfig.aspx. // 2. Cast.Common\CASTPage.cs. document.body.onkeydown = function anonymous() { if(event.keyCode!=17 && event.ctrlKey) { return processCTRLKeys(event.keyCode); } }; if (false) { SearchWindow = window.opener.parent.parent.searchFrame; } else { SearchWindow = window.parent.parent.searchFrame; } SearchWindow.resetSettings(); if (window.doSearchSetup != null) { doSearchSetup(); } } function initGoogleAnalytics() { if (GoogleAnalyticsTrackingId == '') { return; } ga('create', GoogleAnalyticsTrackingId, 'auto'); // Add pages to google analytics. The documentation can be viewed https://developers.google.com/analytics/devguides/collection/analyticsjs/pages ga('send', { 'hitType': 'pageview', // Pageview hits can be sent using the send command and specifying a hitType of pageview 'title': window.location.href, // The title of the page (e.g. homepage) 'location': window.location.href, // URL of the page being tracked. 'page': window.location.pathname + window.location.search // The path portion of a URL. This value should start with a slash (/) character. }); } function getSearchFieldValue(key) { /// Gets value for specified key from selected row. try { return SearchWindow.getSelectedXML() .selectSingleNode("Context/Field[@Key='{0}']/@Value".format(key)) .value; } catch(e) { return null; } } function processCTRLKeys(chr) { event.cancelBubble = true; switch (chr) { case 83: // CTRL-s try { // Move focus to button to complete all blur/change events. saveButton.focus(); saveButton.click(); } catch(e){} return false; case 82: try { // Move focus to button to complete all blur/change events. refreshButton.focus(); refreshButton.click(); } catch(e){} return false; default: event.cancelBubble = false; return true; } } function retrieveHtml(url) { /// Retrieves the html document by specified url. /// Document url. var xhr = new XMLHttpRequest(); xhr.open("GET", url, false); xhr.send(null); var requestResult = parseXhrStatus(xhr); if (!requestResult.success) { alert("Error: " + requestResult.message); return null; } return xhr.responseText; } function retriveAndParseHtml(url) { /// Retrieves and parses HTML from specified url and parses it into jQuery. /// Url to laod HTML from. /// HTML wrapped jQuery. var templatesHtml = retrieveHtml(url); return $.parseHTML(templatesHtml, null, true); } function startDownloadFile(url) { /// Starts file downloading. /// File url. window.location = url; } function postAndRetrieveXML(xmlMessage, url, message, errorHandler, isEncoded) { /// Posts the xmlMessage to a specified url. /// Xml message. /// Url where xmlMessage will be sent. /// Message to show after processing xmlMessage. /// Delegate to handle the error condition(false if common handling is required). /// Indicates whether xmlMessage is already encoded. /// Error messages are not translated in this function, being technically complicated for average user. xmlMessage = transformToXMLFriendlyFormat(xmlMessage, isEncoded); if (xmlMessage == null) { return null; } var errDesc = ""; var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); url = Cast.Url.content(url); xmlHttp.open("POST", url, false); var topCast = null; if (Cast && Cast.TopWindow) { topCast = Cast; } else { topCast = (window.top || {}).Cast; } if (topCast && topCast.TopWindow && topCast.TopWindow.masthead && topCast.TopWindow.masthead.document && topCast.TopWindow.masthead.document.getElementById("CSRFtoken")) { csrfToken = topCast.TopWindow.masthead.document.getElementById("CSRFtoken").value; xmlHttp.setRequestHeader("CAST-CSRF-Value", csrfToken); } xmlHttp.send(xmlMessage); var requestResult = parseXhrStatus(xmlHttp); if (!requestResult.success) { var error = "Error: " + requestResult.message; alert(error); Cast.Logging.logErrorMessage(error); return null; } var errorNode = xmlHttp.responseXML.selectSingleNode("//Error"); if (errorNode) { var handled = false; if (errorHandler != undefined) { handled = errorHandler(errorNode); } if (!handled) { var userScope = getUserScope(); var clientMessage = errorNode.selectSingleNode("//@ClientMessage").value; if (userScope == 1) { clientMessage += "\n"; clientMessage += "Press OK for more details."; if (confirm(clientMessage)) { var errNumber = errorNode.selectSingleNode("//@Number").value; errDesc = errorNode.selectSingleNode("//@Description").value; var errPage = errorNode.selectSingleNode("//@Page").value; alert("Number = " + errNumber + "\n" + "Description = " + errDesc + "\n" + "Page = " + errPage + "\n"); } } else { alert (clientMessage); } return null; } } if (message) { try { statusBar.innerText = message; } catch (e){}; } var response = xmlHttp.responseXML; if (response.xml.length == 0) { return null; } var warningAttribute = response.selectSingleNode("Root/@WarningMessage"); if (warningAttribute) { alert(warningAttribute.value); } return response; } function parseXhrStatus(xhr) { /// Parses XmlHttpRequest send operation status. /// XmlHttpRequest object. var result = { success : false, message : "" }; switch (xhr.status) { case 666: window.parent.parent.location.href = "/CAST/logon/Logon.asp"; return; case 100: result.message="The request can be continued."; break; case 101: result.message="The server has switched protocols in an upgrade header."; break; case 200: result.message="The request completed successfully."; result.success = true; break; case 201: result.message="The request has been fulfilled and resulted in the creation of a new resource."; result.success = true; break; case 202: result.message="The request has been accepted for processing, but the processing has not been completed."; break; case 203: result.message="The returned meta information in the entity-header is not the definitive set available from the origin server."; break; case 204: result.message="The server has fulfilled the request, but there is no new information to send back."; break; case 205: result.message="The request has been completed, and the client program should reset the document view that caused the request to be sent to allow the user to easily initiate another input action."; break; case 206: result.message="The server has fulfilled the partial GET request for the resource."; break; case 300: result.message="The server couldn't decide what to return."; break; case 301: result.message="The requested resource has been assigned to a new permanent URI (Uniform Resource Identifier), and any future references to this resource should be done using one of the returned URIs."; break; case 302: result.message="The requested resource resides temporarily under a different URI (Uniform Resource Identifier)."; break; case 303: result.message="The response to the request can be found under a different URI (Uniform Resource Identifier) and should be retrieved using a GET method on that resource."; break; case 304: result.message="The requested resource has not been modified."; break; case 305: result.message="The requested resource must be accessed through the proxy given by the location field."; break; case 307: result.message="The redirected request keeps the same verb. HTTP/1.1 behavior."; break; case 400: result.message="The request could not be processed by the server due to invalid syntax."; break; case 401: result.message="The requested resource requires user authentication."; break; case 402: result.message="Not currently implemented in the HTTP protocol."; break; case 403: result.message="The server understood the request, but is refusing to fulfill it."; break; case 404: result.message="The server has not found anything matching the requested URI (Uniform Resource Identifier)."; break; case 405: result.message="The method used is not allowed."; break; case 406: result.message="No responses acceptable to the client were found."; break; case 407: result.message="Proxy authentication required."; break; case 408: result.message="The server timed out waiting for the request."; break; case 409: result.message="The request could not be completed due to a conflict with the current state of the resource. The user should resubmit with more information."; break; case 410: result.message="The requested resource is no longer available at the server, and no forwarding address is known."; break; case 411: result.message="The server refuses to accept the request without a defined content length."; break; case 412: result.message="The precondition given in one or more of the request header fields evaluated to false when it was tested on the server."; break; case 413: result.message="The server is refusing to process a request because the request entity is larger than the server is willing or able to process."; break; case 414: result.message="The server is refusing to service the request because the request URI (Uniform Resource Identifier) is longer than the server is willing to interpret."; break; case 415: result.message="The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method."; break; case 449: result.message="The request should be retried after doing the appropriate action."; break; case 500: result.message="The server encountered an unexpected condition that prevented it from fulfilling the request."; break; case 501: result.message="The server does not support the functionality required to fulfill the request."; break; case 502: result.message="The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request."; break; case 503: result.message="The service is temporarily overloaded."; break; case 504: result.message="The request was timed out waiting for a gateway."; break; case 505: result.message="The server does not support, or refuses to support, the HTTP protocol version that was used in the request message."; break; default: result.message="An unknown error (" + xhr.status + ") occurred at the server. Please retry your request."; } return result; } function transformToXMLFriendlyFormat(data, isEncoded) { if (checkNonASCII(data)) { return null; } if (!isEncoded) { var regamp = /&/g; data = data.replace(regamp, "&"); } var tempDom = new ActiveXObject("Microsoft.XMLDOM"); tempDom.loadXML(data); if (tempDom.xml.length == 0) { alert("Some characters are not valid for CAST data.\nFor example you cannot use the less than (<) or single quote (') symbols."); return null; } return data; } function checkNonASCII(text) { for (var l = 0; l < text.length; l++) { if (text.charCodeAt(l) >= 128) { alert ("Some international characters are disallowed for CAST data." + formatString("\nThe character {0} is invalid.", text.charAt(l))); return true; } } return false; } function getXSLDocument(URL) { try { URL = Cast.Url.content(URL); var XSL = new ActiveXObject("Microsoft.XMLDOM"); XSL.async = false; XSL.load (URL); if (XSL.parseError.errorCode != 0) { throw (new Error (0, "Error loading XSL stylesheet")); } return XSL; } catch (e) { alert ("An error occurred while rendering the page.\nPlease refresh your browser (F5)."); return false; } } function renderGeneric(XSLObj, xmlString, optString, optPrefix) { if (xmlString == null) { xmlString = ""; } var newHTML = ""; if (XSLObj != null) { var XMLObj = new ActiveXObject("Microsoft.XMLDOM"); XMLObj.loadXML (xmlString); newHTML += XMLObj.transformNode(XSLObj); } if (optPrefix != null && optPrefix != undefined) { newHTML += "" + optPrefix + "

"; } if (optString == null) { newHTML += ""; newHTML += "

"; newHTML += "Nothing is currently selected.  "; newHTML += "Please select a row from the search results above.
" newHTML += "If the Search frame is closed, click on Search to open it.

"; newHTML += "If there are no search results, or if the results from a previous search are grayed out:

"; newHTML += "    - Enter a search term in the 'Search for' box
"; newHTML += "    - Select a category from the 'by' box
"; newHTML += "    - Click the 'Search' button.
"; } else { newHTML += optString; } try { refreshButton.style.display="none"; } catch(e){} try { saveButton.style.display="none"; } catch(e){} try { removeButton.style.display="none"; } catch(e){} return newHTML; } function renderGenericCannotDisplay(title, message) { var newHTML = ""; newHTML += "" + title + "

"; newHTML += ""; newHTML += "
"; newHTML += message; newHTML += "
"; try { refreshButton.style.display="none"; } catch(e){} try { saveButton.style.display="none"; saveButton.disabled=true; } catch(e){} try { removeButton.style.display="none"; } catch(e){} try { cloneButton.style.display="none"; } catch(e){} statusBar.innerText = ""; xmlContainer.innerHTML = newHTML; } function isProhibitedFCMClass(FCMClassID) { return (Number(FCMClassID) == 2 || Number(FCMClassID) == 3); // Fixed Income, FX } function renderCannotDisplayPageForAccountClass(title, AccountClassID) { var template = ""; switch (Number(AccountClassID)) { case 2: template = "{0} Page is not available for Template Accounts."; break; case 3: template = "{0} Page is not available for Omnibus Accounts."; } renderGenericCannotDisplay(formatString(template, title), "Please choose a different account."); } function renderCannotDisplayPageForFCMClass(title, FCMClassID) { var template = ""; switch (Number(FCMClassID)) { case 2: template = "{0} Page is not available for Fixed Income Accounts."; break; case 3: template = "{0} Page is not available for FX Accounts."; } renderGenericCannotDisplay(formatString(template, title), "Please choose a different account."); } function setElementVisibilitySafe(elementId, isVisible) { /// /// Sets visibility of the element based on element id. Does NOT throw if element is not found /// /// id of the element which visibility to be set. /// true if element to be visible, false otherwise. var elem = document.getElementById(elementId); if (elem) { try { elem.style.display = isVisible ? "inline" : "none"; } catch (e) {} } } function refreshButtons() { setElementVisibilitySafe("refreshButton", true); setElementVisibilitySafe("saveButton", true); setElementVisibilitySafe("removeButton", true); } function insertNavButtons() { var userIndex = window.parent.userIndex; // Make the back button backButton.disabled = !userIndex.canGoBack(); backButton.onclick = userIndex.goBackward; forwardButton.disabled = !userIndex.canGoForward(); forwardButton.onclick = userIndex.goForward; } function pageChanged() { try { if (Cast.PageState.getCurrent().isModifiable()) { saveButton.disabled = false; } } catch (e){} } /* * Make Save page button enabled * if user pressed any key except tab and arrows * (up, down, left, right). * * OBSOLETE: Consider using pageChangedByKeyEx where possible. * Parameters: * eventCode - integer with key code of event */ function pageChangedByKey(eventCode) { if (eventCode != 9 && (eventCode < 37 || eventCode > 40)) { pageChanged(); } } /* * Make Save page button enabled * Best used as onkeypress handler. * if user pressed any key except tab, arrows (up, down, left, right), * Ctrl, Alt, Shift, Home/End, PgUp/Dn, CapsLock, Ins, Pause * * Parameters: * keyCode - integer with key code of event */ function pageChangedByKeyEx(keyCode) { if(keyCode != undefined && keyCode != null) { if( keyCode == 9 || // Tab (keyCode >= 16 && keyCode <=20) || // Shift, Ctrl, Alt, Pause, CapsLock (keyCode >= 33 && keyCode <= 40) || // Navigation (Arrows, End, Home, PgUp, PgDn) keyCode == 45 // Ins ) { // Skip. return; } pageChanged(); } } function showTimeToLive(doTranslation, disableElementsOnReadonlyPage) { /// Initializes lock and shows message in page status bar. /// Indicates whether page requires translation. /// Indicates whether readonly page shouldn't be disabled automatically. doTranslation = (doTranslation === undefined) ? true : !!doTranslation; disableElementsOnReadonlyPage = (disableElementsOnReadonlyPage === undefined) ? true : !!disableElementsOnReadonlyPage; Cast.PageStateView.initialize(doTranslation, disableElementsOnReadonlyPage); } // Disables the inner controls if they don't have "noDisable" attribute. // Params: // parent - all controls nested in parent will be examined. // tagName - string denoting the tag name of disabled controls. function disableControlsHierarchyByTagName(parent, tagName) { var inputs = parent.getElementsByTagName(tagName); for (var index = 0; index < inputs.length; index++) { if (inputs[index].noDisable == null) { inputs[index].disabled = true; } } } // Disables input, button and select controls if they don't have "noDisable" attribute. // Params: // parent - all controls nested in parent will be examined. function disableControlsHierarchy(container) { disableControlsHierarchyByTagName(container, "INPUT"); disableControlsHierarchyByTagName(container, "TEXTAREA"); disableControlsHierarchyByTagName(container, "BUTTON"); disableControlsHierarchyByTagName(container, "SELECT"); } function turnOffRemoved(entityName, disableControls) { if (typeof (disableControls) === "undefined") { disableControls = true; } try { Cast.PageState.setCurrent(Cast.PageState.ENTITY_REMOVED); saveButton.disabled = true; statusBar.innerText += formatString(" This page is disabled because the {0} was removed.", entityName); if (disableControls) { disableControlsHierarchy(xmlContainer); } } catch (e){} } function setRemoveOrRestore(removeOrRestore) { if (document.getElementById("removeButton")) { document.getElementById("removeButton").value = removeOrRestore; } } function disableRemoveOrRestoreButton(disable) { if (document.getElementById("removeButton")) { document.getElementById("removeButton").disabled = disable; } } function allowedToRemoveRestore(canRemoveRestoreXML, clickOkToRemoveEntityOrCancel) { if (!clickOkToRemoveEntityOrCancel) { clickOkToRemoveEntityOrCancel = "Click OK to remove the entity or Cancel to cancel."; } if (canRemoveRestoreXML) { // Get all errors var messages = canRemoveRestoreXML.selectNodes("Root/CanRemoveRestoreStatus/CanRemoveRestoreMessage[Severity/@Value='error']"); var bigMessage = ""; for (var i = 0; i < messages.length; i++) { bigMessage += messages.item(i).selectSingleNode("Message/@Value").value + "\r\n"; } if (bigMessage != "") { alert (bigMessage); return false; } // Get all warnings messages = canRemoveRestoreXML.selectNodes("Root/CanRemoveRestoreStatus/CanRemoveRestoreMessage[Severity/@Value='warning']"); bigMessage = ""; for (var i = 0; i < messages.length; i++) { bigMessage += messages.item(i).selectSingleNode("Message/@Value").value + "\r\n"; } if (bigMessage != "") { bigMessage += "\r\n" + clickOkToRemoveEntityOrCancel; if (!confirm (bigMessage)) { return false; } } return true; } return false; } function popupCalendarDialog(elementOrCallback) { var result = showModalDialog("/CAST/Script/Calendar.asp","","center=true;dialogWidth=200pt;dialogHeight=200pt;status=no;"); if (result=="") { return; } if (typeof(elementOrCallback) === "function") { elementOrCallback(result); } else { elementOrCallback.value = result; } } function showCTXMenu() { CTXMenu.style.display = "inline"; } function changePageManually(pageURL, qstring, searchOptions) { return Cast.TopWindow.innerFrame.userIndex.changePageManually (pageURL, qstring, searchOptions); } function isPageAccessible(pageURL) { return Cast.TopWindow.innerFrame.userIndex.isPageAccessible(pageURL); } function getUserScope() { // because of changes to the frame layout in the CAST facelift, we can no longer // just get the userScope from one location. There are also conditions where // the userIndex is not defined yet - in those cases, we return a default value // for the user scope (the same value of 99 that the DB call returns if it cannot // return a scope). if (window.parent.innerFrame != null) { return window.parent.innerFrame.userIndex.getUserScope(); } else if (window.parent.parent.innerFrame != null) { return window.parent.parent.innerFrame.userIndex.getUserScope(); } else { return 99; } } // // generates password and set it to "password" and "confirm" inputs // /param passwordInput - input element for password value // /param confirmInput - input element for confirm password value // /param generatedPassword - this td element keeps new generated password // function generatePassword(passwordInput,confirmInput,generatedPassword) { var newPassword = GeneratePassword(); generatedPassword.innerText = newPassword; passwordInput.value = newPassword; confirmInput.value = newPassword; pageChanged(); } // // clears the menus displayed from the masthead. If any changes (additions/deletions) // are made to the masthead menu, this method will have to be changed accordingly // // function clearMastheadMenus() { // turn off everything clearUtilitySearchMenu(); clearUtilityInnerMenu(); clearHelpSearchMenu(); clearHelpInnerMenu(); } // // This function is used as the onmouseout for the Utility Iframe to get the menu to disappear // when the mouse leaves the Iframe that is being displayed. The displayed Iframe is dependent // on whether the search frame is displayed or not. function clearUtilityMenu(menuFrame) { searchPanel = Cast.TopWindow.searchFrame.document.getElementById("SearchPanel"); var searchIsShown = (searchPanel != null && searchPanel.style != null && searchPanel.style.display != "none"); if (searchIsShown) { // only clear the menu if the mouseout came from the Search menu frame if (menuFrame.id == "utilityMenuSearchID") { clearUtilitySearchMenu(); } } else { // only clear the menu if the mouseout came from the Inner data menu frame if (menuFrame.id == "utilityMenuDataID") { clearUtilityInnerMenu(); } } } // This function is used as the onmouseout for the Help Iframe to get the menu to disappear // when the mouse leaves the Iframe that is being displayed. The displayed Iframe is dependent // on whether the search frame is displayed or not. function clearHelpMenu(menuFrame) { searchPanel = Cast.TopWindow.searchFrame.document.getElementById("SearchPanel"); var searchIsShown = (searchPanel != null && searchPanel.style != null && searchPanel.style.display != "none"); if (searchIsShown) { // only clear the menu if the mouseout came from the search frame help menu if (menuFrame.id == "helpMenuSearchID") { clearHelpSearchMenu(); } } else { // only clear the menu if the mouseout came from the Inner data frame help menu if (menuFrame.id == "helpMenuDataID") { clearHelpInnerMenu(); } } } // // function to clear out and disable the utility menu associated with the search frame // function clearUtilitySearchMenu() { var utilityChgPassMenu = null; var utilityClntMsgMenu = null; var utilityRoutesMenu = null; var utilityRqstDemoMenu = null; var utilityIncEntMenu = null; var utilityRiskCacheMenu = null; // indicate that we've turned it off. Cast.TopWindow.masthead.document.getElementById("utilityWasCleared").value = "off"; Cast.TopWindow.searchFrame.document.all.utilityMenuSearchID.filters.item('DXImageTransform.Microsoft.Alpha').opacity = 0; utilityChgPassMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityChgPassId"); disableMenuItem(utilityChgPassMenu); utilityClntMsgMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityClntMsgId"); disableMenuItem(utilityClntMsgMenu); utilityRoutesMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityRoutesId"); disableMenuItem(utilityRoutesMenu); utilityRqstDemoMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityRqstDemoId"); disableMenuItem(utilityRqstDemoMenu); utilityIncEntMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityIncEntId"); disableMenuItem(utilityIncEntMenu); utilityRiskCacheMenu = Cast.TopWindow.searchFrame.frames[0].document.getElementById("utilityRiskCacheId"); disableMenuItem(utilityRiskCacheMenu); } // // function to clear out and disable the utility menu associated with the inner data frame // function clearUtilityInnerMenu() { try { var utilityChgPassMenu = null; var utilityClntMsgMenu = null; var utilityRoutesMenu = null; var utilityRqstDemoMenu = null; var utilityIncEntMenu = null; var utilityRiskCacheMenu = null; // indicate that we've turned it off. Cast.TopWindow.masthead.document.getElementById("utilityWasCleared").value = "off"; Cast.TopWindow.innerFrame.dataFrame.document.all.utilityMenuDataID.filters.item('DXImageTransform.Microsoft.Alpha').opacity = 0; utilityChgPassMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityChgPassId"); disableMenuItem(utilityChgPassMenu); utilityClntMsgMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityClntMsgId"); disableMenuItem(utilityClntMsgMenu); utilityRoutesMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityRoutesId"); disableMenuItem(utilityRoutesMenu); utilityRqstDemoMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityRqstDemoId"); disableMenuItem(utilityRqstDemoMenu); utilityIncEntMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityIncEntId"); disableMenuItem(utilityIncEntMenu); utilityRiskCacheMenu = Cast.TopWindow.innerFrame.dataFrame.frames[0].document.getElementById("utilityRiskCacheId"); disableMenuItem(utilityRiskCacheMenu); } catch(e) { // Frames may be not loaded yet, just ignore errors. } } // // function to clear the help menu associated with the search frame // function clearHelpSearchMenu() { var usrGuideMenu = null; var execSymMenu = null; Cast.TopWindow.masthead.document.getElementById("helpWasCleared").value = "off"; Cast.TopWindow.searchFrame.document.all.helpMenuSearchID.filters.item('DXImageTransform.Microsoft.Alpha').opacity = 0; usrGuideMenu = Cast.TopWindow.searchFrame.frames[1].document.getElementById("helpMenuUserGuideId"); disableMenuItem(usrGuideMenu); execSymMenu = Cast.TopWindow.searchFrame.frames[1].document.getElementById("helpMenuExecSymId"); disableMenuItem(execSymMenu); } // // function to clear the help menu associated with the inner data frame // function clearHelpInnerMenu() { var usrGuideMenu = null; var execSymMenu = null; Cast.TopWindow.masthead.document.getElementById("helpWasCleared").value = "off"; Cast.TopWindow.innerFrame.dataFrame.document.all.helpMenuDataID.filters.item('DXImageTransform.Microsoft.Alpha').opacity = 0; usrGuideMenu = Cast.TopWindow.innerFrame.dataFrame.frames[1].document.getElementById("helpMenuUserGuideId"); disableMenuItem(usrGuideMenu); execSymMenu = Cast.TopWindow.innerFrame.dataFrame.frames[1].document.getElementById("helpMenuExecSymId"); disableMenuItem(execSymMenu); } // // disables the events used for the masthead dropdown menu items // function disableMenuItem(menuItem) { if (null != menuItem) { menuItem.onclick = null; menuItem.onmouseover = null; menuItem.onmouseout = null; menuItem.style.cursor = "default"; menuItem.className="masthead-menu-sub-item"; menuItem.style.zIndex = -1; } } // // enables the events used for the masthead dropdown menu items // function enableMenuItem(menuItem,pageName) { if (null != menuItem) { menuItem.onclick = function() { switchToPage(pageName); } menuItem.onmouseover = function() { menuItem.className="masthead-menu-sub-hover"; } menuItem.onmouseout = function() { menuItem.className="masthead-menu-sub-item"; } menuItem.style.cursor = "pointer"; menuItem.style.zIndex = 1; } } //*************************************************************************** // getRadioValue - returns value of the radiobutton group specified by name. Empty if none is selected // @param name name of the radiogroup in question function getRadioValue(radioGroupName) { for (var i=0; i < radioGroupName.length; i++) { if (radioGroupName[i].checked) { return radioGroupName[i].value; } } return ''; } function validatePasswordRestrictionsCompliance(passwordInput, confirmInput, restrictionsNodes) { /// /// Validates password for meeting list of restrictions plus CAST specific restriction /// (& character not allowed in password). /// If validation failed error message will be shown with description of all failed restrictions. /// /// Password input object. /// Password confirmation input object. /// List of nodes with restrictions description. var password = trim(passwordInput.value); var allRestrictionsNodes = new Array(); for (var i=0; i < restrictionsNodes.length; i++) { allRestrictionsNodes[i] = restrictionsNodes[i]; } var errorMessage = DoValidatePasswordExXML(password, allRestrictionsNodes, "Password doesn't meet following restrictions"); if (errorMessage != null) { alert(errorMessage); passwordInput.value = ""; confirmInput.value = ""; passwordInput.focus(); return false; } return true; } function validatePasswordsMatch(newPasswordInput, confirmPasswordInput) { if (newPasswordInput.value != confirmPasswordInput.value) { alert("New password and confirmation do not match.\nPlease retype them."); newPasswordInput.value = ""; confirmPasswordInput.value = ""; newPasswordInput.focus(); return false; } return true; } function validateUniquePasswordPolicy(userId, userType, password) { var data = { newPassword : password, userId : userId, userTypeId : userType }; var url = getControllerActionUrl("Users", "User", "CheckPasswordPolicyCompliance"); // We assume that RequestManager.js + jquery is included on needed pages. try { Cast.RequestManager.postPageDataSync(url, data); return true; } catch (e) { alert(e.errorMessage); return false; } } function validateCompletePasswordCompliance(userId, passwordInput, passwordConfirmationInput) { /// /// Performes validation of password value to all policies, restrictions and conditions. /// /// id of the user for which password to be validated. /// Password input object. /// Password confirmation input object. /// Returns true if all checks out well, false otherwise. //step 1: Sanity check that password typed two times the same way if (!validatePasswordsMatch(passwordInput, passwordConfirmationInput)) { return false; } //step 2: validating restrictions (minimum length, numbers/special symbols, lower/upper case and so on...) var passwordRestrictionsXML = postAndRetrieveXML("", "/CAST/Main/GetPasswordRestrictions.xml.asp", ""); var restrictionsNodes = passwordRestrictionsXML.selectNodes("/Root/PasswordRestrictions/PasswordRestriction"); if (!validatePasswordRestrictionsCompliance(passwordInput, passwordConfirmationInput, restrictionsNodes)) { return false; } //step 3: validating policies compliance (password is different from X previous passwords and so on...) if (!validateUniquePasswordPolicy(userId, USER_TYPE.CAST_USER, passwordInput.value)) { return false; } return true; } // Highlights some listbox options for Risk Parameters (and similar) pages, // if they violate the Maximum FCM settings. // MaxFCMRiskBitMask variable must be defined in the ASP file. function respectMaxFCMRiskBitMaskInListboxes() { if (!bitAnd(MaxFCMRiskBitMask, 524288)) // Don't ignore positive OTE specifically { IgnoreOTEinPP.options[1].style.backgroundColor = maxFCMviolationColor; // "Negative only" } if (!bitAnd(MaxFCMRiskBitMask, 1048576)) // Always include some OTE { IgnoreOTEinPP.options[2].style.backgroundColor = maxFCMviolationColor; // "No" } if (!bitAnd(MaxFCMRiskBitMask, 131072)) // Don't ignore positive NOV specifically { IgnoreNOVinPP.options[1].style.backgroundColor = maxFCMviolationColor; // "Negative only" } if (!bitAnd(MaxFCMRiskBitMask, 262144)) // Always include some NOV { IgnoreNOVinPP.options[2].style.backgroundColor = maxFCMviolationColor; // "No" } if (!bitAnd(MaxFCMRiskBitMask, 8388608)) // Don't ignore positive UPL specifically { IgnoreUPLinDLL.options[1].style.backgroundColor = maxFCMviolationColor; // "Negative only" } if (!bitAnd(MaxFCMRiskBitMask, 16777216)) // Always include some UPL { IgnoreUPLinDLL.options[2].style.backgroundColor = maxFCMviolationColor; // "No" } if (!bitAnd(MaxFCMRiskBitMask, 33554432)) // Don't ignore positive OTE specifically { IgnoreOTEinDLL.options[1].style.backgroundColor = maxFCMviolationColor; // "Negative only" } if (!bitAnd(MaxFCMRiskBitMask, 67108864)) // Always include some OTE { IgnoreOTEinDLL.options[2].style.backgroundColor = maxFCMviolationColor; // "No" } } function getSearchRootXml(searchString, searchType, storedProc, searchTimeout, optArgName, optArg, dbLocationID) { /// /// Returns SearchRoot xml with filled attributes /// /// string with search criteria. /// search type. /// name of search stored procedure. /// DB timeout for search. /// name of the optional argument. /// value of optional argument. /// DB location ID. var res = ""; return res; } function toggleAttribute(jqueryObject, attribute, flag) { /// /// Add/remove attribute of jquery object depending on given flag. /// /// Jquery object. /// Attribute to add/remove. /// If true - add attribute, otherwise remove. if (flag) { jqueryObject.attr(attribute, attribute); } else { jqueryObject.removeAttr(attribute); } } function markControlAsInvalid(jqueryObject, errorMessage, isInvalid) { /// Fills control with color and attach tooltip with message. /// Jquery object with control. /// Determine whether color fill and tooltip should be added to control. // If control should be marked as invalid. if (isInvalid) { jqueryObject.attr("title", errorMessage); // TODO: We can set color using multiple classes or attribute selector due to IE 6 doesn't support it, // so hardcode is here. jqueryObject.css("background-color", "#fc9494"); } else { jqueryObject.removeAttr("title"); jqueryObject.css("background-color", ""); } } // CAST JavaScript objects. (function() { var cast = window.Cast; cast.selectTextbox = function(textbox) { /// Select text and set focus to textbox. /// Text input DOM element. if (!textbox.disabled) { textbox.select(); textbox.focus(); } }; cast.serializeToJson = function(data) { ///Return specified data object represented as JSON string. return JSON.stringify(data); }; cast.convertToArray = function(collection) { /// Converts array-like object to JavaScript array. /// Array-like object. /// JavaScript array. var array = []; for (var i = 0; i < collection.length; ++i) { array[i] = collection[i]; } return array; }; cast.deserializeFromJson = function(json) { ///Deserializes object from given json string. Clone of Cast.Common functionality. /// JSON string. return JSON.parse(json); }; var xhr = { factories: [ function () { return new XMLHttpRequest(); }, function () { return new ActiveXObject("Msxml2.XMLHTTP"); }, function () { return new ActiveXObject("Msxml3.XMLHTTP"); }, function () { return new ActiveXObject("Microsoft.XMLHTTP"); } ], activeFactory: null }; cast.createXhr = function() { /// Creates HttpRequest object in browser-neutral fashion if (xhr.activeFactory != null) { return xhr.activeFactory(); } for (var i = 0; i < xhr.factories.length; i++) { var factory = xhr.factories[i]; try { var xmlhttp = factory(); xhr.activeFactory = factory; return xmlhttp; } catch (e) { } } throw 'No XHR available'; }; cast.removeChildNodes = function(xml) { /// Removes all child nodes from the XML DOM document. while(xml.firstChild) { xml.removeChild(xml.firstChild); } }; })(); function addStatusBarMessage(message) { /// Adds a message to status bar. /// Message. var statusBar = document.getElementById("statusBar"); statusBar.innerHTML = statusBar.innerHTML + " " + message; } function initializeHelp(link, help) { /// /// Associates with , makes visibility toggleable by clicking on . /// /// /// Click on elements with class "close-me" inside will hide . /// Several links can be associated with one help. One link can be associated with several helps. /// /// Link. /// Help. var jHelp = $(help); var jLink = $(link); jLink.addClass("small-help-link small-help"); jHelp.hide(); jLink.click(function() { jHelp.toggle(); }); jHelp.find(".close-me").click(function() { jHelp.hide(); }); } function forceRedrawElement(element) { /// Forces element to redraw. /// Element to redraw. /// IE hack for redrawing selects. element.className = element.className; };