;\nlet logoData = \"\";\nlet employees = JSON.parse(localStorage.getItem('employees')) || [];\n\n\/\/ \u56fd\u9645\u5316\u6587\u672c\nconst i18n = {\n en: {\n companyInfo: \"Company Information\",\n uploadLogo: \"Upload Company Logo\",\n selectLogo: \"Select Logo\",\n employerName: \"Employer Name\",\n employeeName: \"Employee Name\",\n period: \"Pay Period\",\n periodEnd: \"End Date\",\n paymentDate: \"Payment Date\",\n paymentMode: \"Payment Mode\",\n cash: \"Cash\",\n cheque: \"Cheque\",\n bankDeposit: \"Bank Deposit\",\n earningsDeductions: \"Earnings \u0026amp; Deductions\",\n basicPay: \"Basic Pay (A)\",\n totalAllowances: \"Total Allowances (B)\",\n grossPay: \"Gross Pay (A + B) (C)\",\n totalDeductions: \"Total Deductions (D)\",\n cpfEmployee: \"Employee's CPF Deduction\",\n overtimeDetails: \"Overtime Details\",\n otPeriod: \"Overtime Payment Period(s)\",\n otHours: \"Overtime Hours Worked\",\n otPay: \"Total Overtime Pay (E)\",\n additionalPayments: \"Additional Payments\",\n addPayment: \"Add Payment Item\",\n netPay: \"Net Pay (C - D + E + F)\",\n cpfEmployer: \"Employer's CPF Contribution\",\n preview: \"Preview Payslip\",\n downloadPDF: \"Download PDF\",\n reset: \"Reset Form\",\n footerText: \"Belgian Black Professional Payslip Generator \u00a9 2025 | All Rights Reserved\",\n bonus: \"Bonus\",\n commission: \"Commission\",\n transport: \"Transport Allowance\",\n meal: \"Meal Allowance\",\n other: \"Other\",\n specifyOther: \"Specify Other\",\n remove: \"Remove\",\n errorTitle: \"Validation Error\",\n payslipTitle: \"Itemised Pay Slip\",\n earnings: \"Earnings\",\n deductions: \"Deductions\",\n overtime: \"Overtime\",\n otherPayments: \"Other Payments\",\n employer: \"Employer\",\n employee: \"Employee\",\n paymentDateText: \"Payment Date\",\n paymentModeText: \"Payment Mode\",\n netPayText: \"Net Pay\",\n cpfContribution: \"Employer CPF Contribution\",\n employeeManagement: \"Employee Management\",\n employeeId: \"Employee ID\",\n employeeName: \"Employee Name\",\n nricId: \"NRIC\/ID\",\n position: \"Position\",\n department: \"Department\",\n saveEmployee: \"Save Employee\",\n selectEmployee: \"Select Employee\",\n selectEmployeeOption: \"Select an employee\",\n noEmployees: \"No employees saved yet\",\n importExcel: \"Import from Excel\",\n exportExcel: \"Export to Excel\",\n importSuccess: \"Employees imported successfully!\",\n exportSuccess: \"Employees exported successfully!\",\n importError: \"Error importing employees. Please check the file format.\",\n excelTemplate: \"Download Excel Template\",\n generatedOn: \"Generated On\",\n employmentType: \"Employment Type\",\n citizen: \"Citizen\",\n resident: \"Permanent Resident\",\n foreigner: \"Foreigner\",\n cpfInfo: \"CPF Contribution\",\n cpfDisabled: \"Not applicable for foreigners\"\n },\n zh: {\n companyInfo: \"\u516c\u53f8\u4fe1\u606f\",\n uploadLogo: \"\u4e0a\u4f20\u516c\u53f8\u6807\u5fd7\",\n selectLogo: \"\u9009\u62e9\u6807\u5fd7\",\n employerName: \"\u96c7\u4e3b\u540d\u79f0\",\n employeeName: \"\u5458\u5de5\u540d\u79f0\",\n period: \"\u5de5\u8d44\u5468\u671f\",\n periodEnd: \"\u7ed3\u675f\u65e5\u671f\",\n paymentDate: \"\u4ed8\u6b3e\u65e5\u671f\",\n paymentMode: \"\u4ed8\u6b3e\u65b9\u5f0f\",\n cash: \"\u73b0\u91d1\",\n cheque: \"\u652f\u7968\",\n bankDeposit: \"\u94f6\u884c\u8f6c\u8d26\",\n earningsDeductions: \"\u6536\u5165\u4e0e\u6263\u9664\",\n basicPay: \"\u57fa\u672c\u5de5\u8d44 (A)\",\n totalAllowances: \"\u603b\u6d25\u8d34 (B)\",\n grossPay: \"\u603b\u6536\u5165 (A + B) (C)\",\n totalDeductions: \"\u603b\u6263\u9664\u989d (D)\",\n cpfEmployee: \"\u5458\u5de5\u516c\u79ef\u91d1\u6263\u9664\",\n overtimeDetails: \"\u52a0\u73ed\u8be6\u60c5\",\n otPeriod: \"\u52a0\u73ed\u5de5\u8d44\u5468\u671f\",\n otHours: \"\u52a0\u73ed\u65f6\u6570\",\n otPay: \"\u52a0\u73ed\u5de5\u8d44\u603b\u989d (E)\",\n additionalPayments: \"\u5176\u4ed6\u4ed8\u6b3e\",\n addPayment: \"\u6dfb\u52a0\u4ed8\u6b3e\u9879\u76ee\",\n netPay: \"\u51c0\u5de5\u8d44 (C - D + E + F)\",\n cpfEmployer: \"\u96c7\u4e3b\u516c\u79ef\u91d1\u7f34\u7eb3\",\n preview: \"\u9884\u89c8\u5de5\u8d44\u5355\",\n downloadPDF: \"\u4e0b\u8f7dPDF\",\n reset: \"\u91cd\u7f6e\u8868\u5355\",\n footerText: \"Belgian Black \u4e13\u4e1a\u5de5\u8d44\u5355\u751f\u6210\u5668 \u00a9 2025 | \u4fdd\u7559\u6240\u6709\u6743\u5229\",\n bonus: \"\u5956\u91d1\",\n commission: \"\u4f63\u91d1\",\n transport: \"\u4ea4\u901a\u8865\u8d34\",\n meal: \"\u9910\u8d39\u8865\u8d34\",\n other: \"\u5176\u4ed6\",\n specifyOther: \"\u5176\u4ed6\u8bf4\u660e\",\n remove: \"\u5220\u9664\",\n errorTitle: \"\u9a8c\u8bc1\u9519\u8bef\",\n payslipTitle: \"\u8be6\u7ec6\u5de5\u8d44\u5355\",\n earnings: \"\u6536\u5165\",\n deductions: \"\u6263\u9664\",\n overtime: \"\u52a0\u73ed\",\n otherPayments: \"\u5176\u4ed6\u4ed8\u6b3e\",\n employer: \"\u96c7\u4e3b\",\n employee: \"\u5458\u5de5\",\n paymentDateText: \"\u4ed8\u6b3e\u65e5\u671f\",\n paymentModeText: \"\u4ed8\u6b3e\u65b9\u5f0f\",\n netPayText: \"\u51c0\u5de5\u8d44\",\n cpfContribution: \"\u96c7\u4e3b\u516c\u79ef\u91d1\u7f34\u7eb3\",\n employeeManagement: \"\u5458\u5de5\u7ba1\u7406\",\n employeeId: \"\u5458\u5de5ID\",\n employeeName: \"\u5458\u5de5\u59d3\u540d\",\n nricId: \"\u8eab\u4efd\u8bc1\/\u8bc1\u4ef6\u53f7\",\n position: \"\u804c\u4f4d\",\n department: \"\u90e8\u95e8\",\n saveEmployee: \"\u4fdd\u5b58\u5458\u5de5\",\n selectEmployee: \"\u9009\u62e9\u5458\u5de5\",\n selectEmployeeOption: \"\u9009\u62e9\u5458\u5de5\",\n noEmployees: \"\u6682\u65e0\u5458\u5de5\u6570\u636e\",\n importExcel: \"\u4eceExcel\u5bfc\u5165\",\n exportExcel: \"\u5bfc\u51fa\u5230Excel\",\n importSuccess: \"\u5458\u5de5\u5bfc\u5165\u6210\u529f\uff01\",\n exportSuccess: \"\u5458\u5de5\u5bfc\u51fa\u6210\u529f\uff01\",\n importError: \"\u5bfc\u5165\u5458\u5de5\u51fa\u9519\uff0c\u8bf7\u68c0\u67e5\u6587\u4ef6\u683c\u5f0f\u3002\",\n excelTemplate: \"\u4e0b\u8f7dExcel\u6a21\u677f\",\n generatedOn: \"\u751f\u6210\u65e5\u671f\",\n employmentType: \"\u96c7\u4f63\u8eab\u4efd\",\n citizen: \"\u516c\u6c11\",\n resident: \"\u6c38\u4e45\u5c45\u6c11\",\n foreigner: \"\u5916\u56fd\u4eba\",\n cpfInfo: \"\u516c\u79ef\u91d1\u7f34\u7eb3\",\n cpfDisabled: \"\u5916\u56fd\u4eba\u4e0d\u9002\u7528\"\n }\n};\n\n\/\/ \u521d\u59cb\u5316\u9875\u9762\nfunction initializePage() {\n updateCurrencySymbols();\n updateTexts();\n attachEventListeners();\n loadEmployees();\n \n \/\/ \u8bbe\u7f6e\u9ed8\u8ba4\u65e5\u671f\n const today = new Date();\n const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);\n const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);\n \n document.getElementById('periodStart').valueAsDate = firstDay;\n document.getElementById('periodEnd').valueAsDate = lastDay;\n document.getElementById('paymentDate').valueAsDate = today;\n document.getElementById('generatedOn').valueAsDate = today;\n \n calculateGross();\n calculateNetPay();\n}\n\n\/\/ \u66f4\u65b0\u8d27\u5e01\u7b26\u53f7\nfunction updateCurrencySymbols() {\n currencySymbol = currentCurrency === 'USD' ? '
: 'S
;\n document.querySelectorAll('.currency-symbol').forEach(el =\u0026gt; {\n el.textContent = currencySymbol;\n });\n}\n\n\/\/ \u66f4\u65b0\u754c\u9762\u6587\u672c\nfunction updateTexts() {\n const texts = i18n[currentLanguage];\n document.querySelectorAll('[data-i18n]').forEach(el =\u0026gt; {\n const key = el.getAttribute('data-i18n');\n if (texts[key]) {\n el.textContent = texts[key];\n }\n });\n \n \/\/ \u66f4\u65b0\u4e0b\u62c9\u83dc\u5355\u9009\u9879\n const paymentMode = document.getElementById('paymentMode');\n paymentMode.options[0].text = texts.cash;\n paymentMode.options[1].text = texts.cheque;\n paymentMode.options[2].text = texts.bankDeposit;\n \n \/\/ \u66f4\u65b0\u5458\u5de5\u9009\u62e9\u4e0b\u62c9\u83dc\u5355\n const employeeSelect = document.getElementById('employeeSelect');\n employeeSelect.options[0].text = \"-- \" + texts.selectEmployeeOption + \" --\";\n}\n\n\/\/ \u9644\u52a0\u4e8b\u4ef6\u76d1\u542c\u5668\nfunction attachEventListeners() {\n const logoInput = document.getElementById('logoInput');\n \n logoInput.addEventListener('change', function() {\n const file = logoInput.files[0];\n if (file) {\n \/\/ \u68c0\u67e5\u6587\u4ef6\u5927\u5c0f\n if (file.size \u0026gt; 2 * 1024 * 1024) {\n alert(currentLanguage === 'en' ? \"File size exceeds 2MB. Please choose a smaller file.\" : \"\u6587\u4ef6\u5927\u5c0f\u8d85\u8fc72MB\uff0c\u8bf7\u9009\u62e9\u8f83\u5c0f\u7684\u6587\u4ef6\u3002\");\n return;\n }\n \n const reader = new FileReader();\n reader.onload = function(e) {\n logoData = e.target.result;\n \n \/\/ \u521b\u5efa\u9884\u89c8\n const previewContainer = document.getElementById('logoPreviewContainer');\n previewContainer.innerHTML = `\n \u0026lt;div class=\"logo-preview-container\"\u0026gt;\n \u0026lt;img src=\"${logoData}\" class=\"header-logo\" style=\"max-height: 90px;\"\u0026gt;\n \u0026lt;div class=\"remove-logo\" onclick=\"removeLogo()\"\u0026gt;\n \u0026lt;i class=\"fas fa-times\"\u0026gt;\u0026lt;\/i\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;\/div\u0026gt;\n `;\n };\n reader.onerror = function() {\n alert(currentLanguage === 'en' ? \"Error reading file. Please try another image.\" : \"\u8bfb\u53d6\u6587\u4ef6\u9519\u8bef\uff0c\u8bf7\u5c1d\u8bd5\u5176\u4ed6\u56fe\u7247\u3002\");\n };\n reader.readAsDataURL(file);\n }\n });\n \n \/\/ \u81ea\u52a8\u8ba1\u7b97\u603b\u6536\u5165\n document.getElementById('basic').addEventListener('input', calculateGross);\n document.getElementById('allowance').addEventListener('input', calculateGross);\n \n \/\/ \u81ea\u52a8\u8ba1\u7b97\u51c0\u5de5\u8d44\n document.getElementById('deductions').addEventListener('input', calculateNetPay);\n document.getElementById('cpfEmployee').addEventListener('input', calculateNetPay);\n document.getElementById('otPay').addEventListener('input', calculateNetPay);\n \n \/\/ \u5f53\u96c7\u4f63\u7c7b\u578b\u6539\u53d8\u65f6\u66f4\u65b0CPF\u5b57\u6bb5\n document.getElementById('employmentType').addEventListener('change', updateCpfFields);\n \n \/\/ \u6dfb\u52a0\u6309\u94ae\u4e8b\u4ef6\u76d1\u542c\u5668\n document.getElementById('language').addEventListener('change', changeLanguage);\n document.getElementById('currency').addEventListener('change', changeCurrency);\n document.getElementById('saveEmployeeBtn').addEventListener('click', saveEmployee);\n document.getElementById('importEmployeesBtn').addEventListener('click', importEmployees);\n document.getElementById('exportEmployeesBtn').addEventListener('click', exportEmployees);\n document.getElementById('addPaymentBtn').addEventListener('click', addAdditionalPayment);\n document.getElementById('previewBtn').addEventListener('click', previewPayslip);\n document.getElementById('downloadPdfBtn').addEventListener('click', downloadPDF);\n document.getElementById('resetBtn').addEventListener('click', resetForm);\n document.getElementById('employeeSelect').addEventListener('change', loadEmployeeData);\n}\n\n\/\/ \u5220\u9664logo\nfunction removeLogo() {\n logoData = \"\";\n const texts = i18n[currentLanguage];\n document.getElementById('logoPreviewContainer').innerHTML = `\n \u0026lt;label for=\"logoInput\" class=\"logo-upload-btn\"\u0026gt;\n \u0026lt;i class=\"fas fa-cloud-upload-alt\"\u0026gt;\u0026lt;\/i\u0026gt; ${texts.selectLogo}\n \u0026lt;\/label\u0026gt;\n \u0026lt;input type=\"file\" id=\"logoInput\" accept=\"image\/*\" style=\"display: none;\"\u0026gt;\n `;\n document.getElementById('logoInput').addEventListener('change', attachEventListeners);\n}\n\n\/\/ \u8ba1\u7b97\u603b\u6536\u5165\nfunction calculateGross() {\n const basic = parseFloat(document.getElementById('basic').value) || 0;\n const allowance = parseFloat(document.getElementById('allowance').value) || 0;\n const gross = basic + allowance;\n document.getElementById('gross').value = gross.toFixed(2);\n calculateCPF();\n calculateNetPay();\n}\n\n\/\/ \u8ba1\u7b97CPF (\u6839\u636e\u65b0\u52a0\u5761CPF\u5b98\u7f51\u903b\u8f91)\nfunction calculateCPF() {\n const employmentType = document.getElementById('employmentType').value;\n const gross = parseFloat(document.getElementById('gross').value) || 0;\n \n \/\/ \u4ec5\u5bf9\u516c\u6c11\u548c\u6c38\u4e45\u5c45\u6c11\u8ba1\u7b97CPF\n if (employmentType === 'Citizen' || employmentType === 'Resident') {\n \/\/ \u6839\u636e\u65b0\u52a0\u5761CPF\u89c4\u5219\u8ba1\u7b97\n const employeeRate = 0.20; \/\/ 20% \u5458\u5de5\u8d21\u732e\n const employerRate = 0.17; \/\/ 17% \u96c7\u4e3b\u8d21\u732e\n const cpfCeiling = 6000; \/\/ CPF\u4e0a\u9650\n \n \/\/ \u8ba1\u7b97\u5458\u5de5\u548c\u96c7\u4e3bCPF\uff08\u4e0d\u8d85\u8fc7\u4e0a\u9650\uff09\n const cpfEmployee = Math.min(gross, cpfCeiling) * employeeRate;\n const cpfEmployer = Math.min(gross, cpfCeiling) * employerRate;\n \n document.getElementById('cpfEmployee').value = cpfEmployee.toFixed(2);\n document.getElementById('cpfEmployer').value = cpfEmployer.toFixed(2);\n } else {\n \/\/ \u5916\u56fd\u4eba\u6ca1\u6709CPF\n document.getElementById('cpfEmployee').value = '0.00';\n document.getElementById('cpfEmployer').value = '0.00';\n }\n}\n\n\/\/ \u66f4\u65b0CPF\u5b57\u6bb5\u72b6\u6001\nfunction updateCpfFields() {\n const employmentType = document.getElementById('employmentType').value;\n const cpfEmployeeInput = document.getElementById('cpfEmployee');\n const cpfEmployerInput = document.getElementById('cpfEmployer');\n const texts = i18n[currentLanguage];\n \n if (employmentType === 'Foreigner') {\n \/\/ \u5916\u56fd\u4eba - \u7981\u7528CPF\u5b57\u6bb5\n cpfEmployeeInput.disabled = true;\n cpfEmployerInput.disabled = true;\n cpfEmployeeInput.value = '0.00';\n cpfEmployerInput.value = '0.00';\n cpfEmployeeInput.classList.add('cpf-disabled');\n cpfEmployerInput.classList.add('cpf-disabled');\n cpfEmployeeInput.title = texts.cpfDisabled;\n cpfEmployerInput.title = texts.cpfDisabled;\n } else {\n \/\/ \u516c\u6c11\u6216\u6c38\u4e45\u5c45\u6c11 - \u542f\u7528CPF\u5b57\u6bb5\n cpfEmployeeInput.disabled = false;\n cpfEmployerInput.disabled = false;\n cpfEmployeeInput.classList.remove('cpf-disabled');\n cpfEmployerInput.classList.remove('cpf-disabled');\n cpfEmployeeInput.title = '';\n cpfEmployerInput.title = '';\n calculateCPF(); \/\/ \u91cd\u65b0\u8ba1\u7b97CPF\n }\n \n calculateNetPay();\n}\n\n\/\/ \u8ba1\u7b97\u51c0\u5de5\u8d44\nfunction calculateNetPay() {\n const gross = parseFloat(document.getElementById('gross').value) || 0;\n const deductions = parseFloat(document.getElementById('deductions').value) || 0;\n const cpfEmployee = parseFloat(document.getElementById('cpfEmployee').value) || 0;\n const otPay = parseFloat(document.getElementById('otPay').value) || 0;\n \n \/\/ \u8ba1\u7b97\u5176\u4ed6\u4ed8\u6b3e\n let otherPayments = 0;\n document.querySelectorAll('#additionalPaymentsContainer \u0026gt; div').forEach(div =\u0026gt; {\n const amountInput = div.querySelector('input[name=\"amount\"]');\n if (amountInput) {\n const amount = parseFloat(amountInput.value) || 0;\n otherPayments += amount;\n }\n });\n \n const netPay = gross - deductions - cpfEmployee + otPay + otherPayments;\n document.getElementById('netPay').value = netPay.toFixed(2);\n}\n\n\/\/ \u5207\u6362\u8bed\u8a00\nfunction changeLanguage() {\n currentLanguage = document.getElementById('language').value;\n updateTexts();\n}\n\n\/\/ \u5207\u6362\u8d27\u5e01\nfunction changeCurrency() {\n currentCurrency = document.getElementById('currency').value;\n updateCurrencySymbols();\n}\n\n\/\/ \u6dfb\u52a0\u4ed8\u6b3e\u9879\u76ee\nfunction addAdditionalPayment() {\n const container = document.getElementById('additionalPaymentsContainer');\n const div = document.createElement('div');\n div.classList.add('additional-payment-entry');\n \n const texts = i18n[currentLanguage];\n \n div.innerHTML = `\n \u0026lt;div\u0026gt;\n \u0026lt;label\u0026gt;${texts.addPayment.split(' ')[0] || 'Description'}\u0026lt;\/label\u0026gt;\n \u0026lt;select name=\"desc\"\u0026gt;\n \u0026lt;option value=\"Bonus\"\u0026gt;${texts.bonus}\u0026lt;\/option\u0026gt;\n \u0026lt;option value=\"Commission\"\u0026gt;${texts.commission}\u0026lt;\/option\u0026gt;\n \u0026lt;option value=\"Transport Allowance\"\u0026gt;${texts.transport}\u0026lt;\/option\u0026gt;\n \u0026lt;option value=\"Meal Allowance\"\u0026gt;${texts.meal}\u0026lt;\/option\u0026gt;\n \u0026lt;option value=\"Other\"\u0026gt;${texts.other}\u0026lt;\/option\u0026gt;\n \u0026lt;\/select\u0026gt;\n \u0026lt;input type=\"text\" name=\"otherDesc\" placeholder=\"${texts.specifyOther}\" style=\"display:none; margin-top: 5px;\" \/\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;div class=\"input-with-symbol\"\u0026gt;\n \u0026lt;label\u0026gt;${texts.addPayment.split(' ')[1] || 'Amount'}\u0026lt;\/label\u0026gt;\n \u0026lt;span class=\"currency-symbol\"\u0026gt;${currencySymbol}\u0026lt;\/span\u0026gt;\n \u0026lt;input type=\"number\" name=\"amount\" step=\"0.01\" placeholder=\"0.00\"\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;div style=\"display: flex; align-items: flex-end;\"\u0026gt;\n \u0026lt;button type=\"button\" class=\"btn btn-danger\" style=\"height: fit-content;\"\u0026gt;\n \u0026lt;i class=\"fas fa-trash\"\u0026gt;\u0026lt;\/i\u0026gt; ${texts.remove}\n \u0026lt;\/button\u0026gt;\n \u0026lt;\/div\u0026gt;\n `;\n \n \/\/ \u6dfb\u52a0\u4e8b\u4ef6\u76d1\u542c\u5668\n const select = div.querySelector('select[name=\"desc\"]');\n select.addEventListener('change', function() {\n toggleOtherInput(this);\n });\n \n const amountInput = div.querySelector('input[name=\"amount\"]');\n amountInput.addEventListener('input', calculateNetPay);\n \n const removeBtn = div.querySelector('button');\n removeBtn.addEventListener('click', function() {\n this.parentElement.parentElement.remove();\n calculateNetPay();\n });\n \n container.appendChild(div);\n}\n\n\/\/ \u5207\u6362\u5176\u4ed6\u8bf4\u660e\u8f93\u5165\u6846\nfunction toggleOtherInput(select) {\n const otherInput = select.parentElement.querySelector('input[name=\"otherDesc\"]');\n if (select.value === 'Other') {\n otherInput.style.display = 'block';\n } else {\n otherInput.style.display = 'none';\n }\n}\n\n\/\/ \u9884\u89c8\u5de5\u8d44\u5355\nfunction previewPayslip() {\n document.getElementById('errorBox').style.display = 'none';\n document.getElementById('errorBox').innerHTML = '';\n \n const texts = i18n[currentLanguage];\n let errorMessages = [];\n let hasError = false;\n errorMessages.push(`\u0026lt;strong\u0026gt;\u0026lt;i class=\"fas fa-exclamation-triangle\"\u0026gt;\u0026lt;\/i\u0026gt; ${texts.errorTitle}:\u0026lt;\/strong\u0026gt;`);\n\n const employer = document.getElementById('employer').value;\n const employeeSelect = document.getElementById('employeeSelect');\n const employee = employeeSelect.options[employeeSelect.selectedIndex].text;\n const periodStart = document.getElementById('periodStart').value;\n const periodEnd = document.getElementById('periodEnd').value;\n const paymentDate = document.getElementById('paymentDate').value;\n const paymentMode = document.getElementById('paymentMode').value;\n const generatedOn = document.getElementById('generatedOn').value;\n const basic = parseFloat(document.getElementById('basic').value) || 0;\n const allowance = parseFloat(document.getElementById('allowance').value) || 0;\n const deductions = parseFloat(document.getElementById('deductions').value) || 0;\n const cpfEmployee = parseFloat(document.getElementById('cpfEmployee').value) || 0;\n const cpfEmployer = parseFloat(document.getElementById('cpfEmployer').value) || 0;\n const otPay = parseFloat(document.getElementById('otPay').value) || 0;\n const otPeriod = document.getElementById('otPeriod').value;\n const employmentType = document.getElementById('employmentType').value;\n\n \/\/ \u83b7\u53d6\u5458\u5de5\u804c\u4f4d\n const employeeId = employeeSelect.value;\n const employeeData = employees.find(e =\u0026gt; e.id === employeeId);\n const position = employeeData ? employeeData.position : '';\n const department = employeeData ? employeeData.department : '';\n const nric = employeeData ? employeeData.nric : '';\n\n \/\/ \u9a8c\u8bc1\u5fc5\u586b\u5b57\u6bb5\n if (!employer) {\n errorMessages.push(`- ${texts.employerName}`);\n document.getElementById('employer').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('employer').classList.remove('error-highlight');\n }\n \n if (!employeeSelect.value) {\n errorMessages.push(`- ${texts.selectEmployee}`);\n document.getElementById('employeeSelect').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('employeeSelect').classList.remove('error-highlight');\n }\n \n if (!periodStart || !periodEnd) {\n errorMessages.push(`- ${texts.period}`);\n document.getElementById('periodStart').classList.add('error-highlight');\n document.getElementById('periodEnd').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('periodStart').classList.remove('error-highlight');\n document.getElementById('periodEnd').classList.remove('error-highlight');\n }\n \n if (!paymentDate) {\n errorMessages.push(`- ${texts.paymentDate}`);\n document.getElementById('paymentDate').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('paymentDate').classList.remove('error-highlight');\n }\n \n if (!generatedOn) {\n errorMessages.push(`- ${texts.generatedOn}`);\n document.getElementById('generatedOn').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('generatedOn').classList.remove('error-highlight');\n }\n \n if (basic \u0026lt;= 0) {\n errorMessages.push(`- ${texts.basicPay}`);\n document.getElementById('basic').classList.add('error-highlight');\n hasError = true;\n } else {\n document.getElementById('basic').classList.remove('error-highlight');\n }\n\n const gross = basic + allowance;\n\n const addPayEls = document.querySelectorAll('#additionalPaymentsContainer \u0026gt; div');\n let otherPayments = 0;\n let otherPaymentsRows = '';\n\n if (addPayEls.length === 0) {\n otherPaymentsRows += `\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.additionalPayments}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}0.00\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;`;\n } else {\n addPayEls.forEach((div, i) =\u0026gt; {\n const descSelect = div.querySelector('select[name=\"desc\"]');\n const descOther = div.querySelector('input[name=\"otherDesc\"]');\n const amountInput = div.querySelector('input[name=\"amount\"]');\n let desc = descSelect.value;\n\n if (desc === 'Other') {\n if (!descOther.value.trim()) {\n errorMessages.push(`- ${texts.specifyOther} #${i + 1}`);\n descOther.classList.add('error-highlight');\n hasError = true;\n return;\n } else {\n desc = descOther.value.trim();\n descOther.classList.remove('error-highlight');\n }\n }\n\n let amt = parseFloat(amountInput.value);\n if (isNaN(amt) || amt \u0026lt; 0) {\n amt = 0;\n amountInput.value = '0.00';\n errorMessages.push(`- ${texts.addPayment} \"${desc}\"`);\n hasError = true;\n amountInput.classList.add('error-highlight');\n } else {\n amountInput.classList.remove('error-highlight');\n }\n otherPayments += amt;\n otherPaymentsRows += `\u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${desc}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${amt.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;`;\n });\n }\n\n const netPay = gross - deductions - cpfEmployee + otPay + otherPayments;\n\n if (hasError) {\n document.getElementById('errorBox').innerHTML = errorMessages.join('\u0026lt;br\u0026gt;');\n document.getElementById('errorBox').style.display = 'block';\n const firstErrorInput = document.querySelector('.error-highlight');\n if (firstErrorInput) {\n firstErrorInput.scrollIntoView({ behavior: 'smooth', block: 'center' });\n }\n return;\n }\n\n \/\/ \u4f7f\u7528\u66f4\u7d27\u51d1\u7684\u5e03\u5c40\n const output = `\n \u0026lt;div id=\"previewContent\"\u0026gt;\n \u0026lt;div class=\"payslip-header\"\u0026gt;\n \u0026lt;div class=\"payslip-info\"\u0026gt;\n \u0026lt;h2 style=\"color: var(--primary-color); margin-top: 0; font-size: 28px;\"\u0026gt;${texts.payslipTitle}\u0026lt;\/h2\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.employer}:\u0026lt;\/strong\u0026gt; ${employer}\u0026lt;\/p\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.employee}:\u0026lt;\/strong\u0026gt; ${employee}\u0026lt;\/p\u0026gt;\n ${nric ? `\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.nricId}:\u0026lt;\/strong\u0026gt; ${nric}\u0026lt;\/p\u0026gt;` : ''}\n ${position ? `\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.position}:\u0026lt;\/strong\u0026gt; ${position}\u0026lt;\/p\u0026gt;` : ''}\n ${department ? `\u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.department}:\u0026lt;\/strong\u0026gt; ${department}\u0026lt;\/p\u0026gt;` : ''}\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.employmentType}:\u0026lt;\/strong\u0026gt; ${employmentType}\u0026lt;\/p\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.period}:\u0026lt;\/strong\u0026gt; ${periodStart} ${currentLanguage === 'en' ? 'to' : '\u81f3'} ${periodEnd}\u0026lt;\/p\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.paymentDateText}:\u0026lt;\/strong\u0026gt; ${paymentDate}\u0026lt;\/p\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.paymentModeText}:\u0026lt;\/strong\u0026gt; ${paymentMode}\u0026lt;\/p\u0026gt;\n \u0026lt;\/div\u0026gt;\n ${logoData ? `\u0026lt;img src=\"${logoData}\" class=\"payslip-logo\"\u0026gt;` : '\u0026lt;div style=\"min-width: 120px;\"\u0026gt;\u0026lt;\/div\u0026gt;'}\n \u0026lt;\/div\u0026gt;\n \n \u0026lt;div class=\"payslip-details\"\u0026gt;\n \u0026lt;div class=\"payslip-section\"\u0026gt;\n \u0026lt;h3\u0026gt;${texts.earnings}\u0026lt;\/h3\u0026gt;\n \u0026lt;table class=\"compact-table\"\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;Description\u0026lt;\/th\u0026gt;\u0026lt;th\u0026gt;Amount (${currentCurrency})\u0026lt;\/th\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.basicPay}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${basic.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.totalAllowances}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${allowance.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td class=\"bold\"\u0026gt;${texts.grossPay}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${gross.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;\/table\u0026gt;\n \u0026lt;\/div\u0026gt;\n \n \u0026lt;div class=\"payslip-section\"\u0026gt;\n \u0026lt;h3\u0026gt;${texts.deductions}\u0026lt;\/h3\u0026gt;\n \u0026lt;table class=\"compact-table\"\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;Description\u0026lt;\/th\u0026gt;\u0026lt;th\u0026gt;Amount (${currentCurrency})\u0026lt;\/th\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.totalDeductions}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${deductions.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.cpfEmployee}\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${cpfEmployee.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;\/table\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;\/div\u0026gt;\n \n \u0026lt;div class=\"payslip-details\"\u0026gt;\n \u0026lt;div class=\"payslip-section\"\u0026gt;\n \u0026lt;h3\u0026gt;${texts.overtime}\u0026lt;\/h3\u0026gt;\n \u0026lt;table class=\"compact-table\"\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;Description\u0026lt;\/th\u0026gt;\u0026lt;th\u0026gt;Amount (${currentCurrency})\u0026lt;\/th\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;td\u0026gt;${texts.otPay} (${otPeriod})\u0026lt;\/td\u0026gt;\u0026lt;td\u0026gt;${currencySymbol}${otPay.toFixed(2)}\u0026lt;\/td\u0026gt;\u0026lt;\/tr\u0026gt;\n \u0026lt;\/table\u0026gt;\n \u0026lt;\/div\u0026gt;\n \n \u0026lt;div class=\"payslip-section\"\u0026gt;\n \u0026lt;h3\u0026gt;${texts.otherPayments}\u0026lt;\/h3\u0026gt;\n \u0026lt;table class=\"compact-table\"\u0026gt;\n \u0026lt;tr\u0026gt;\u0026lt;th\u0026gt;Description\u0026lt;\/th\u0026gt;\u0026lt;th\u0026gt;Amount (${currentCurrency})\u0026lt;\/th\u0026gt;\u0026lt;\/tr\u0026gt;\n ${otherPaymentsRows}\n \u0026lt;\/table\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;\/div\u0026gt;\n \n \u0026lt;div class=\"payslip-footer\"\u0026gt;\n \u0026lt;div\u0026gt;\n \u0026lt;h3 class=\"net-pay\"\u0026gt;${texts.netPayText}: ${currentCurrency} ${currencySymbol}${netPay.toFixed(2)}\u0026lt;\/h3\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.cpfInfo}:\u0026lt;\/strong\u0026gt; ${currencySymbol}${cpfEmployer.toFixed(2)}\u0026lt;\/p\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;div style=\"text-align: right;\"\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;${texts.generatedOn}:\u0026lt;\/strong\u0026gt; ${generatedOn}\u0026lt;\/p\u0026gt;\n \u0026lt;p\u0026gt;\u0026lt;strong\u0026gt;Generator:\u0026lt;\/strong\u0026gt; Belgian Black Professional Payslip Generator\u0026lt;\/p\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;\/div\u0026gt;\n \u0026lt;\/div\u0026gt;\n `;\n\n document.getElementById('output').innerHTML = output;\n document.getElementById('output').style.display = 'block';\n \n \/\/ \u6eda\u52a8\u5230\u9884\u89c8\u533a\u57df\n document.getElementById('output').scrollIntoView({ behavior: 'smooth' });\n}\n\n\/\/ \u4e0b\u8f7dPDF\nfunction downloadPDF() {\n previewPayslip();\n \n \/\/ \u786e\u4fdd\u9884\u89c8\u5df2\u751f\u6210\n setTimeout(() =\u0026gt; {\n const element = document.getElementById('previewContent');\n if (!element) {\n alert(currentLanguage === 'en' ? \"Please generate preview first\" : \"\u8bf7\u5148\u751f\u6210\u9884\u89c8\");\n return;\n }\n \n const opt = {\n margin: [0.3, 0.3, 0.3, 0.3],\n filename: `Payslip_${new Date().toISOString().slice(0, 10)}.pdf`,\n image: { type: 'jpeg', quality: 0.98 },\n html2canvas: { \n scale: 2.5, \n useCORS: true, \n logging: false,\n onclone: function(clonedDoc) {\n \/\/ \u786e\u4fdd\u56fe\u7247\u5728\u514b\u9686\u7684\u6587\u6863\u4e2d\u4e5f\u80fd\u663e\u793a\n const img = clonedDoc.querySelector('img');\n if (img \u0026amp;\u0026amp; logoData) {\n img.src = logoData;\n }\n }\n },\n jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' },\n pagebreak: { mode: ['avoid-all', 'css', 'legacy'] }\n };\n\n html2pdf().set(opt).from(element).toPdf().get('pdf').then(function (pdf) {\n const totalPages = pdf.internal.getNumberOfPages();\n if (totalPages \u0026gt; 1) {\n for (let i = 1; i \u0026lt;= totalPages; i++) {\n pdf.setPage(i);\n pdf.setFontSize(10);\n pdf.text(`Page ${i} of ${totalPages}`, pdf.internal.pageSize.getWidth() - 50, pdf.internal.pageSize.getHeight() - 10);\n }\n }\n }).save();\n }, 500);\n}\n\n\/\/ \u91cd\u7f6e\u8868\u5355\nfunction resetForm() {\n if (confirm(currentLanguage === 'en' ? \"Are you sure you want to reset the form?\" : \"\u786e\u5b9a\u8981\u91cd\u7f6e\u8868\u5355\u5417\uff1f\")) {\n document.querySelectorAll('input:not([type=\"button\"]):not([type=\"submit\"])').forEach(input =\u0026gt; {\n input.value = '';\n });\n document.getElementById('output').style.display = 'none';\n document.getElementById('additionalPaymentsContainer').innerHTML = '';\n document.getElementById('errorBox').style.display = 'none';\n document.getElementById('gross').value = '';\n document.getElementById('netPay').value = '';\n document.getElementById('employmentType').value = 'Citizen';\n logoData = \"\";\n removeLogo();\n updateCpfFields();\n \n \/\/ \u91cd\u7f6e\u65e5\u671f\n const today = new Date();\n const firstDay = new Date(today.getFullYear(), today.getMonth(), 1);\n const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0);\n \n document.getElementById('periodStart').valueAsDate = firstDay;\n document.getElementById('periodEnd').valueAsDate = lastDay;\n document.getElementById('paymentDate').valueAsDate = today;\n document.getElementById('generatedOn').valueAsDate = today;\n \n calculateGross();\n calculateNetPay();\n }\n}\n\n\/\/ \u5458\u5de5\u7ba1\u7406\u529f\u80fd\nfunction saveEmployee() {\n const id = document.getElementById('employeeId').value;\n const name = document.getElementById('employeeName').value;\n const nric = document.getElementById('employeeNric').value;\n const position = document.getElementById('employeePosition').value;\n const department = document.getElementById('employeeDepartment').value;\n const employmentType = document.getElementById('employmentType').value;\n \n if (!id || !name) {\n alert(currentLanguage === 'en' ? \"Employee ID and Name are required\" : \"\u5458\u5de5ID\u548c\u59d3\u540d\u662f\u5fc5\u586b\u9879\");\n return;\n }\n \n \/\/ \u68c0\u67e5\u5458\u5de5\u662f\u5426\u5df2\u5b58\u5728\n const existingIndex = employees.findIndex(emp =\u0026gt; emp.id === id);\n \n if (existingIndex !== -1) {\n \/\/ \u66f4\u65b0\u73b0\u6709\u5458\u5de5\n employees[existingIndex] = { id, name, nric, position, department, employmentType };\n } else {\n \/\/ \u6dfb\u52a0\u65b0\u5458\u5de5\n employees.push({ id, name, nric, position, department, employmentType });\n }\n \n \/\/ \u4fdd\u5b58\u5230\u672c\u5730\u5b58\u50a8\n localStorage.setItem('employees', JSON.stringify(employees));\n \n \/\/ \u66f4\u65b0UI\n loadEmployees();\n \n \/\/ \u6e05\u7a7a\u8868\u5355\n document.getElementById('employeeId').value = '';\n document.getElementById('employeeName').value = '';\n document.getElementById('employeeNric').value = '';\n document.getElementById('employeePosition').value = '';\n document.getElementById('employeeDepartment').value = '';\n \n alert(currentLanguage === 'en' ? \"Employee saved successfully!\" : \"\u5458\u5de5\u4fdd\u5b58\u6210\u529f\uff01\");\n}\n\nfunction loadEmployees() {\n const employeeList = document.getElementById('employeeList');\n const employeeSelect = document.getElementById('employeeSelect');\n \n employeeList.innerHTML = '';\n employeeSelect.innerHTML = '\u0026lt;option value=\"\"\u0026gt;-- ' + i18n[currentLanguage].selectEmployeeOption + ' --\u0026lt;\/option\u0026gt;';\n \n if (employees.length === 0) {\n employeeList.innerHTML = '\u0026lt;div style=\"padding: 20px; text-align: center;\"\u0026gt;' + i18n[currentLanguage].noEmployees + '\u0026lt;\/div\u0026gt;';\n return;\n }\n \n employees.forEach(emp =\u0026gt; {\n \/\/ \u6dfb\u52a0\u5230\u5458\u5de5\u5217\u8868\n const div = document.createElement('div');\n div.className = 'employee-item';\n \n \/\/ \u6839\u636e\u96c7\u4f63\u7c7b\u578b\u786e\u5b9a\u72b6\u6001\u6807\u7b7e\n let statusClass = 'status-citizen';\n let statusText = i18n[currentLanguage].citizen;\n \n if (emp.employmentType === 'Resident') {\n statusClass = 'status-resident';\n statusText = i18n[currentLanguage].resident;\n } else if (emp.employmentType === 'Foreigner') {\n statusClass = 'status-foreigner';\n statusText = i18n[currentLanguage].foreigner;\n }\n \n div.innerHTML = `\n \u0026lt;div\u0026gt;\n \u0026lt;strong\u0026gt;${emp.name}\u0026lt;\/strong\u0026gt; (ID: ${emp.id}) \n \u0026lt;span class=\"status-indicator ${statusClass}\"\u0026gt;${statusText}\u0026lt;\/span\u0026gt;\n \u0026lt;br\u0026gt;\n ${emp.nric ? `\u0026lt;span\u0026gt;${i18n[currentLanguage].nricId}: ${emp.nric}\u0026lt;\/span\u0026gt;\u0026lt;br\u0026gt;` : ''}\n ${emp.position ? emp.position : ''} ${emp.department ? '\u00b7 ' + emp.department : ''}\n \u0026lt;\/div\u0026gt;\n \u0026lt;div class=\"actions\"\u0026gt;\n \u0026lt;button class=\"btn btn-outline\"\u0026gt;\n \u0026lt;i class=\"fas fa-edit\"\u0026gt;\u0026lt;\/i\u0026gt;\n \u0026lt;\/button\u0026gt;\n \u0026lt;button class=\"btn btn-danger\"\u0026gt;\n \u0026lt;i class=\"fas fa-trash\"\u0026gt;\u0026lt;\/i\u0026gt;\n \u0026lt;\/button\u0026gt;\n \u0026lt;\/div\u0026gt;\n `;\n \n \/\/ \u6dfb\u52a0\u7f16\u8f91\u548c\u5220\u9664\u4e8b\u4ef6\u76d1\u542c\n const editBtn = div.querySelector('.btn-outline');\n editBtn.addEventListener('click', function() {\n loadEmployeeForEdit(emp.id);\n });\n \n const deleteBtn = div.querySelector('.btn-danger');\n deleteBtn.addEventListener('click', function() {\n deleteEmployee(emp.id);\n });\n \n employeeList.appendChild(div);\n \n \/\/ \u6dfb\u52a0\u5230\u9009\u62e9\u4e0b\u62c9\u83dc\u5355\n const option = document.createElement('option');\n option.value = emp.id;\n option.textContent = `${emp.name} (${emp.id})`;\n employeeSelect.appendChild(option);\n });\n}\n\nfunction loadEmployeeForEdit(id) {\n const emp = employees.find(e =\u0026gt; e.id === id);\n if (emp) {\n document.getElementById('employeeId').value = emp.id;\n document.getElementById('employeeName').value = emp.name;\n document.getElementById('employeeNric').value = emp.nric || '';\n document.getElementById('employeePosition').value = emp.position || '';\n document.getElementById('employeeDepartment').value = emp.department || '';\n document.getElementById('employmentType').value = emp.employmentType || 'Citizen';\n updateCpfFields();\n }\n}\n\nfunction deleteEmployee(id) {\n if (confirm(currentLanguage === 'en' ? \"Are you sure you want to delete this employee?\" : \"\u786e\u5b9a\u8981\u5220\u9664\u6b64\u5458\u5de5\u5417\uff1f\")) {\n employees = employees.filter(emp =\u0026gt; emp.id !== id);\n localStorage.setItem('employees', JSON.stringify(employees));\n loadEmployees();\n }\n}\n\nfunction loadEmployeeData() {\n const select = document.getElementById('employeeSelect');\n const id = select.value;\n \n if (!id) return;\n \n const emp = employees.find(e =\u0026gt; e.id === id);\n if (emp) {\n document.getElementById('employmentType').value = emp.employmentType || 'Citizen';\n updateCpfFields();\n }\n}\n\n\/\/ Excel\u5bfc\u5165\u5bfc\u51fa\u529f\u80fd\nfunction exportEmployees() {\n if (employees.length === 0) {\n alert(currentLanguage === 'en' ? \"No employees to export\" : \"\u6ca1\u6709\u5458\u5de5\u6570\u636e\u53ef\u4ee5\u5bfc\u51fa\");\n return;\n }\n \n \/\/ \u521b\u5efa\u5de5\u4f5c\u7c3f\n const wb = XLSX.utils.book_new();\n \n \/\/ \u521b\u5efa\u5de5\u4f5c\u8868\n const wsData = [\n [i18n[currentLanguage].employeeId, i18n[currentLanguage].employeeName, \n i18n[currentLanguage].nricId, i18n[currentLanguage].employmentType,\n i18n[currentLanguage].position, i18n[currentLanguage].department],\n ...employees.map(emp =\u0026gt; [\n emp.id, \n emp.name, \n emp.nric || '', \n emp.employmentType || '',\n emp.position || '', \n emp.department || ''\n ])\n ];\n \n const ws = XLSX.utils.aoa_to_sheet(wsData);\n \n \/\/ \u5c06\u5de5\u4f5c\u8868\u6dfb\u52a0\u5230\u5de5\u4f5c\u7c3f\n XLSX.utils.book_append_sheet(wb, ws, \"Employees\");\n \n \/\/ \u5bfc\u51faExcel\u6587\u4ef6\n XLSX.writeFile(wb, `employees_${new Date().toISOString().slice(0, 10)}.xlsx`);\n \n alert(i18n[currentLanguage].exportSuccess);\n}\n\nfunction importEmployees() {\n const fileInput = document.createElement('input');\n fileInput.type = 'file';\n fileInput.accept = '.xlsx, .xls';\n \n fileInput.onchange = function(e) {\n const file = e.target.files[0];\n if (!file) return;\n \n const reader = new FileReader();\n reader.onload = function(e) {\n try {\n const data = new Uint8Array(e.target.result);\n const workbook = XLSX.read(data, {type: 'array'});\n \n \/\/ \u83b7\u53d6\u7b2c\u4e00\u4e2a\u5de5\u4f5c\u8868\n const worksheet = workbook.Sheets[workbook.SheetNames[0]];\n const jsonData = XLSX.utils.sheet_to_json(worksheet, {header: 1});\n \n \/\/ \u79fb\u9664\u8868\u5934\n jsonData.shift();\n \n \/\/ \u5904\u7406\u6570\u636e\n const newEmployees = jsonData.map(row =\u0026gt; ({\n id: row[0] || '',\n name: row[1] || '',\n nric: row[2] || '',\n employmentType: row[3] || 'Citizen',\n position: row[4] || '',\n department: row[5] || ''\n })).filter(emp =\u0026gt; emp.id \u0026amp;\u0026amp; emp.name);\n \n if (newEmployees.length === 0) {\n throw new Error(\"No valid employee data found\");\n }\n \n \/\/ \u6dfb\u52a0\u5230\u73b0\u6709\u5458\u5de5\n employees = [...employees, ...newEmployees];\n \n \/\/ \u4fdd\u5b58\u5230\u672c\u5730\u5b58\u50a8\n localStorage.setItem('employees', JSON.stringify(employees));\n \n \/\/ \u66f4\u65b0UI\n loadEmployees();\n \n alert(i18n[currentLanguage].importSuccess);\n } catch (error) {\n console.error(error);\n alert(i18n[currentLanguage].importError);\n }\n };\n \n reader.readAsArrayBuffer(file);\n };\n \n fileInput.click();\n}\n\n\/\/ \u9875\u9762\u52a0\u8f7d\u5b8c\u6210\u540e\u521d\u59cb\u5316\nwindow.addEventListener('DOMContentLoaded', function() {\n initializePage();\n updateCpfFields(); \/\/ \u521d\u59cb\u5316\u65f6\u66f4\u65b0CPF\u5b57\u6bb5\u72b6\u6001\n});\n\/\/]]\u0026gt;\n\u0026lt;\/script\u0026gt;\n\u0026lt;\/body\u0026gt;\n\u0026lt;\/html\u0026gt;","render_as_iframe":false,"selected_app_name":"HtmlApp","app_list":"{\"HtmlApp\":9018981}"}}}],"title":"Payslip generator","uid":"88bf8fa0-779b-4b60-b916-8016e4ce4239","path":"\/payslip-generator","autoPath":true,"authorized":true}],"menu":{"type":"Menu","id":"f_ad7148f2-af96-4dc5-aa3f-46401ccad342","defaultValue":null,"template_name":"navbar","logo":null,"components":{"image1":{"type":"Image","id":"3ab868d5-99d5-43c9-b5e7-40308fe2ce32","defaultValue":true,"link_url":"http:\/\/belgianblacksg.com","thumb_url":"!","url":"!","caption":"","description":"","storageKey":"18909116\/228582_94207","storage":"s","storagePrefix":null,"format":"png","h":166,"w":492,"s":12148,"new_target":false,"noCompression":false,"focus":null},"image2":{"type":"Image","id":"f_824b2906-5c2f-437d-bd33-861ecc41caed","defaultValue":true,"link_url":null,"thumb_url":null,"url":"http:\/\/assets.strikingly.com\/assets\/themes\/fresh\/power.png","caption":"","description":"","storageKey":null,"storage":null,"format":null,"h":37,"w":32,"s":null,"new_target":true},"text1":{"type":"RichText","id":"f_bd8ffe00-92de-470a-9b1e-cd264bc9be90","defaultValue":false,"alignment":null,"value":"","backupValue":null,"version":1,"defaultDataProcessed":true},"text2":{"type":"RichText","id":"f_f34417a6-85c0-4021-97fe-9194e628cd64","defaultValue":true,"value":"Add a subtitle","backupValue":null,"version":null},"button1":{"type":"Button","id":"f_58973ba0-f18b-48f9-93fc-a2011d66a593","defaultValue":false,"alignment":"center","text":"\u4e3b\u9875","link_type":"Web","size":"small","mobile_size":"automatic","style":"","color":"","font":"Montserrat","url":"https:\/\/www.belgianblacksg.com","new_target":false,"backgroundSettings":{"default":"#040404","preIndex":null,"type":"default","id":"f_6c79cf0d-a818-4f03-95a5-0b0c844dbc8a"}},"background1":{"type":"Background","id":"f_a66c8c28-6eaf-4f3a-8ea1-635a90bfdcb7","defaultValue":true,"url":"\/assets\/themes\/profile\/bg.jpg","textColor":"light","backgroundVariation":"","sizing":"cover","videoUrl":null,"videoHtml":null,"storageKey":null,"storage":null,"format":null,"h":null,"w":null,"s":null},"image3":{"type":"Image","id":"4b188eac-510c-4495-8f1a-9e6295b56731","defaultValue":true,"link_url":"","thumb_url":"\/images\/icons\/transparent.png","url":"\/images\/icons\/transparent.png","caption":"","description":"","storageKey":null,"storage":null,"storagePrefix":null,"format":null,"h":null,"w":null,"s":null,"new_target":true,"noCompression":false,"focus":null}}},"footer":{"type":"Footer","id":"f_e1d67782-58b2-4698-96bb-6b239864ef3e","defaultValue":null,"socialMedia":null,"copyright":null,"components":{"background1":{"type":"Background","id":"f_bf1fca52-5753-4f14-8c48-dc95bab16f07","defaultValue":true,"url":"","textColor":"light","backgroundVariation":"","sizing":"cover","videoUrl":"","videoHtml":"","useSameBg":true,"backgroundApplySettings":{}},"text1":{"type":"RichText","id":"f_c0d614a1-8bc9-488e-bbf0-9c87dad7443e","defaultValue":false,"alignment":null,"value":"\u003cp\u003e\u003cstrong\u003e\u5173\u4e8e\u6211\u4eec\u003c\/strong\u003e\u003c\/p\u003e\u003cp\u003e\u6211\u4eec\u7684\u4f7f\u547d\u003c\/p\u003e\u003cp\u003e\u6b63\u5728\u62db\u8058\uff01\u003c\/p\u003e"},"text2":{"type":"RichText","id":"f_b0f0c564-245c-4d69-8dac-251834a796de","defaultValue":false,"alignment":null,"value":"\u003cp\u003e\u003cstrong\u003e\u4fe1\u606f\u003c\/strong\u003e\u003c\/p\u003e\u003cp\u003e\u5e2e\u52a9\u6587\u6863\u003c\/p\u003e\u003cp\u003e\u54c1\u724c\u4f18\u52bf\u003c\/p\u003e"},"text3":{"type":"RichText","id":"f_eae65cc7-9216-41c5-8a7c-64c57872c849","defaultValue":false,"alignment":null,"value":"\u003cp\u003e\u003cstrong\u003e\u8054\u7cfb\u6211\u4eec\u003c\/strong\u003e\u003c\/p\u003e\u003cp\u003e\u6211\u4eec\u671f\u5f85\u6536\u5230\u4f60\u7684\u6765\u4fe1\uff01\u003c\/p\u003e\u003cp\u003e321-555-5555\u003c\/p\u003e\u003cp\u003einfo@company.com\u003c\/p\u003e"},"text4":{"type":"RichText","id":"f_59815973-34a4-4f35-809a-6869d591e9f3","defaultValue":false,"alignment":null,"value":"\u003cp\u003e\u003cstrong\u003e\u8ba2\u9605\u6211\u4eec\u7684\u6700\u65b0\u8d44\u8baf\u003c\/strong\u003e\u003c\/p\u003e","backupValue":null,"version":1},"copyright":{"type":"RichText","id":"f_785655a3-8816-444f-8caa-3049282d544b","defaultValue":false,"alignment":null,"value":"\u003cdiv class=\"s-rich-text-wrapper\" style=\"display: block; \"\u003e\u003cp class=\" s-rich-text-wrapper\"\u003e\u003cspan style=\"color: #50555c;\"\u003e@2024 Belgian Black \u003c\/span\u003e\u003c\/p\u003e\u003c\/div\u003e","backupValue":null,"version":1,"defaultDataProcessed":true},"email1":{"type":"EmailForm","id":"f_7040dc6a-ff2f-48de-a235-612362231ca6","defaultValue":null,"hideMessageBox":false,"hide_name":false,"hide_email":false,"hide_phone_number":true,"name_label":"\u540d\u5b57","name_format":"single","first_name_label":"First Name","last_name_label":"Last Name","email_label":"\u90ae\u7bb1","phone_number_label":"\u7535\u8bdd","message_label":"\u7559\u8a00","submit_label":"\u8ba2\u9605","thanksMessage":"\u611f\u8c22\u63d0\u4ea4","recipient":"","label":null},"image1":{"type":"Image","id":"f_9aeaa3f3-58a6-43fa-b493-317d0f642c2a","defaultValue":true,"link_url":null,"thumb_url":null,"url":"","caption":"","description":"","new_target":true},"socialMedia":{"type":"SocialMediaList","id":"f_ca94e3fe-967d-42e5-ba23-841d7f3d9387","defaultValue":false,"link_list":[],"button_list":[{"type":"Facebook","id":"f_5c42cdbd-4398-4ed9-b74d-5f14fe7af572","defaultValue":false,"url":"","link_url":"","share_text":"","show_button":false,"app_id":543870062356274},{"type":"Twitter","id":"f_428d754c-28b2-4bd1-bd26-54917ae15c50","defaultValue":false,"url":"","link_url":"","share_text":"","show_button":false},{"type":"LinkedIn","id":"f_f5bcf098-ed59-4e4a-84c5-1b1840e66303","defaultValue":null,"url":"","link_url":"","share_text":"","show_button":false},{"type":"Pinterest","id":"f_98fbe7d6-db84-4ed8-9e26-09e0d2652724","url":"","show_button":false}],"contact_list":[{"type":"SocialMediaPhone","id":"617794ae-4d4e-11f0-90ae-c3fb4c0ebe97","defaultValue":"91896789","className":"fas fa-phone-alt"},{"type":"SocialMediaEmail","id":"617794af-4d4e-11f0-90ae-c3fb4c0ebe97","defaultValue":"biz@belgianblacksg.com","className":"fas fa-envelope"}],"list_type":"link"}},"layout_variation":"vertical"},"submenu":{"type":"SubMenu","id":"f_adb41d14-3d1d-404d-810f-9ec1f2e8a81b","defaultValue":null,"list":[{"type":"RepeatableItem","id":"f_69588675-7e73-4bff-8170-3c800f1fc2ca","components":{"link":{"type":"Button","id":"f_e8976d05-8d21-4b43-8540-acd918ff29c7","defaultValue":false,"text":"\u4e3b\u9875","url":"http:\/\/www.belgianblacksg.com","new_target":false}}}],"components":{"link":{"type":"Button","id":"f_c764276a-b868-4068-ab67-a960bb3a8cdb","defaultValue":null,"text":"Facebook","url":"http:\/\/www.facebook.com","new_target":true}}},"customColors":{"type":"CustomColors","id":"f_a57fb4e8-14c5-4c38-bf7b-9795b45ae5ec","active":true,"highlight1":"#040404","highlight2":"#080404","themePreColors":[{"type":"ThemeColor","id":"f_c42171bb-f5c8-4259-95cc-32ffdce07461","key":0,"value":"#0d0d0d"},{"type":"ThemeColor","id":"f_c53b6413-fe8f-4d61-bd57-736930bee02f","key":1,"value":"#383838"},{"type":"ThemeColor","id":"f_81f625bf-1509-49c0-8dfe-52a28a40f241","key":2,"value":"#6b6b6b"},{"type":"ThemeColor","id":"f_68623a7b-6248-4800-953a-59607540c41c","key":3,"value":"#9e9e9e"},{"type":"ThemeColor","id":"f_09f1f8ba-fca3-4e55-b1ed-d57b3fc0a4d7","key":4,"value":"#d1d1d1"},{"type":"ThemeColor","id":"f_cba6ea28-6f6d-45be-9093-bceb1dc3377b","key":5,"value":"#110909"},{"type":"ThemeColor","id":"f_450b299e-3047-4afb-84ef-45e869c4c58a","key":6,"value":"#4b2626"},{"type":"ThemeColor","id":"f_d0629699-2f4e-40d6-8ab2-fb0b38e906de","key":7,"value":"#8e4848"},{"type":"ThemeColor","id":"f_ed30050a-a5e1-406f-a80d-06c01223c97d","key":8,"value":"#be7e7e"},{"type":"ThemeColor","id":"f_7c8e2462-0570-4ff9-88cc-9de879dbabe3","key":9,"value":"#e0c2c2"},{"type":"ThemeColor","id":"f_eece177e-446a-4889-8baa-62745cad98d6","key":10,"value":"#ffffff"},{"type":"ThemeColor","id":"f_d593e5a4-ed8d-4a4b-b525-836dbffe4742","key":11,"value":"#555555"},{"type":"ThemeColor","id":"f_d173fa70-276d-433f-bbab-d0953064e9cb","key":12,"value":"#000000"},{"type":"ThemeColor","id":"f_8f74ee36-de28-4c9c-b237-4c83670ac257","key":13,"value":"#816354"},{"type":"ThemeColor","id":"f_423911a5-d704-4470-8b2a-a85eb3921e9b","key":14,"value":"#ff4d4d"},{"type":"ThemeColor","id":"f_9e99c203-ef52-4ca1-a8e0-634723443321","key":15,"value":"#ffa64d"},{"type":"ThemeColor","id":"f_68a7c2f5-81c7-441a-8df2-a2332af07fd9","key":16,"value":"#9cce06"},{"type":"ThemeColor","id":"f_e477f6af-d251-47f3-b86a-3a0005a7c06e","key":17,"value":"#26c9ff"}]},"animations":{"type":"Animations","id":"f_1e864d09-1899-4c92-98b3-d7c80ca2377e","defaultValue":null,"page_scroll":"none","background":"none","image_link_hover":"none"},"s5Theme":{"type":"Theme","id":"f_247e5d2c-d437-4993-a487-1c633cb2e339","defaultValue":null,"version":"10","nav":{"type":"NavTheme","id":"f_a7eefaef-c78a-4fe1-925d-f515062961c4","defaultValue":null,"name":"topBar","layout":"a","padding":"medium","sidebarWidth":"medium","topContentWidth":"section","horizontalContentAlignment":"center","verticalContentAlignment":"middle","fontSize":"medium","backgroundColor1":"","highlightColor":null,"presetColorName":"transparent","itemColor":null,"itemSpacing":"compact","dropShadow":"no","socialMediaListType":"link","isTransparent":true,"isSticky":true,"showSocialMedia":false,"hasTransparentFixedNavConfigChanged":true,"highlight":{"blockBackgroundColor":null,"blockTextColor":null,"blockBackgroundColorSettings":{"preIndex":null,"type":"default","default":"#cccccc","id":"f_c4a2f70c-d8fa-465d-829d-c687ec140f4f"},"blockTextColorSettings":{"preIndex":null,"type":"default","default":"#000000","id":"f_d4c83a43-d846-4298-a22d-2793d8f7695e"},"blockShape":"pill","textColor":null,"textColorSettings":{"preIndex":null,"type":"default","default":"#000000","id":"f_1ef63884-2b65-4e14-9a0b-81b48aeb9dda"},"type":"underline","id":"f_b4954571-e930-445f-b6e3-a4680d5df720"},"border":{"enable":false,"borderColor":"#000","position":"bottom","thickness":"small","borderColorSettings":{"preIndex":null,"type":"custom","default":"#ffffff","id":"f_36e2f41c-bfc0-4e02-833b-561ede6898f0"}},"socialMedia":[],"socialMediaButtonList":[{"type":"Facebook","id":"b90b5c28-4d2a-11f0-82bf-c90993699d6d","url":"","link_url":"","share_text":"","show_button":false},{"type":"Twitter","id":"b90b5c29-4d2a-11f0-82bf-c90993699d6d","url":"","link_url":"","share_text":"","show_button":false},{"type":"LinkedIn","id":"b90b5c2a-4d2a-11f0-82bf-c90993699d6d","url":"","link_url":"","share_text":"","show_button":false},{"type":"Pinterest","id":"b90b5c2b-4d2a-11f0-82bf-c90993699d6d","url":"","link_url":"","share_text":"","show_button":false}],"socialMediaContactList":[{"type":"SocialMediaPhone","id":"617794ae-4d4e-11f0-90ae-c3fb4c0ebe97","defaultValue":"91896789","className":"fas fa-phone-alt"},{"type":"SocialMediaEmail","id":"617794af-4d4e-11f0-90ae-c3fb4c0ebe97","defaultValue":"biz@belgianblacksg.com","className":"fas fa-envelope"}],"backgroundColorSettings":{"preIndex":null,"type":"default","default":"#ffffff","id":"f_ac66b670-e8fe-41da-a59f-c25b1b407995"},"highlightColorSettings":{"preIndex":null,"type":"default","default":"#040404","id":"f_4bf6a494-ce6b-469a-a74d-867298ae1755"},"itemColorSettings":{"preIndex":10,"type":"pre-color","default":"#323232","id":"f_04c037cc-f6bb-4ed8-90b7-5689f8f20f78"}},"section":{"type":"SectionTheme","id":"f_4fc6197e-5182-4a82-a157-ca9ae223252b","defaultValue":null,"padding":"normal","contentWidth":"wide","contentAlignment":"center","baseFontSize":17,"titleFontSize":null,"subtitleFontSize":null,"itemTitleFontSize":null,"itemSubtitleFontSize":null,"textHighlightColor":null,"baseColor":"","titleColor":"","subtitleColor":"#040404","itemTitleColor":"","itemSubtitleColor":"#040404","textHighlightSelection":{"type":"TextHighlightSelection","id":"f_100266f9-faa6-4a20-8290-809532d31c19","defaultValue":null,"title":false,"subtitle":true,"itemTitle":false,"itemSubtitle":true},"base":{"preIndex":null,"type":"default","default":"#50555c","id":"f_7932a4e9-fb99-412a-b4f1-02d596c64a86"},"title":{"preIndex":null,"type":"default","default":"#1D2023","id":"f_2f117007-4e92-432d-9f0e-53fae3f00c7b"},"subtitle":{"preIndex":null,"type":"default","default":"#040404","id":"f_b1bffc9a-4cde-4fcf-99b7-f9ad016bd460"},"itemTitle":{"preIndex":null,"type":"default","default":"#1D2023","id":"f_a3623709-41e8-436f-be0d-9927f81acf39"},"itemSubtitle":{"preIndex":null,"type":"default","default":"#040404","id":"f_a72ab19c-6309-409e-a163-9668659198b8"}},"firstSection":{"type":"FirstSectionTheme","id":"f_9f9203be-cabb-4145-b07c-4de2ccc75783","defaultValue":null,"height":"normal","shape":"arrow"},"button":{"type":"ButtonTheme","id":"f_78383a89-ed4d-4cda-9d68-f5c72825706d","defaultValue":null,"backgroundColor":"#040404","shape":"rounded","fill":"solid","backgroundSettings":{"preIndex":null,"type":"default","default":"#040404","id":"f_da8607ad-56df-4840-bdbb-c2dab70956a2"}}},"navigation":{"items":[{"type":"page","id":"88bf8fa0-779b-4b60-b916-8016e4ce4239","visibility":true}],"links":[{"type":"link","id":"f_e8976d05-8d21-4b43-8540-acd918ff29c7","visibility":true}]}},"pageMeta":{"user":{"membership":"pro20","subscription_plan":"pro20_2y","subscription_period":"2y","is_on_trial":false,"id":18909116,"enable_desktop_notifications":null,"canUseLiveChat":false,"hideNavTextColor":true,"hideNewDashboardTour":false,"hideMobileEditorTour":true,"hideMobileActionsTour":false,"hideNewEditorTour":true,"hideChangeStyleTooltip":false},"guides":{"display_site_new_editor_modal":false},"ecommerceSettings":{"currencyCode":"USD","currencyData":{"code":"USD","symbol":"$","decimal":".","thousand":",","precision":2,"name":"\u7f8e\u5143"},"displayTax":true,"registration":"no_registration","postOrderRedirection":{},"enableProductReview":false,"paymentGateways":{"stripe":false,"square":false,"offline":false,"paypal":false,"midtrans":false,"alipay":false,"pingpp_wx_pub":false,"pingpp_wx_pub_qr":false,"pingpp_alipay_qr":false,"pingpp_alipay_wap":false,"wechatpay":false}},"portfolioSetting":true,"portfolioCurrencyCode":"USD","portfolioContactRequired":false,"portfolioRestrictedDetails":null,"portfolioCustomButton":{"buttonType":"no_button","urlType":"same_url","individualButtonMigrated":true,"buttonSetting":{"individual_button_migrated":true}},"chatSettings":null,"connectedSites":[],"category":null,"s4_migration":{"is_migrated":false,"is_retired_theme":false,"has_custom_code":false},"page_groups":[],"slide_names":["\u4e3b\u9875","Payslip generator"],"theme":{"name":"s5-theme"},"theme_selection":{"id":496,"theme_id":48,"display_name":"BLANK","description":"","is_new":null,"priority":null,"thumb_image":"https://static-assets.strikinglycdn.com/templates/1667529697014.jpg","demo_page_permalink":"app-blank-demo-v4-cn","data_page_permalink":"app-blank-demo-v4-cn","created_at":"2022-11-03T19:41:41.729-07:00","updated_at":"2025-12-18T02:03:27.762-08:00","name":"blank_en_zh-CN","is_control":false,"control_name":"blank_en","locale":"zh-CN","version":"v4","tags":[],"mobile_thumb_image":"","platforms":[""],"required_membership":[""],"priority_automated":null,"priority_b":0,"one_page_only":true,"rank_automated":4,"rank_score":9.69,"only_asb":false,"theme_name":"app"},"description":"","connected_sites":[],"linkedin_app":false,"is_weitie_page":false,"canonical_locale_supported":true,"forced_locale":"zh-CN","china_optimization":false,"mobile_actions":{"phone":null,"sms":null,"location":null,"email":null,"version":null,"actions":[]},"domain_connection":{"domain_id":118774,"idn":"payslip2.belgianblacksg.com","fqdn":"payslip2.belgianblacksg.com","https_status":"ssl_active","ssl_cert_status":"activated","dns_status":"active","connect_status":"connected"},"public_url":"https:\/\/payslip2.belgianblacksg.com\/","current_path":"\/","rollouts":{"custom_code":true,"pro_sections":true,"pro_apps":true,"custom_form":false,"new_settings_dialog_feature":true,"google_analytics":true,"strikingly_analytics":true,"popup":null,"sections_name_sync":true,"membership_feature":false},"membership_feature_active":false,"site_mode":"show","password_protected":false,"is_section_template":false,"google":{"enable_ga_universal":false,"analytics_tracker":null,"analytics_type":null,"site_checker":null},"facebook_pixel_id":null,"enable_site_search":false,"enable_card_preset_color":false,"enable_fixed_button_color":true,"enable_fixed_text_color":true,"enable_fixed_text_color_remaining":true,"enable_fixed_text_color_has_bg_color":false,"enable_fixed_gallery_section_rtl_style":false,"enable_section_smart_binding":false,"enable_fixed_section_content_style_20251020":false,"enable_fixed_s6_transfer_2025112":false,"enable_fixed_mobile_section_style_20251103":false,"enable_fixed_mobile_section_style_20251117":false,"enable_section_padding_adjust":false,"enable_faq_text_color_adjust":true,"enable_new_luma_version":true,"enable_fixed_nav_special_logic_color":false,"enable_match_height_for_feature_list":true,"enable_tweaked_text_alignment":true,"enable_layout_setting_text_alignment":true,"enable_grid_slider_first_section_full_height":true,"enable_tweak_footer_hyperlink_color":true,"enable_slider_layout_c_content_align":false,"enable_form_alignment_fix":false,"optimizely":{"project_id":null,"experiment_id":null},"splash_screen_color":"#ffffff","id":32008750,"permalink":"obedient-zebra-nvv3q1","created_at":"2025-06-19T09:30:32.459-07:00","logo_url":"https:\/\/custom-images.strikinglycdn.com\/res\/hrscywv4p\/image\/upload\/c_limit,fl_lossy,h_630,w_1200,f_auto,q_auto\/18909116\/306189_941983.png","icon_url":"https:\/\/custom-images.strikinglycdn.com\/res\/hrscywv4p\/image\/upload\/c_limit,fl_lossy,h_64,w_64,q_auto\/18909116\/306189_941983.png","name":"Payslip generator","url_type":"subdomain_link","icp_filing_number":null,"psb_filing_number":null,"social_media_config":{"url":"https:\/\/payslip2.belgianblacksg.com\/","title":"Payslip generator","image":"https:\/\/custom-images.strikinglycdn.com\/res\/hrscywv4p\/image\/upload\/c_limit,fl_lossy,h_630,w_1200,f_auto,q_auto\/18909116\/306189_941983.png","description":"","fb_app_id":"138736959550286"},"keenio_config":{"keenio_project_id":"5317e03605cd66236a000002","keenio_write_key":"efd460f8e282891930ff1957321c12b64a6db50694fd0b4a01d01f347920dfa3ce48e8ca249b5ea9917f98865696cfc39bc6814e4743c39af0a4720bb711627d9cf0fe63d5d52c3866c9c1c3178aaec6cbfc1a9ab62a3c9a827d2846a9be93ecf4ee3d61ebee8baaa6a1d735bff6e37b"},"show_strikingly_logo":false,"show_navigation_buttons":false,"social_media":null,"has_optimizely":false,"optimizely_experiment_id":null,"services":[],"strk_upvt":"VTN1YkgwMmpkcWFPcFg2UXExYnJHU3FqL3JqbERJbGpRRnhBY3lpZnZnYUF1QUZTakFZRCtabENKVmlmY0tzZ1BEYWduaHFFTUNDSjVzSzQ5NjFnNmpZMVVuOVV2M3lOdGdLOTUwS0hwRjJLc0tONkZhQ3BNVjFYeWhhQ2dzdVlBbjk5a0RWcHZ0YnhjZHJIaXpDRWd4R0ZuZld5N0NxK3l5UDN6b0R1Vm84PS0tV2V6TTVyQzh1b3R4L1BIWWdQVkpsZz09--fbc54f8969d9d7144d0697dbabd748d4ad42bc83","strk_ga_tracker":"UA-25124444-6","google_analytics_tracker":null,"google_analytics_type":null,"exception_tracking":false,"ecommerce":{"seller_wechat_app_id":null,"has_set_payment_account":false},"customCodes":{},"hideDummyData":{"hideEcommerceDummyData":false,"hidePortfolioDummyData":false,"hideBlogDummyData":false,"hideBookingDummyData":false},"redirectUrls":[]},"blogCollection":{"data":{"blog":{"id":32008750,"blogSettings":{"previewLayout":1,"mailchimpCode":null},"blogPosts":[],"wechatMpAccountId":null,"pagination":{"blogPosts":{"currentPage":1,"previousPage":null,"nextPage":null,"perPage":20,"totalPages":0,"totalCount":0}}}}},"ecommerceProductCollection":{"data":{"products":[]}},"ecommerceCategoriesProductCollection":null,"portfolioCategoriesProductCollection":null,"portfolioProductCollection":{"data":{"products":[]}},"blogCategoriesPostCollection":null,"ecommerceProductOrderList":{},"ecommerceCategoryCollection":{"data":{"categories":[]}},"portfolioCategoryCollection":{"data":{"categories":[]}},"blogCategoryCollection":{},"eventTypeCategoryCollection":null};$S.blink={"page":{"logo_url":"https:\/\/custom-images.strikinglycdn.com\/res\/hrscywv4p\/image\/upload\/c_limit,fl_lossy,h_630,w_1200,f_auto,q_auto\/18909116\/306189_941983.png","weitie_url":"http:\/\/obedient-zebra-nvv3q1.weitie.co","description":"","name":"Payslip generator"},"conf":{"WECHAT_APP_ID":"wxd009fb01de1ec8b5"}}; //]]>