cut-to-pack-service/target/classes/static/js/utils.js

732 lines
28 KiB
JavaScript

(function() {
// global uind object
window.ctp = {};
// utils object
window.ctp.utils = {};
// date format
window.ctp.utils.dateFormat = 'm/d/yy';
// month names
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
// datatable default config
window.ctp.dataTableDefaultConfig = {
pageLength: 100,
searching: true,
lengthChange: false,
processing: true,
fixedHeader: true,
dom: `
<'row'<'col-sm-5'B><'col-sm-7'f>>
<'row'<'col-sm-12't>>
<'row'<'col-sm-5'i><'col-sm-7'p>>`,
buttons: [{
extend: 'excel',
text: '',
className: 'bi bi-file-earmark-spreadsheet btn-sm'
}]
};
// image compressor default config
window.ctp.compressor = {
quality: 0.8,
maxWidth: 2000,
maxHeight: 2000
};
// tinymce
window.ctp.getTinyMceDefaultConfig = function( selector ) {
return {
selector: selector,
skin: 'oxide',
statusbar: false,
plugins: [
'advlist','autolink','lists','link','image','charmap',
'fullscreen','insertdatetime','media','table','help','wordcount',
'preview','anchor','searchreplace','visualblocks','textcolor'
],
toolbar: 'undo redo | a11ycheck casechange blocks | bold italic backcolor forecolor | alignleft aligncenter alignright alignjustify | bullist numlist checklist outdent indent | removeformat | code table help'
};
}
// initialize datatable
window.ctp.utils.initializeDataTable = function( $el, customConfig ) {
customConfig = ( typeof customConfig === 'undefined' ) ? {} : customConfig;
let config = Object.assign( window.ctp.dataTableDefaultConfig, customConfig );
return $el.DataTable( config );
};
// util function: populate options in a select tag
window.ctp.utils.populateOptions = function( $select, optionArr, addMinusOption = false, addFirstOption = false ) {
const emptyOptionStr = '<option value="0">Please select</option>';
let htmlStr = '';
if ( addFirstOption ) {
htmlStr += emptyOptionStr;
}
for ( let i = 0; i < optionArr.length; i++ ) {
htmlStr += `<option value="${ optionArr[i].id }">${ optionArr[i].title }</option>`;
}
if ( addMinusOption ) {
htmlStr += '<option value="-1">Other (Please specify)</option>';
}
$select.html( htmlStr );
};
window.ctp.utils.populateMachineOptions = function( $select, optionArr,addFirstOption = false ) {
const emptyOptionStr = '<option value="">Please select</option>';
let htmlStr = '';
if ( addFirstOption ) {
htmlStr += emptyOptionStr;
}
for ( let i = 0; i < optionArr.length; i++ ) {
htmlStr += `<option value="${ optionArr[i].machineId }">${ optionArr[i].machineName}</option>`;
}
$select.html( htmlStr );
};
// populate system users
window.ctp.utils.populateUserOptions = function( $select, optionArr, addFirstOption = false ) {
const emptyOptionStr = '<option value="">Please select</option>';
let htmlStr = '';
if ( addFirstOption ) {
htmlStr += emptyOptionStr;
}
for ( let i = 0; i < optionArr.length; i++ ) {
htmlStr += `<option value="${ optionArr[i].username }">${ optionArr[i].username }</option>`;
}
$select.html( htmlStr );
};
// populate location options
window.ctp.utils.populateLocationOptions = function( $select, optionArr, addFirstOption = false ) {
const emptyOptionStr = '<option value="" data-empty-option>Please select</option>';
let htmlStr = '';
if ( addFirstOption ) {
htmlStr += emptyOptionStr;
}
for ( let i = 0; i < optionArr.length; i++ ) {
// data attributes
let dataAttributes = "";
// check for unit id
if ( optionArr[i].hasOwnProperty( 'unitId' ) ) {
dataAttributes += `data-unit-id=${optionArr[i]['unitId']} `;
}
// check for floor id
if ( optionArr[i].hasOwnProperty( 'floorId' ) ) {
dataAttributes += `data-floor-id=${optionArr[i]['floorId']} `;
}
// check for store id
if ( optionArr[i].hasOwnProperty( 'storeId' ) ) {
dataAttributes += `data-store-id=${optionArr[i]['storeId']} `;
}
htmlStr += `<option value="${ optionArr[i].id }" ${dataAttributes}>${ optionArr[i].title }</option>`;
}
$select.html( htmlStr );
};
window.ctp.utils.populateTypeOptions = function( $select, optionArr, addMinusOption = false, addFirstOption = false ) {
const emptyOptionStr = '<option value="">Please select</option>';
let htmlStr = '';
if ( addFirstOption ) {
htmlStr += emptyOptionStr;
}
for ( let i = 0; i < optionArr.length; i++ ) {
htmlStr += `<option value="${ optionArr[i].id }">${ optionArr[i].type }</option>`;
}
if ( addMinusOption ) {
htmlStr += '<option value="-1">Other (Please specify)</option>';
}
$select.html( htmlStr );
};
// function to convert image to blob
window.ctp.utils.fileToBase64 = function( file ) {
return new Promise(function( resolve, reject ) {
const reader= new FileReader();
reader.readAsDataURL( file );
reader.onload = function() {
resolve( reader.result );
};
reader.onerror = function( err ) {
reject( err );
}
});
};
// debounce function
window.ctp.utils.debounce = async function( func, interval ) {
let lastCall = -1;
return async function() {
clearTimeout( lastCall );
let args = arguments;
let self = this;
lastCall = setTimeout(function() {
func.apply( self, args );
}, interval );
};
};
// check duplicates
window.ctp.utils.hasDuplicates = function( $selector, $otherSelectors, value ) {
let hasDuplicate = false;
$otherSelectors.not( $selector ).each(function() {
if ( $( this ).val() === value ) {
hasDuplicate = true;
}
});
return hasDuplicate;
};
// number with commas
window.ctp.utils.numberWithCommas = function( number ) {
let floatNumber = parseFloat( number ).toFixed( 2 );
return floatNumber.toString().replace( /\B(?=(\d{3})+(?!\d))/g, "," );
};
// number with commas without fixed decimal places
window.ctp.utils.numberWithCommasWithoutFixedDecimals = function( number ) {
let floatNumber = parseFloat( number );
return floatNumber.toString().replace( /\B(?=(\d{3})+(?!\d))/g, "," );
};
// format currency
window.ctp.utils.formatCurrency = function( number, language, location, currency ) {
let locale = language + '-' + location;
return new Intl.NumberFormat( locale, { style: 'currency', currency: currency }).format( number );
};
// format currency pkr
window.ctp.utils.formatCurrencyPKR = function( number ) {
let locale = 'en-PK';
return new Intl.NumberFormat( locale, { style: 'currency', currency: 'PKR' }).format( number );
};
window.ctp.utils.formatCurrencyPKRWithoutDecimal = function( number ) {
return ( window.ctp.utils.formatCurrencyPKR( number ) ).split( '.' )[0];
};
//format decimal places of given decimal number upto given decimal places
window.ctp.utils.formatDecimalPlaces = function( num, decimalPlaces ) {
const strNum = num.toString();
const decimalIndex = strNum.indexOf('.');
if( decimalIndex === -1 ) {
return num;
}
const endIndex = decimalIndex + decimalPlaces;
const strFormattedNumber = strNum.slice( 0, endIndex + 1 );
return parseFloat( strFormattedNumber );
};
// number to american system
window.ctp.utils.numberToAmericanSystemWords = function( number ) {
number = Math.ceil( number );
const ones = ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
const tens = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
const teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];
function convert_millions( num ) {
if ( num >= 1000000 ) {
return convert_millions( Math.floor( num / 1000000 ) ) + " million " + convert_thousands( num % 1000000 );
} else {
return convert_thousands( num );
}
}
function convert_thousands( num ) {
if ( num >= 1000 ) {
return convert_hundreds( Math.floor( num / 1000 ) ) + " thousand " + convert_hundreds( num % 1000 );
} else {
return convert_hundreds( num );
}
}
function convert_hundreds( num ) {
if ( num > 99 ) {
return ones[Math.floor( num / 100 )] + " hundred " + convert_tens( num % 100 );
} else {
return convert_tens( num );
}
}
function convert_tens( num ) {
if ( num < 10 ) return ones[num];
else if ( num >= 10 && num < 20 ) return teens[num - 10];
else {
return tens[Math.floor( num / 10 )] + " " + ones[num % 10];
}
}
function convert( num ) {
if ( num == 0 ) return "zero";
else return convert_millions( num );
}
let result = convert( number );
if ( typeof result === 'undefined' ) {
return zero;
}
return result.trim();
};
// number to south asian system
window.ctp.utils.numberToSouthAsianSystemWords = function( number ) {
const a = ['', 'one ', 'two ', 'three ', 'four ', 'five ', 'six ', 'seven ', 'eight ', 'nine ', 'ten ', 'eleven ', 'twelve ', 'thirteen ', 'fourteen ', 'fifteen ', 'sixteen ', 'seventeen ', 'eighteen ', 'nineteen '];
const b = ['', '', 'twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];
const regex = /^(\d{2})(\d{2})(\d{2})(\d{1})(\d{2})$/;
const getLT20 = ( n ) => a[Number( n )];
const get20Plus = ( n ) => b[n[0]] + ' ' + a[n[1]];
function convert ( input ) {
const num = Number( input );
if ( isNaN( num ) ) return '';
if ( num === 0 ) return 'zero';
const numStr = num.toString();
if ( numStr.length > 9 ) {
throw new Error( 'overflow' ) // Does not support converting more than 9 digits yet
}
const [, n1, n2, n3, n4, n5] = ( '000000000' + numStr ).substr( -9 ).match( regex ) // left pad zeros
let str = '';
str += n1 != 0 ? ( getLT20( n1 ) || get20Plus( n1 ) ) + 'crore ' : '';
str += n2 != 0 ? ( getLT20( n2 ) || get20Plus( n2 ) ) + 'lakh ' : '';
str += n3 != 0 ? ( getLT20( n3 ) || get20Plus( n3 ) ) + 'thousand ' : '';
str += n4 != 0 ? getLT20( n4 ) + 'hundred ' : '';
str += n5 != 0 && str != '' ? 'and ' : '';
str += n5 != 0 ? ( getLT20( n5 ) || get20Plus( n5 ) ) : '';
return str.trim();
}
return convert( number );
};
/**
* sleep method
*/
window.ctp.utils.sleep = async function( ms ) {
return new Promise( resolve => setTimeout( resolve, ms ) );
};
// number to words
window.ctp.utils.numberToWords = function( number, currencySymbol ) {
let words = window.ctp.utils.numberToAmericanSystemWords( number );
return words + ' only.';
};
// format grades
window.ctp.utils.formatGrades = function( grades ) {
let gradesArr = [];
for ( let grade of grades ) {
let gradeFormatted = {};
gradeFormatted['id'] = grade.id;
gradeFormatted['title'] = grade.type + '-' + grade.level + " (" + grade.description + ")";
gradesArr.push( gradeFormatted );
}
return gradesArr;
};
// format companies
window.ctp.utils.formatCompanies = function( companies ) {
let companyArr = [];
for ( let company of companies ) {
let companyFormatted = {};
companyFormatted['id'] = company.id;
companyFormatted['title'] = company.title;
companyArr.push( companyFormatted );
}
return companyArr;
};
// format raw expense data into pie chart data
window.ctp.utils.formatExpenseDataForPieChart = function( expenses ) {
let formattedData = [];
for ( let expense of expenses ) {
let formattedExpense = {};
formattedExpense['name'] = expense.title;
formattedExpense['y'] = expense.cost;
formattedData.push( formattedExpense );
}
return formattedData;
};
// bind cost center search
window.ctp.utils.bindItemNewCostCenterSearchAutoComplete = function( $selector ) {
$selector.autocomplete({
source: '/uind/rest/accounts-finance/cost-centers/search?departmentId=0',
minLength: 1,
select: async function (e, ui) {
e.preventDefault();
//format string
let splitStr = ui.item.heirarchicalString.split(">");
let hierarchyStr = `${splitStr[3]} > ${splitStr[2]} > ${splitStr[1]} > ${splitStr[0]}`
let $container = $selector.closest( '[data-cost-center-search-container]' );
$container.find( '[data-cost-center-one-search-id]' ).val( ui.item.oneId );
$container.find( '[data-cost-center-two-search-id]' ).val( ui.item.twoId );
$container.find( '[data-cost-center-three-search-id]' ).val( ui.item.threeId );
$container.find( '[data-cost-center-four-search-id]' ).val( ui.item.fourId );
$selector.val( hierarchyStr );
},
focus: function ( e, ui ) {
$selector.val( '' );
}
}).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
let splitStr = ui.heirarchicalString.split(">");
let hierarchyStr = `${splitStr[3]} > ${splitStr[2]} > ${splitStr[1]} > ${splitStr[0]}`
return $( '<li>' )
.attr( "data-value", ui.costCenterOneId )
.append( `<div class="ui-menu-item-wrapper">${hierarchyStr}</div>` )
.appendTo( ul );
};
};
// bind cost center search
window.ctp.utils.bindItemCostCenterSearchAutoComplete = function( $selector ) {
$selector.autocomplete({
source: '/uind/rest/uic/cost-centers/search',
minLength: 1,
select: async function (e, ui) {
e.preventDefault();
let $container = $selector.closest( '[data-cost-center-search-container]' );
$container.find( '[data-cost-center-one-search-id]' ).val( ui.item.costCenterOneId );
$container.find( '[data-cost-center-two-search-id]' ).val( ui.item.costCenterTwoId );
$container.find( '[data-cost-center-three-search-id]' ).val( ui.item.costCenterThreeId );
$container.find( '[data-cost-center-four-search-id]' ).val( ui.item.costCenterFourId );
$selector.val( ui.item.hierarchyString );
},
focus: function ( e, ui ) {
$selector.val( '' );
}
}).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
return $( '<li>' )
.attr( "data-value", ui.costCenterOneId )
.append( `<div class="ui-menu-item-wrapper">${ui.hierarchyString}</div>` )
.appendTo( ul );
};
};
// bind item brand search
window.ctp.utils.bindItemBrandSearchAutoComplete = function( $selector ) {
$selector.autocomplete({
source: '/uind/rest/admin/item-brands/search',
minLength: 1,
select: async function (e, ui) {
e.preventDefault();
let $container = $selector.closest( '[data-item-brand-search-container]' );
$container.find( '[data-item-brand-search-id]' ).val( ui.item.id );
$selector.val( ui.item.title );
},
focus: function ( e, ui ) {
$selector.val( '' );
$selector.closest( '[data-item-brand-search-container]' ).find( '[data-item-brand-search-id]' ).removeAttr( 'value' );
}
}).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
return $( '<li>' )
.attr( "data-value", ui.id )
.append( `<div class="ui-menu-item-wrapper">${ui.title}</div>` )
.appendTo( ul );
};
};
// bind item config search
window.ctp.utils.bindItemConfigSearchAutoComplete = function( $selector ) {
$selector.autocomplete({
source: '/uind/rest/admin/item-brands/search',
minLength: 1,
select: async function (e, ui) {
e.preventDefault();
let $container = $selector.closest( '[data-item-config-search-container]' );
$container.find( '[data-item-config-search-id]' ).val( ui.item.id );
$selector.val( ui.item.title );
},
focus: function ( e, ui ) {
$selector.val( '' );
$selector.closest( '[data-item-config-search-container]' ).find( '[data-item-config-search-id]' ).removeAttr( 'value' );
}
}).data( 'ui-autocomplete' )._renderItem = function ( ul, ui ) {
return $( '<li>' )
.attr( "data-value", ui.id )
.append( `<div class="ui-menu-item-wrapper">${ui.title}</div>` )
.appendTo( ul );
};
};
// format events data
window.ctp.utils.formatLogbackEventsDataTimeSeries = function( events ) {
let formattedData = [];
for ( let event of events ) {
let eventData = [];
eventData.push( event.timestmp );
eventData.push( 1 );
formattedData.push( eventData );
}
return formattedData;
};
// get formatted date from date string
// e.g. accept '2020-10-15' and return 'October 15, 2020'
window.ctp.utils.getFormattedDateStringFromDateString = function( dateString ) {
let date = new Date( Date.parse( dateString ) );
return `${monthNames[date.getMonth()]} ${date.getDate()}, ${date.getFullYear()}`;
};
// get formatted datetime from datetime string
// e.g. accept '2021-01-25T12:38:02' and return '1/25/21 12:38 PM'
window.ctp.utils.getFormattedDateTimeStringFromDateTimeString = function( dateString ) {
if ( ! dateString ) {
return null;
}
let date = new Date( Date.parse( dateString ) );
let day = date.getDate();
let month = date.getMonth();
let year = date.getFullYear().toString().substr( -2 );
let hour = ( date.getHours() > 12 ) ? ( date.getHours() - 12 ) : date.getHours();
hour = ( hour > 9 ) ? hour : ( '0' + hour );
let minute = date.getMinutes();
minute = ( minute > 9 ) ? minute : ( '0' + minute );
let ampm = ( hour >= 12 ) ? 'PM' : 'AM';
return `${month + 1}/${day}/${year} ${hour}:${minute} ${ampm}`;
};
// get formatted datetime from datetime string
// e.g. accept '2021-01-25T12:38:02' and return '1/25/21 12:38 PM'
window.ctp.utils.getFormatted24HrsDateTimeStringFromDateTimeString = function( dateString ) {
if ( ! dateString ) {
return null;
}
let date = new Date( Date.parse( dateString ) );
let day = date.getDate();
day = ( day > 9 ) ? day : ( '0' + day );
let month = date.getMonth();
month = ( month > 9 ) ? month : ( '0' + month );
let year = date.getFullYear();
let hour = ( date.getHours() > 12 ) ? ( date.getHours() - 12 ) : date.getHours();
hour = ( hour > 9 ) ? hour : ( '0' + hour );
let minute = date.getMinutes();
minute = ( minute > 9 ) ? minute : ( '0' + minute );
let seconds = date.getSeconds();
seconds = ( seconds > 9 ) ? seconds : ( '0' + seconds );
return `${year}-${month + 1}-${day} ${hour}:${minute}:${seconds}`;
};
// get formatted datetime from datetime string
// e.g. accept '2021-01-25T12:38:02' and return '12:38 PM'
window.ctp.utils.getFormattedTimeStringFromDateTimeString = function( dateString ) {
if ( ! dateString ) {
return null;
}
let date = new Date( Date.parse( dateString ) );
let hour = ( date.getHours() > 12 ) ? ( date.getHours() - 12 ) : date.getHours();
hour = ( hour > 9 ) ? hour : ( '0' + hour );
let minute = date.getMinutes();
minute = ( minute > 9 ) ? minute : ( '0' + minute );
let ampm = ( date.getHours() >= 12 ) ? 'PM' : 'AM';
return `${hour}:${minute} ${ampm}`;
};
// get formatted date as yyyy-mm-dd
window.ctp.utils.getFormattedDateAsISO8601 = function( date ) {
let month = '' + ( date.getMonth() + 1 ),
day = '' + date.getDate(),
year = date.getFullYear();
if ( month.length < 2 ) {
month = '0' + month;
}
if ( day.length < 2 ) {
day = '0' + day;
}
return [year, month, day].join( '-' );
};
// check if element in viewport
window.ctp.utils.elementInViewport = function( el ) {
// Special bonus for those using jQuery
if ( typeof jQuery === "function" && el instanceof jQuery ) {
el = el[0];
}
let rect = el.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= ( window.innerHeight || document.documentElement.clientHeight ) && /* or $(window).height() */
rect.right <= ( window.innerWidth || document.documentElement.clientWidth ) /* or $(window).width() */
);
};
// get number of number-of-months-added date
window.ctp.utils.addMonthsToDate = function( date, numberOfMonths ) {
// make new date from given date
let newDate = new Date( date.getTime() );
// add given number of months to new date
const addedMonths = newDate.getMonth() + numberOfMonths;
newDate.setMonth( addedMonths );
return newDate;
}
// get year-month string from date
window.ctp.utils.getYearMonthStringFromDate = function( date ) {
let month = '' + ( date.getMonth() + 1 );
const year = date.getFullYear();
if ( month.length < 2 ) {
month = '0' + month;
}
return year + '-' + month;
}
// get date from year-month string
window.ctp.utils.getDateFromYearMonthString = function( yearMonthString ) {
// split given year-month string in array
let yearMonthArray = yearMonthString.split( '-' );
const year = yearMonthArray[0];
const month = '' + ( parseInt( yearMonthArray[1] ) - 1 )
return new Date( year, month );
}
// get months added year-month string
window.ctp.utils.getMonthsAddedYearMonthStringFromYearMonthString = function( startYearMonthString, numberOfMonths ) {
// get start date from startYearMonthString
const startDate = window.ctp.utils.getDateFromYearMonthString( startYearMonthString );
// get end date
const endDate = window.ctp.utils.addMonthsToDate( startDate, numberOfMonths );
// get end year-month string
const endYearMonthString = window.ctp.utils.getYearMonthStringFromDate( endDate );
return endYearMonthString;
}
// get months added year-month string from date
window.ctp.utils.getMonthsAddedYearMonthStringFromDate = function( startDate, numberOfMonths ) {
const endDate = window.ctp.utils.addMonthsToDate( startDate, numberOfMonths );
const endYearMonthString = window.ctp.utils.getYearMonthStringFromDate( endDate );
return endYearMonthString;
}
// get number of days in given date's month
window.ctp.utils.getNumberOfDaysInGivenDate = function( date ) {
return new Date( date.getFullYear(), date.getMonth() + 1, 0 ).getDate();
}
// get date object from date string ( string format yyyy-MM-dd )
window.ctp.utils.getDateFromString = function( dateString ) {
const dateArray = dateString.split( '-' );
return new Date( dateArray[0], ( parseInt( dateArray[1] ) - 1 ) + '', dateArray[2] );
}
// add days to given date string ( string format yyyy-MM-dd )
window.ctp.utils.addDaysToDate = function( dateString, days ) {
const date = window.ctp.utils.getDateFromString( dateString );
const daysAdded = date.getDate() + days;
const month = date.getMonth();
return new Date( date.getFullYear().toString(), month.toString(), daysAdded.toString() );
}
// google map styles
window.ctp.google_map_styles = [
{
"featureType": "road",
"elementType": "geometry",
"stylers": [
{
"lightness": 100
},
{
"visibility": "simplified"
}
]
},
{
"featureType": "water",
"elementType": "geometry",
"stylers": [
{
"visibility": "on"
},
{
"color": "#C6E2FF"
}
]
},
{
"featureType": "poi",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#C5E3BF"
}
]
},
{
"featureType": "road",
"elementType": "geometry.fill",
"stylers": [
{
"color": "#D1D1B8"
}
]
}
];
// default file icon
window.ctp.defaultFileIcon = '/uind/img/file_types/misc.svg';
/**
* get similarity score using Levenshtein distance algorithm
*/
window.ctp.utils.getSimilarityScore = function( toCheck, original ) {
const m = toCheck.length;
const n = original.length;
const d = [];
for ( let i = 0; i <= m; i++ ) {
d[i] = [i];
}
for ( let j = 0; j <= n; j++ ) {
d[0][j] = j;
}
for ( let j = 1; j <= n; j++ ) {
for ( let i = 1; i <= m; i++ ) {
if ( toCheck[i - 1] === original[j - 1] ) {
d[i][j] = d[i - 1][j - 1];
} else {
d[i][j] = Math.min(
d[i - 1][j] + 1, // deletion
d[i][j - 1] + 1, // insertion
d[i - 1][j - 1] + 1 // substitution
);
}
}
}
return Math.max( 0, Math.min( 1, ( 1 - d[m][n] / Math.max( m, n ) ) ) );
};
/*
* return the uuid for browser
* */
window.ctp.utils.getOrGenerateBrowserId = function () {
let browserId = localStorage.getItem('device-hash');
if ( !browserId ) {
browserId = window.ctp.utils.generateUUID();
localStorage.setItem( 'device-hash', browserId );
}
return browserId;
}
/*
* generate uuid for each browser
* */
window.ctp.utils.generateUUID = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
})();