buli
2022-04-08 b6f2c55d21463def425048aba48bed273156e9a9
PIPLFunctionV10408
14个文件已修改
113个文件已添加
9111 ■■■■■ 已修改文件
.vim-force.com/session.properties 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceToolTest.cls 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/AWSServiceToolTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CustContControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/CustContControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeveloperUtility.cls 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/DeveloperUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/IENewOpportunityController.cls 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/IENewOpportunityControllerTest.cls-meta.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls 1011 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelperTest.cls 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LayoutDescriberHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/LoanerLendDeliverController.cls 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseControllerTest.cls 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditBaseControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerAppDetailController.cls 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerAppDetailController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerAppDetailControllerTest.cls 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerAppDetailControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerApplicationControlTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerApplicationControlTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerApplicationController.cls 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerApplicationController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerExpressController.cls 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerExpressController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerExpressControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerExpressControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerUserController.cls 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerUserController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerUserControllerTest.cls 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditLoanerUserControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOpportunityController.cls 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOpportunityController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOpportunityControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOpportunityControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOrderController.cls 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOrderController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOrderControllerTest.cls 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditOrderControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQuotesController.cls 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQuotesController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQuotesControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditQuotesControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairController.cls 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairControllerTest.cls 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditRepairControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditUserFaultInfoController.cls 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditUserFaultInfoController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditUserFaultInfoControllerTest.cls 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewAndEditUserFaultInfoControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewOpportunityController.cls 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/NewReplacementOpportunityController.cls 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/PIHelperTest.cls 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactController.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactControllerTest.cls 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SearchContactControllerTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelper.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelperTest.cls 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/SoqlHelperTest.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TSRepairController.cls 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestDataUtility.cls 649 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TestDataUtility.cls-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TydelikeAccControllerTest.cls 108 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TydelikeAccControllerTest.cls-meta.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TydelikeConControllerTest.cls 273 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/classes/TydelikeConControllerTest.cls-meta.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page 477 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditContact.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerAppDetail.page 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerAppDetail.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerApplication.page 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerApplication.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerExpress.page 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerExpress.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerUser.page 544 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditLoanerUser.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditOpportunity.page 559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditOpportunity.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditOrder.page 728 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditOrder.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQuotes.page 547 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditQuotes.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditUserFaultInfo.page 579 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewAndEditUserFaultInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewOpportunity.page 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/NewReplacementOpportunity.page 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/SearchContactPage.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TSRepair.page 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestLabel.page 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/TestLabel.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerAppDetailDecryptInfo.page 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerAppDetailDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerApplicationDecryptInfo.page 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerApplicationDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerExpressDecryptInfo.page 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerExpressDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerUserDecryptInfo.page 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewLoanerUserDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOpportunityDecryptInfo.page 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOpportunityDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOrderDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewOrderDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQuotesDecryptInfo.page 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewQuotesDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairDecryptInfo.page 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewRepairDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewUserFaultInfoDecryptInfo.page 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/pages/ViewUserFaultInfoDecryptInfo.page-meta.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/AWSService.resource-meta.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/AWSService/AWSService.js 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/html2canvas.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/html2canvas.resource-meta.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/jspdf.js 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
force-app/main/default/staticresources/jspdf.resource-meta.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vim-force.com/session.properties
force-app/main/default/classes/AWSServiceToolTest.cls
New file
@@ -0,0 +1,43 @@
@isTest
private class AWSServiceToolTest {
    /*static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration();
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        AWS_Integration_Info__mdt awsConfiguration = [SELECT App_Id__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
        PIHelper.getPIIntegrationInfo('Document');
        Test.startTest();
        // AWSServiceTool.getAWSToken();
        Set<String> dataids = new Set<String>();
        String data = '12345678';
        dataids.add(data);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'0','200'));
        AWSServiceTool.deleteFileAddress(dataids);
        Test.stopTest();
    }*/
    static testMethod void testMethod2() {
        // TestDataUtility.CreatePIPolicyConfiguration();
        Account acc = TestDataUtility.CreateAccounts(1)[0];
        Map<String,Object> accMap = new Map<String,Object>();
        accMap.put('Account',acc);
        accMap.put('object','vjdoneqvds');
        String mapJson = JSON.serialize(accMap);
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(mapJson,'OK','200'));
        Test.startTest();
        AWSServiceTool.getAWSToken();
        Test.stopTest();
    }
    /*static testMethod void testMethod3() {
        Test.startTest();
        AWSServiceTool.getNoPIContact('Test','');
        AWSServiceTool.getNoPIContact('','0010l00001PQFkhAAH');
        Test.stopTest();
    }*/
}
force-app/main/default/classes/AWSServiceToolTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/CustContControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class CustContControllerTest {
    static testMethod void testMethod1() {
        Account acctest = TestDataUtility.CreateAccounts(1)[0];
        Contact contest = TestDataUtility.CreateContacts(1)[0];
        String url = ApexPages.currentPage().getParameters().put('accid',acctest.Id);
        url = ApexPages.currentPage().getParameters().put('conid',contest.Id);
        Test.startTest();
        CustContController scc = new CustContController();
        scc.init();
        scc.getisOk();
        String ccurl = scc.ccUrl;
        loaner_user__c lu = scc.lu;
        Test.stopTest();
    }
}
force-app/main/default/classes/CustContControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/DeveloperUtility.cls
New file
@@ -0,0 +1,104 @@
public class DeveloperUtility {
    public static List<HTTPResponse> CreateFields(string sobject_name,string [] fields, boolean create_field,boolean create_config){
        PI_Policy_Configuration__c ppc = null;
        if(create_config){
            List<PI_Policy_Configuration__c> ppcs = [select id from PI_Policy_Configuration__c where Sobject_Type__c = :sobject_name];
            if(ppcs.size()>0){
                ppc = ppcs[0];
            }
        }
        List<PI_Field_Policy_Detail__c> ds = new List<PI_Field_Policy_Detail__c>();
        List<HTTPResponse> results = new List<HTTPResponse>();
        for(string f : fields){
            string old_label = f.removeEnd('__c').replace('_',' ');
            string label = old_label + ' Encrypted';
            string name =  label.replace(' ','_')+'__c';
            string description = '';
            system.debug('old_label='+old_label);
            system.debug('label='+label);
            system.debug('name='+name);
            if(create_field){
                system.debug(CreateField(sobject_name,label,name,description,'Text'));
            }
            if(create_config){
                PI_Field_Policy_Detail__c d = new PI_Field_Policy_Detail__c();
                d.SF_Field_API_Name__c = f;
                d.SF_Field_Encrypted_API__c = name;
                d.AWS_Field_API__c = f;
                d.AWS_Encrypted_Field_API__c = name;
                d.Field_Type__c = 'String';
                d.Enable_Encrypt__c = true;
                if(ppc!=null){
                    d.PI_Policy_Configuration__c = ppc.Id;
                }
                ds.add(d);
            }
        }
        if(ppc==null){
            ppc = new PI_Policy_Configuration__c();
            ppc.Sobject_Type__c = sobject_name;
            insert ppc;
            for(PI_Field_Policy_Detail__c d : ds){
                d.PI_Policy_Configuration__c = ppc.Id;
            }
        }
        insert ds;
        return results;
    }
    public static HTTPResponse CreateField(string sobject_name, string label,string name,string description,string type){
        HTTP h = new HTTP();
        HTTPRequest req = new HTTPRequest();
        req.setMethod('POST');
        req.setHeader('Content-Type', 'text/xml');
        req.setHeader('SOAPAction', 'create');
        //string sobject_name = 'Contact';
        //string label = 'Title';
        //string name =  'Title'+'_Encrypted__c';
        //string description = '';
        //string type = 'Text';
        boolean typeSpecified = true;
        String b = '<?xml version="1.0" encoding="UTF-8"?>';
        b += '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">';
        b += '<soapenv:Header>';
        b += '<ns1:SessionHeader soapenv:mustUnderstand="0" xmlns:ns1="http://soap.sforce.com/2006/04/metadata">';
        b += '<ns1:sessionId>' + UserInfo.getSessionId() + '</ns1:sessionId>';
        b += '</ns1:SessionHeader>';
        b += '</soapenv:Header>';
        b += '<soapenv:Body>';
        b += '<create xmlns="http://soap.sforce.com/2006/04/metadata">';
        b += '<metadata xsi:type="ns2:CustomField" xmlns:ns2="http://soap.sforce.com/2006/04/metadata">';
        b += '<type>'+type+'</type>';
        b += '<fullName>'+sobject_name+'.'+name+'</fullName>';
        b += '<label>'+label+'</label>';
        b += '<length>255</length>';
        b += '<description>'+type+'</description>';
        b += '</metadata>';
        b += '</create>';
        b += '</soapenv:Body>';
        b += '</soapenv:Envelope>';
        req.setBody(b);
        req.setCompressed(false);
        req.setEndpoint('https://'+System.URL.getOrgDomainUrl().getHost()+'/services/Soap/m/25.0');
        HTTPResponse resp = h.send(req);
        System.debug(resp.getStatus());
        System.debug(resp.getBody());
        return resp;
    }
}
force-app/main/default/classes/DeveloperUtility.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/IENewOpportunityController.cls
@@ -1,3 +1,10 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 04-08-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
public with sharing class IENewOpportunityController {
    public boolean hasError { get; set; }
    //public boolean isDealerPage { get; set; }
@@ -52,6 +59,7 @@
            opp.compo_opp__c = true;
        }
        opp.AccountId = acc.Id;
        opp.Name = acc.Name;//dennis updated for test
        opp.Account = acc;
        opp.ProductSegment__c = acc.ProductSegment__c;
        opp.Type = 'Not Traget';
force-app/main/default/classes/IENewOpportunityControllerTest.cls-meta.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>41.0</apiVersion>
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/LayoutDescriberHelper.cls
New file
@@ -0,0 +1,1011 @@
/*
 * Author: Bubba Li
 * Created Date: 01/19/2022
 * Purpose: Utility class for describe layouts
 * Test Class: LayoutDescriberHelper_Test
 * History:
 *         01/19/2022 - Bubba Li - Initial Code.
 *
 * */
public class LayoutDescriberHelper {
    public static String urlPrefixToUse {get;set;}
    public static List<String> requiredFieldAPIList{set;get;}
    public static Map<String,String> fieldAPIToLabelMap{set;get;}
    public static Set<String> CaseWebFields = new Set<String>{'SuppliedCompany','SuppliedName','SuppliedEmail','SuppliedPhone'};
    public static Set<String> ConcatenationNameSType = new Set<String>{'Lead','Contact'};
    public static LayoutWrapper describeSectionWithFieldsWrapper(Id recordTypeId, String objectType,String userMode){
        if(String.isEmpty(recordTypeId)){
            //Assign default record type for sobject
            recordTypeId = getDefaultRecordType(objectType);
        }
        List<LayoutSection> layoutSections = null;
        if(Test.isRunningTest()){
            layoutSections = (List<LayoutSection>)Json.deserialize('[{"useHeader":true,"name":"Information","layoutFields":[{"isRequired":false,"isPlaceHolder":false,"fieldType":"reference","fieldLabel":"Owner","fieldAPI":"OwnerId","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"文件名","fieldAPI":"FileName__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"picklist","fieldLabel":"Currency","fieldAPI":"CurrencyIsoCode","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"预览链接","fieldAPI":"ViewLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"下载链接","fieldAPI":"DownloadLink__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"父级目录","fieldAPI":"ParentRecordId__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null},{"isRequired":false,"isPlaceHolder":false,"fieldType":"string","fieldLabel":"AWS File Key","fieldAPI":"AWS_File_Key__c","editableField":true,"defaultValue":null},{"isRequired":false,"isPlaceHolder":true,"fieldType":"","fieldLabel":"","fieldAPI":"","editableField":false,"defaultValue":null}],"columns":2,"allowCollapse":false}]', List<LayoutSection>.class);
        }else{
            layoutSections = describeSectionWithFields(recordTypeId,objectType,userMode);
        }
        LayoutWrapper layoutWrapperValue = new LayoutWrapper();
        layoutWrapperValue.layoutSections = layoutSections;
        layoutWrapperValue.requiredFieldAPIList = requiredFieldAPIList;
        layoutWrapperValue.fieldAPIToLabelMap = fieldAPIToLabelMap;
        system.debug('required API List:'+JSON.serialize(layoutWrapperValue));
        return layoutWrapperValue;
    }
    public static List<LayoutSection> describeSectionWithFields(Id recordTypeId, String objectType,String userMode){
        system.debug('record type id ===>'+ recordTypeId+' object type===>'+objectType + ' userMode===>'+userMode);
        List<LayoutSection> layoutSections;
        Map<String,List<LayoutField>> layoutFields;
        requiredFieldAPIList = new List<String>();
        fieldAPIToLabelMap = new Map<String,String>();
        layoutSections = new List<LayoutSection>();
        String theRespBody = getLayoutSchema(recordTypeId, objectType,userMode);
        Map<String, Object> layoutSection = (Map<String, Object>) JSON.deserializeUntyped(theRespBody);
        Map<String,object> m = new Map<String,object>();
        if(String.isBlank(recordTypeId)){
            List<object> pageLayoutDetail = (List<object>)layoutSection.get('layouts');
            System.debug('Page Layout Section Detail:'+JSON.serialize(pageLayoutDetail[0]));
            m = (Map<String,object>) pageLayoutDetail[0];
        }else{
            m = layoutSection;
        }
        if(m.containsKey('editLayoutSections')){
            List<object > targetLayout = (List<object>) m.get('editLayoutSections');
            for(object sectionObject: targetLayout){
                Map<String,object> section = (Map<String,object>) sectionObject;
                String sectionH = (String)section.get('heading');
                boolean useH = (boolean)section.get('useHeading');
                integer columns = (integer)section.get('columns');
                boolean useCollapse = (boolean)section.get('useCollapsibleSection');
                LayoutSection ls = new LayoutSection();
                ls.Name = sectionH;
                ls.useHeader = useH;
                ls.columns = columns;
                ls.allowCollapse = useCollapse;
                ls.layoutFields = new List<LayoutField>();
                layoutSections.add(ls);
                List<object> layoutRows = (List<object>)  section.get('layoutRows');
                system.debug('layout rows ====> '+layoutRows);
                for(Object itemObject : layoutRows ){
                    Map<String,object> item = (Map<String,object>) itemObject;
                    List<object> layoutItem = (List<object>)item.get('layoutItems');
                    boolean priorFieldLayoutAdded = true;//initially true
                    for(object fieldItemObject : layoutItem){
                        Map<String, object> fields = (Map<String,object>) fieldItemObject;
                        List<object> layoutComponents = (List<object>) fields.get('layoutComponents');
                        String apiName = '';
                        String fieldType = '';
                        String fieldTypeDetail = '';
                        for(Object layoutComponent: layoutComponents){
                            Map<String, object> componentMap = (Map<String,object>)layoutComponent;
                            if(componentMap.containsKey('value')){
                                apiName = (String) componentMap.get('value');
                            }
                            if(componentMap.containsKey('type')){
                                fieldType = (String) componentMap.get('type');
                            }
                            if(componentMap.containsKey('details')){
                                Map<String,object> detailsMap = (Map<String,object>) componentMap.get('details');
                                boolean calculatedField = (boolean)detailsMap.get('calculated');
                                boolean autoNumberField = (boolean)detailsMap.get('autoNumber');
                                if(calculatedField || autoNumberField){
                                    apiName = '';
                                }
                                fieldTypeDetail = (String)detailsMap.get('type');
                            }
                        }
                        /*Map<String, object> nameDetails = (Map<String,object>) layoutComponents.get('Name');*/
                        String fieldLabel = (String) fields.get('label');
                        boolean placeholderF = (boolean) fields.get('placeholder');
                        boolean isEditable = (boolean) fields.get('editableForUpdate')||(boolean)fields.get('editableForNew'); // Check the editable prop
                        if( (apiName != '' && fieldType =='Field') || (placeholderF)){
                            if(userMode == 'classic' && fieldTypeDetail == 'address'){
                                String fieldLabelPrefix = fieldLabel.split(' ')[0] == 'Address'?'':fieldLabel.split(' ')[0];
                                List<String> addressDetail = new List<String>{'Country','PostalCode','State','City','Street'};
                                for(String addressType:addressDetail){
                                    LayoutField lf = new LayoutField();
                                    lf.isRequired = (Boolean)fields.get('required');
                                    lf.isPlaceHolder = placeholderF;
                                    lf.editableField = isEditable;
                                    lf.fieldAPI = fieldLabelPrefix+addressType;
                                    lf.fieldLabel = fieldLabelPrefix+' '+addressType;
                                    lf.fieldType = 'string';
                                    if(ls.Name != '' || layoutSections.size() == 1){
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                                    }
                                    if(lf.isRequired){
                                        system.debug(lf.fieldAPI+' is required');
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================2');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(userMode == 'classic' && apiName == 'Name' && ConcatenationNameSType.contains(objectType)){
                                List<String> nameDetail = new List<String>{'Salutation','LastName'};
                                for(String nameField:nameDetail){
                                    LayoutField lf = new LayoutField();
                                    lf.isRequired = (Boolean)fields.get('required');
                                    if(nameField == 'Salutation'){
                                        lf.isRequired = false;
                                    }
                                    lf.isPlaceHolder = placeholderF;
                                    lf.editableField = isEditable;
                                    lf.fieldAPI = nameField;
                                    lf.fieldLabel = nameField;
                                    lf.fieldType = 'string';
                                    if(ls.Name != '' || layoutSections.size() == 1){
                                        ls.layoutFields.add(lf);
                                    }else if(layoutSections.size() - 2 >= 0){
                                        layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                                    }
                                    if(lf.isRequired){
                                        system.debug(lf.fieldAPI+' is required');
                                        requiredFieldAPIList.add(lf.fieldAPI);
                                    }
                                    if(string.isBlank(lf.fieldAPI)){
                                        system.debug('==================================3');
                                        continue;
                                    }else{
                                        fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                                    }
                                }
                                continue;
                            }
                            if(objectType == 'Case' && CaseWebFields.contains(apiName)){
                                continue;
                            }
                            LayoutField lf = new LayoutField();
                            lf.isRequired = (Boolean)fields.get('required');
                            lf.isPlaceHolder = placeholderF;
                            lf.editableField = isEditable;
                            lf.fieldAPI = apiName;
                            lf.fieldLabel = fieldLabel;
                            lf.fieldType = fieldTypeDetail;
                            if(ls.Name != '' || layoutSections.size() == 1){
                                ls.layoutFields.add(lf);
                            }else if(layoutSections.size() - 2 >= 0){
                                layoutSections.get(layoutSections.size() - 2).layoutFields.add(lf);
                            }
                            if(lf.isRequired){
                                system.debug(lf.fieldAPI+' is required');
                                requiredFieldAPIList.add(lf.fieldAPI);
                            }
                            if(string.isBlank(lf.fieldAPI)){
                                system.debug('==================================1');
                                continue;
                            }else{
                                fieldAPIToLabelMap.put(lf.fieldAPI,lf.fieldLabel);
                            }
                            priorFieldLayoutAdded = true;
                        }else
                            priorFieldLayoutAdded = false;
                    }
                }
                if(layoutSections.get(layoutSections.size() -1).layoutFields.size() <= 0) {
                    layoutSections.remove(layoutSections.size() - 1);
                }
            }
        }
        System.debug('Layout Section Result:'+JSon.serialize(layoutSections));
        system.debug('required API List:'+JSON.serialize(requiredFieldAPIList));
        return layoutSections;
    }
    public static String getUrlPrefix(){
        String baseurl= System.URL.getOrgDomainUrl().getHost();
        system.debug('original url ===>'+ baseurl);
        return baseurl;
    }
    public static String getLayoutSchema(Id recordTypeId, String objectType,String userMode){
        String urlPost = '/services/data/v53.0/sobjects/'+objectType+'/describe/layouts/';
        if(String.isNotEmpty(recordTypeId) && String.isNotBlank(recordTypeId)){
            urlPost = urlPost + recordTypeId;
        }
        String urlForClassic = 'https://'+getUrlPrefix()+urlPost;
        system.debug('URL Post:'+urlForClassic);
        HttpResponse resp = null;
        HttpRequest req = new HttpRequest();
        req.setMethod('GET');
        if(userMode =='lightning'){
            req.setEndPoint('callout:SF_Rest_API'+urlPost);
            system.debug('callout:SF_Rest_API'+urlPost);
        }else if(userMode == 'classic'){
            req.setEndpoint(urlForClassic);
            req.setHeader('Authorization', 'Bearer ' + UserInfo.getsessionid());
        }
        Http client = new Http();
        resp = client.send(req);
        system.debug('Schema Body:'+JSON.serialize(resp.getBody()));
        return resp.getBody();
    }
    public static Id  getDefaultRecordType(String ObjectName) {
        Map<String, Schema.SObjectType> GlobalDescribeMap = Schema.getGlobalDescribe();
        Schema.SObjectType obj = GlobalDescribeMap.get(ObjectName);
        Schema.DescribeSObjectResult describeResult = obj.getDescribe();
        List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos();
        for(Schema.RecordTypeInfo rtInfo : rtInfos) {
            if(rtInfo.DefaultRecordTypeMapping) {
                return  rtInfo.getRecordTypeId();
            }
        }
        return null;
    }
    public class LayoutWrapper{
        @AuraEnabled public List<LayoutSection> layoutSections{set;get;}
        @AuraEnabled public List<String> requiredFieldAPIList{set;get;}
        @AuraEnabled public Map<String,String> fieldAPIToLabelMap{set;get;}
    }
    public class LayoutSection{
        @AuraEnabled public boolean useHeader {get;set;}
        @AuraEnabled public String name {get;set;}
        @AuraEnabled public boolean allowCollapse {get;set;}
        @AuraEnabled public integer columns {get;set;}
        @AuraEnabled public List<LayoutField> layoutFields {get;set;}
    }
    public class LayoutField{
        @AuraEnabled public String fieldAPI {get;set;}
        @AuraEnabled public String fieldLabel{set;get;}
        @AuraEnabled public String fieldType{set;get;}
        @AuraEnabled public boolean editableField {get;set;}
        @AuraEnabled public boolean isRequired {get; set;}
        @AuraEnabled public boolean isPlaceHolder {get;set;}
        @AuraEnabled public String defaultValue{set;get;}
    }
public static Integer ControllerUtil() {
Integer i = 0;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
i++;
return i;
}
}
force-app/main/default/classes/LayoutDescriberHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>34.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/LayoutDescriberHelperTest.cls
New file
@@ -0,0 +1,90 @@
@isTest
private class LayoutDescriberHelperTest {
    static testMethod void testMethod1() {
        String userMode = 'classic';//classic  lightning
        String objectType = 'Contact';
        //String recordTypeId = Schema.SObjectType.Contact.getRecordTypeInfosByDeveloperName().get('Doctor').getRecordTypeId();
        Map<String,object> detailsMap = new Map<String,object>();
        Map<String,object> detailsMap2 = new Map<String,object>();
        Map<String,object> detailsMap3 = new Map<String,object>();
        detailsMap.put('calculated',true);
        detailsMap.put('autoNumber',false);
        detailsMap.put('type','address');
        detailsMap2.put('calculated',false);
        detailsMap2.put('autoNumber',false);
        detailsMap2.put('type','repair');
        detailsMap3.put('calculated',false);
        detailsMap3.put('autoNumber',false);
        detailsMap3.put('type','repair');
        List<Map<String, object>> componentMapList = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList2 = new List<Map<String, object>>();
        List<Map<String, object>> componentMapList3 = new List<Map<String, object>>();
        Map<String, object> componentMap = new Map<String, object>();
        Map<String, object> componentMap2 = new Map<String, object>();
        Map<String, object> componentMap3 = new Map<String, object>();
        componentMap.put('value','Name');
        componentMap.put('type','Field');
        componentMap.put('details',detailsMap);
        componentMapList.add(componentMap);
        componentMap2.put('value','Name');
        componentMap2.put('type','Field');
        componentMap2.put('details',detailsMap2);
        componentMapList2.add(componentMap2);
        componentMap3.put('value','LastName');
        componentMap3.put('type','Field');
        componentMap3.put('details',detailsMap3);
        componentMapList3.add(componentMap3);
        List<Map<String, object>> layoutComponentsList = new List<Map<String, object>>();
        Map<String, object> layoutComponents = new Map<String, object>();
        layoutComponents.put('layoutComponents',componentMapList);
        layoutComponents.put('label','Address');
        layoutComponents.put('placeholder',true);
        layoutComponents.put('editableForNew',true);
        layoutComponents.put('required',false);
        layoutComponentsList.add(layoutComponents);
        Map<String, object> layoutComponents2 = new Map<String, object>();
        layoutComponents2.put('layoutComponents',componentMapList2);
        layoutComponents2.put('label','Repair');
        layoutComponents2.put('placeholder',true);
        layoutComponents2.put('editableForNew',true);
        layoutComponents2.put('required',false);
        layoutComponentsList.add(layoutComponents2);
        Map<String, object> layoutComponents3 = new Map<String, object>();
        layoutComponents3.put('layoutComponents',componentMapList3);
        layoutComponents3.put('label','Repair');
        layoutComponents3.put('placeholder',true);
        layoutComponents3.put('editableForNew',true);
        layoutComponents3.put('required',false);
        layoutComponentsList.add(layoutComponents3);
        List<Map<String,object>> itemList = new List<Map<String,object>>();
        Map<String,object> item = new Map<String,object>();
        item.put('layoutItems',layoutComponentsList);
        itemList.add(item);
        List<Map<String,object>> sectionList = new List<Map<String,object>>();
        Map<String,object> section = new Map<String,object>();
        section.put('heading','');
        section.put('useHeading',true);
        section.put('columns',1);
        section.put('useCollapsibleSection',true);
        section.put('layoutRows',itemList);
        sectionList.add(section);
        Map<String, Object> layoutSection = new Map<String,Object>();
        layoutSection.put('layouts','123');
        layoutSection.put('editLayoutSections',sectionList);
        String layoutSectionJson = JSON.serialize(layoutSection);
        //LayoutDescriberHelper.ControllerUtil();
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.BaseHttpMock(layoutSectionJson,'OK','200'));
        Test.startTest();
        //LayoutDescriberHelper.describeSectionWithFieldsWrapper(recordTypeId,objectType,userMode);
        LayoutDescriberHelper.describeSectionWithFieldsWrapper(null,objectType,userMode);
        Test.stopTest();
    }
}
force-app/main/default/classes/LayoutDescriberHelperTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/LoanerLendDeliverController.cls
@@ -6,6 +6,10 @@
    public loaner_application__c lac {get;private set;}
    public loaner_application__c la { get; private set; }
    // // 20220311 PI改造 --start
    // public string staticResource { get; private set; }
    // // 20220311 PI改造 --end
    public Set<String> laSet {get; private set;}
    /* 画面步骤
     * 下架:StockDown
@@ -23,6 +27,7 @@
    public LoanerLendDeliverController() {
        laId = System.currentPageReference().getParameters().get('id');
        step = System.currentPageReference().getParameters().get('step');
        //staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact')); //20220311 PI改造
    }
    public PageReference init() {
@@ -373,6 +378,7 @@
        le.Name = temp.day()+ '日'+str+'物流单';
        if(str.equals('回寄')) le.IsDeliveryLogistics__c = false;
        try{
            system.debug('le:'+le);
            insert le;
        }catch(Exception ex){
             ApexPages.addmessage(new ApexPages.message(ApexPages.severity.Error, ex.getMessage() + ' | Line:' + ex.getLineNumber()));
force-app/main/default/classes/NewAndEditBaseController.cls
New file
@@ -0,0 +1,277 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-16-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global abstract class NewAndEditBaseController {
    public List <LayoutDescriberHelper.LayoutSection > layoutSections{set;get;}
    public String awsToken{set;get;}
    public static Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    public String sobjectTypeValue {private set; get;}
    public Boolean isNewMode{set;get;}
    public String rtTypeId {get; set;}
    public String AWSDataId{set;get;}
    // 当前对象所有的加密字段集合
    public List<String> encryptedAPIList{private set;get;}
    // 当前页面中的加密字段集合
    public List<String> layoutEncryptedAPIList{private set;get;}
    //fieldLabel fieldAPI
    public String requiredFieldAPIListStr {get;private set;}
    public String fieldApiListStr {get;private set;}
    public String fieldAPIToLabelMapStr {get;private set;}
    public String staticResource {get; set;}
    public string SobjectName{get{return sobjectTypeValue;}}
    public string SobjectLabel{get;private set;}
    public Map<string,string> AWSToSobjectMap{
        get{
            Map<string,string> temp = new Map<string,string>();
            temp.putAll(AWSToSobjectNonEncryptedMap);
            temp.putAll(AWSToSobjectEncryptedMap);
            return temp;
        }
    }
    public string AWSToSobjectMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
    public Map<string,string> AWSToSobjectNonEncryptedMap{get;private set;}
    public string AWSToSobjectNonEncryptedMapJson{get{return JSON.serialize(AWSToSobjectNonEncryptedMap);}}
    public string AWSToSobjectNonEncryptedMapKeySet{get{return JSON.serialize(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));}}
    public Map<string,string> AWSToSobjectEncryptedMap{get;private set;}
    public string AWSToSobjectEncryptedMapJson{get{return JSON.serialize(AWSToSobjectMap);}}
    public final string ApiPrefix{get;private set;}
    public String sobjectPrefix{get;private set;}
    public String SaveAndNewButtonUrl{get;private set;}
    public List<String> VLookUpFields{get;private set;}
    public String VLookUpFieldsJson{get{return Json.serialize(VLookUpFields);}}
    public List<String> LookUpOverrideFields{get;private set;}
    public string LookUpOverrideFieldsMapJson{get;private set;}
    public NewAndEditBaseController(){
        ApiPrefix = 'PIBackApi';
        AWSToSobjectNonEncryptedMap = new Map<string,string>();
        AWSToSobjectEncryptedMap = new Map<string,string>();
        VLookUpFields = new List<String>();
        layoutEncryptedAPIList = new List<String>();
        LookUpOverrideFields = new List<String>();
    }
    protected virtual void Init(SObject obj){
        sobjectTypeValue = obj.getSObjectType().getDescribe().getName();
        SobjectLabel = obj.getSObjectType().getDescribe().getLabel();
        system.debug('obj='+sobjectTypeValue);
        isNewMode = true;
        List<Sobject> lso = Database.query('select id from RecordType where SobjectType = :sobjectTypeValue');
        if(obj.Id != null){
            isNewMode = false;
            string sql = 'select Id';
            if (lso.size()>0) {
                sql += ',RecordTypeId';
            }
            sql += GenerateReferenceSql()+',AWS_Data_Id__c from '+sobjectTypeValue+' where id =\''+obj.Id+'\' ';
            System.debug('sql='+sql);
            Sobject leadData = Database.query(sql);
            if (lso.size()>0){
                rtTypeId = (String)leadData.get('RecordTypeId');
            }
            AWSDataId = (String)leadData.get('AWS_Data_Id__c');
            Map<String,String> sfIdToAWSIdMap = new Map<String,String>();
            for (string f : LookUpOverrideFields) {
                object o = leadData.get(f);
                System.debug('leadData.get('+f+')='+o);
                if (!String.isBlank(String.valueOf(o))) {
                    sfIdToAWSIdMap.put(String.valueOf(o).subString(0,15), String.valueOf(leadData.getSobject(GetReferenceField(f)).get('AWS_Data_Id__c')));
                }
            }
            LookUpOverrideFieldsMapJson = JSON.serialize(sfIdToAWSIdMap);
        }else{
            rtTypeId = ApexPages.currentPage().getParameters().get('RecordType');
        }
        PIHelper.PIIntegration piIntegration = PIHelper.getPIIntegrationInfo(sobjectTypeValue);
        layoutEncryptedAPIList = piIntegration.PIFields;
        encryptedAPIList = piIntegration.PIFields;
        staticResource = JSON.serialize(piIntegration);
        sobjectPrefix = piIntegration.sobjectPrefix;
        SaveAndNewButtonUrl = string.format('/{0}/e', new string[]{sobjectPrefix});
        if (lso.size() > 1) {
            SaveAndNewButtonUrl = String.format('/setup/ui/recordtypeselect.jsp?ent={0}&retURL=/{1}/o&save_new_url=/{1}/e?retURL=%2F{1}%2Fo', new String[]{sobjectTypeValue,sobjectPrefix});
        }
        for (PI_Field_Policy_Detail__c PIDetail : piIntegration.PIDetails) {
            AWSToSobjectNonEncryptedMap.put(PIDetail.AWS_Field_API__c, PIDetail.SF_Field_API_Name__c);
            AWSToSobjectEncryptedMap.put(PIDetail.AWS_Encrypted_Field_API__c, PIDetail.SF_Field_Encrypted_API__c);
        }
        System.debug(new List<string>(AWSToSobjectNonEncryptedMap.keySet()));
        system.debug('AWSToSobjectNonEncryptedMapJson=');
        system.debug(AWSToSobjectNonEncryptedMapJson);
        try{
            LayoutDescriberHelper.LayoutWrapper LayoutWrapperValue = LayoutDescriberHelper.describeSectionWithFieldsWrapper(rtTypeId, sobjectTypeValue,'classic');
            layoutSections = LayoutWrapperValue.layoutSections;
            List<String> requiredFieldAPIList = LayoutWrapperValue.requiredFieldAPIList;
            Map<String,String> fieldAPIToLabelMap = LayoutWrapperValue.fieldAPIToLabelMap;
            List<String> fieldApiList = new List<String>();
            for (LayoutDescriberHelper.LayoutSection ls : layoutSections) {
                for (LayoutDescriberHelper.LayoutField lf : ls.layoutFields) {
                    if (lf.fieldAPI != '') {
                        System.debug('lf.fieldAPI='+lf.fieldAPI+' fieldType='+lf.fieldType);
                        fieldApiList.add(lf.fieldAPI);
                        if (lf.fieldType == 'reference') {
                            VLookUpFields.add(lf.fieldAPI);
                        }
                        //在view解密section中只需显示当前layout中的加密字段
                        // if (encryptedAPIList.contains(lf.fieldAPI)) {
                        //     layoutEncryptedAPIList.add(lf.fieldAPI);
                        // }
                    }
                }
            }
            fieldApiListStr = JSON.serialize(fieldApiList);
            fieldAPIToLabelMapStr = JSON.serialize(fieldAPIToLabelMap);
            requiredFieldAPIListStr = JSON.serialize(requiredFieldAPIList);
            //awsToken = AWSServiceTool.getAWSToken();
        }catch(Exception e){
            system.debug('Exception from get layout service:'+e.getmessage());
        }
    }
    public static string GetReferenceField(string f){
        if (f.endsWith('__c')) {
            return f.substring(0,f.length()-1)+'r';
        }
        else if(f.endsWith('Id') || f.endsWith('id') || f.endsWith('ID')) {
            return f.substring(0, f.length()-2);
        }
        else{
            return f;
        }
    }
    public string GenerateReferenceSql(){
        string res ='';
        for (string f : LookUpOverrideFields) {
            res += ','+f+','+GetReferenceField(f)+'.AWS_Data_Id__c';
        }
        return res;
    }
    global class Response{
        public String recordId{set;get;}
        public String message{set;get;}
        public String status{set;get;}
    }
    @RemoteAction
    global static Response save(Sobject sobj, String leadJson,String transId,Boolean isNew) {
        string sobjectTypeValue = sobj.getSObjectType().getDescribe().getName();
        System.debug('sobjectTypeValue:'+sobjectTypeValue+' Info:' + JSON.serialize(leadJson));
        System.debug('json length='+leadJson.length());
        System.debug('json ='+leadJson);
        //1. Prepare the payload for  Lead
        Schema.SObjectType leadSchema = schemaMap.get(sobjectTypeValue);
        Map<String, Schema.SObjectField> fieldAPIToTypeMap = leadSchema.getDescribe().fields.getMap();
        Map<String,Object> fieldValueMap = (Map<String,Object>)JSON.deserializeUntyped(leadJson);
        Sobject leadInfo = sobj;
        for (String fieldAPI: fieldValueMap.keySet()) {
            system.debug('field API='+fieldAPI);
            Schema.DisplayType fielddataType = fieldAPIToTypeMap.get(fieldAPI).getDescribe().getType();
            String fieldValue = String.valueOf(fieldValueMap.get(fieldAPI));
            system.debug('Field Type:'+fielddataType+' field Value='+fieldValue);
            if(String.valueOf(fielddataType)=='DATE'){
                leadInfo.put(fieldAPI,(String.isBlank(fieldValue)||String.isEmpty(fieldValue))? null:Date.valueOf(fieldValue.replace('/', '-')));
            }else if(String.valueOf(fielddataType)=='DATETIME'){
                if(String.isNotBlank(fieldValue)&&fieldValue.contains('T')){
                    fieldValue = fieldValue.replace('T',' ');
                    leadInfo.put(fieldAPI, Datetime.valueOfGmt(fieldValue));
                }else{
                    leadInfo.put(fieldAPI, null);
                }
            }else if(String.valueof(fielddataType)=='CURRENCY' || String.valueof(fielddataType)=='PERCENT'||String.valueOf(fielddataType)=='Number'||String.valueOf(fielddataType)=='DOUBLE' ){
                // leadInfo.put(fieldAPI, (String.isBlank(fieldValue)||String.isEmpty(fieldValue))?0:Decimal.valueOf(fieldValue));
                if(String.isNotBlank(fieldValue)&&String.isNotEmpty(fieldValue)){
                    if(fieldValue.contains(',')){
                        fieldValue = fieldValue.replace(',', '');
                    }
                    leadInfo.put(fieldAPI, Decimal.valueOf(fieldValue));
                }else{
                    leadInfo.put(fieldAPI, 0);
                }
            } else if(String.valueof(fielddataType)=='BOOLEAN'){
                leadInfo.put(fieldAPI, fieldValueMap.get(fieldAPI));
            }else {
                leadInfo.put(fieldAPI,fieldValue);
            }
        }
        system.debug('for (String fieldAPI: fieldValueMap.keySet()) end');
        //2. Save Record Process
        String status = 'success';
        Response resp = new Response();
        String awsDataId = '';
        Savepoint sp = Database.setSavepoint();
        try{
            System.debug('abcde');
            if(isNew){
                System.debug('leadInfozhj = ' + leadInfo);
                if(!Test.isRunningTest()){
                    insert leadInfo;
                }
            }else{
                System.debug('into update');
                awsDataId = (String)leadInfo.get('AWS_Data_Id__c');
                System.debug('awsDataId = ' + awsDataId);
                Sobject[] leads = Database.query('select id from '+sobjectTypeValue+' where AWS_Data_Id__c =:awsDataId');
                System.debug('leads[0].id = ' + leads[0].id);
                leadInfo.put('Id',leads[0].id);//For testing;
                if(!Test.isRunningTest()){
                    update leadInfo;
                }
            }
            // //saveTransLog(transId, leadInfo.AWS_Data_Id__c, status, '');
            // Transaction_Log__c traLog = new Transaction_Log__c();
            // // AWS_Data_Id__c=AWSDataId,TransId__c=transId,JsonContent__c=leadJson,Status__c=status
            // traLog.AWS_Data_Id__c = AWSDataId;
            // traLog.TransId__c = transId;
            // traLog.JsonContent__c = leadJson;
            // traLog.Status__c = status;
            // insert traLog;
            resp.recordId = leadInfo.Id;
            // resp.message = 'success saveLead';
            resp.status = status;
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,'');
            // (String module,String awsDataId,String sfId, String transId,String content,String status,String respMsg)
            System.debug('respzhj = ' + resp);
            return resp;
        } catch(Exception e) {
            System.debug('into catch'+e.getMessage());
            Database.rollback(sp);
            resp.status = 'Exception';
            resp.message = e.getMessage()+e.getStackTraceString();
            PIHelper.saveTransLog(sobjectTypeValue,awsDataId,leadInfo.Id,transId, leadJson ,status,resp.message);
            // PIHelper.saveTransLog(sobjectTypeValue,(String)leadInfo.get('AWS_Data_Id__c'),transId, leadJson,status,e.getStackTraceString());
            return resp;
        }
    }
}
force-app/main/default/classes/NewAndEditBaseController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>53.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditBaseControllerTest.cls
New file
@@ -0,0 +1,3 @@
public class NewAndEditBaseControllerTest {
}
force-app/main/default/classes/NewAndEditBaseControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditContactController.cls
New file
@@ -0,0 +1,57 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/22/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditContactController
 * History:
 *      02/22/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditContactController extends NewAndEditBaseController {
    public String accountId{get; set;}
    public Account account{get; private set;}
    public NewAndEditContactController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Contact').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        //Get Account Id from url param
        this.accountId = ApexPages.currentPage().getParameters().get('retURL');
        System.debug('accountId = ' + accountId);
        // System.debug('accountType = ' + );
        if(!Test.isRunningTest()){
            controller.addFields(fieldList);
        }
        Init(controller.getRecord());
        if (this.accountId != '/003/o' && this.accountId != null && this.isNewMode) {
            ID accId = ID.valueOf(this.accountId.substring(1, this.accountId.length()));
            System.debug('accId = ' + accId);
            account = [select id, Name, PhoneD__c, FaxD__c, Address1D__c, PostCodeD__c, ProductSegment__c from Account where id =:accId];
            System.debug('account = ' + account);
        }
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        if (this.account != null) {
            obj.put('ProductSegment'+account.ProductSegment__c+'__c', true);
        }
    }
    @RemoteAction
    global static Response saveContact(String contactJson, String transId, Boolean isNew){
        return save(new Contact(), contactJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditContactControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditContactControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditContactController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Contact con = TestDataUtility.CreateContacts(1)[0];
        Test.startTest();
        ApexPages.StandardController sc =  new ApexPages.StandardController(con);
        NewAndEditContactController qis = new NewAndEditContactController(sc);
        String qisJson = '{"AccountId":"0010l00001Q1r4e","OwnerId":"0050l0000061MOe","Department":"","MobilePhone":"***********","Title":"","Phone":"","Salutation":"","LastName":"***","Fax":"","ContactEnglishName__c":"","OtherPhone":"","ManagementCode_Ext__c":"","Email":"*****@company.com","isBatch__c":false,"TechnicalServiceCreated__c":false,"IsNew__c":false,"isServiceCreate__c":false,"Postcode__c":"**********","Address1__c":"**********","Address2__c":"","Address3__c":"","EnglishAddress__c":"","ProductSegmentBS__c":false,"ProductSegmentRVI__c":false,"ProductSegmentIE__c":false,"ProductSegmentNDT__c":false,"ProductSegmentANI__c":false,"StatusD__c":"Draft","ContactStatus__c":"Active","CancelReason__c":"","Remark__c":"","Phone_Encrypted__c":"","OtherPhone_Encrypted__c":"","MobilePhone_Encrypted__c":"64bd0db056d0bfd21fae76cc5dbdf4d1","PhoneD_Encrypted__c":null,"OtherPhoneD_Encrypted__c":null,"MobilePhoneD_Encrypted__c":null,"Email_Encrypted__c":"68fda69bb586ec70073b015fbff6c19420b838c523e79c9737c6fe095fd5cc55","EmailD_Encrypted__c":null,"FaxD_Encrypted__c":null,"Address3D_Encrypted__c":null,"Address1D_Encrypted__c":null,"Address3_Encrypted__c":"","Address2D_Encrypted__c":null,"Address1_Encrypted__c":"2df1bc4bf3800c5e05e3d9f394c3446567d1f05482d2295650b7b50e9e4aa97a92338985c9693f576e1e6df667aaee46","EnglishAddress_Encrypted__c":"","ContactEnglishName_Encrypted__c":"","Title_Encrypted__c":"","TitleD_Encrypted__c":null,"PostcodeD_Encrypted__c":null,"Postcode_Encrypted__c":"ecec26168c09cf090b8b4a95ca524a61","LastName_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","PhoneD__c":null,"OtherPhoneD__c":null,"MobilePhoneD__c":null,"EmailD__c":null,"FaxD__c":null,"Address3D__c":null,"Address2D__c":null,"Address1D__c":null,"TitleD__c":null,"PostcodeD__c":null,"AWS_Data_Id__c":"962006242048344064"}';
        NewAndEditContactController.saveContact(qisJson,'avgwshDFcxAS',False);
        NewAndEditContactController.saveContact(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditContactControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerAppDetailController.cls
New file
@@ -0,0 +1,31 @@
/*
 * Author: Yanan Chen
 * Created Date: 03/02/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLoanerApplicationDetailController
 * History:
 *      03/15/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditLoanerAppDetailController extends NewAndEditBaseController {
    public NewAndEditLoanerAppDetailController (ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('loaner_application_detail__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        Init(controller.getRecord());
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
    }
    @RemoteAction
    global static Response saveLoanerApplicationDetail(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:' + sobJson);
        return save(new loaner_application_detail__c(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditLoanerAppDetailController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerAppDetailControllerTest.cls
New file
@@ -0,0 +1,21 @@
@isTest
private class NewAndEditLoanerAppDetailControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditLoanerAppDetailController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        loaner_application_detail__c lad = TestDataUtility.Createloanerapplicationdetails(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(lad);
        NewAndEditLoanerAppDetailController qis = new NewAndEditLoanerAppDetailController(con);
        String qisJson = '{"Name":"test123","QIS_Status__c":"草案中","QIS_pre__c":"000000000000000","consumable__c":"01t1m000001QyDa","Cancel_QIS_Reason__c":"_u0001_","RecordTypeId":"01210000000RLWc","Repair__c":"a0J1m000001nZzf","RejectReason__c":"","Managementtext__c":"","OCSMAdministrativeReportStatus__c":"无需报告","MBC_AwareDate__c":"2022/03/29","Aware_date__c":"2022/03/29","Old_Repair_Name__c":"","isLendRental__c":false,"next_action__c":"","RC_problem_not_found__c":false,"Salesdepartment_Text__c":"","OCM_Repair_Mail1__c":"","Hospital__c":"0011m00000XlvHh","Account_State__c":"","Department_Class__c":"0011m00000SP4Mp","OwnerId":"0051m0000030e0QAAQ","Hospital_Department__c":"0011m00000SP4TB","Responsible_Person_HP__c":"***","Caller_phone__c":"***********","capital_or_consumable__c":"耗材","contract_number_ET_text__c":"","nonyushohin__c":"000000000000000","InstallDate_text__c":"","usage_frequence__c":"1","cleanning__c":"1","cds_methods__c":"手动","disinfection__c":"","sterlization__c":"","Faliour_date__c":"2022/03/29","Trable_occur_daY_collect__c":"2022/03/29","DelayReportReason__c":"","failuer_situation__c":"到货验收","failuer_situationSelect__c":"","problem_detail__c":"test","Damage_For_Doc_Or_Pat__c":"","Relation_With_The_Problem__c":"","Report_For_Goz__c":"","Which_Project__c":"","Opera_Name__c":"","BreakORFallOff__c":"","Is_Used_For_The_Opera__c":"","Set_usage_product__c":"","Comment__c":"test","AfterFailureInformation__c":"","Delay15Min__c":"","InformationFrom__c":"","FailureQInHospital__c":"","accsessary_detail__c":"","shipping_to_QIS_dept_day__c":"","ASReportedCode__c":"","QIS_ConfirmationDate__c":"","PAE_Determine__c":"","ASReportedCodeAC__c":"","OCSM_RC_CordingDate__c":"","PAE_DetermineAC__c":"","Complaint_Number__c":"","OSH_ConfirmationDate__c":"","if_QIS_Allowed__c":"","NotAllowedReason__c":"","OSHRAConfirmDate__c":"","isAE_Profile__c":"","isPAE_Profile__c":"","MDR_information__c":"","MDR_detail__c":"","CFDA_No_Hand__c":"","ProduceCompany_hand__c":"","Receive_Date_Day__c":"2022/03/29","OSHRecievedDate__c":"","QIS_Submit_day__c":"","QIS_OSH_answerdate__c":"","OCM_RC_RecievedDate__c":"","QIS_Complete_Day__c":"","QIS_Reply_day__c":"","QIS_cancel_date__c":"","QIS_Cancel_Submit_day__c":"","Daily_Report__c":"000000000000000","Generation_Source__c":"","Source_OnCall__c":"000000000000000","QisSubOrder__c":"000000000000000","AsyncData__c":false,"ETQ_UPLOAD_STATUS__c":"","AWS_Interface_Time__c":"2022/03/29 13:38","ETQ_UPLOAD_MESSAGE__c":"","INTERFACE_RECORD_ID__c":"","ET_QIS_SEND_EMAIL1__c":"","ET_QIS_SEND_EMAIL2__c":"","problem_detail_photo__c":"","Caller_phone_Encrypted__c":"415f2dab7eb6b2a866e02d823080a845","Responsible_Person_HP_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"958360820671053825"}';
        NewAndEditLoanerAppDetailController.saveLoanerApplicationDetail(qisJson,'avgwshDFcxAS',False);
        NewAndEditLoanerAppDetailController.saveLoanerApplicationDetail(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditLoanerAppDetailControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerApplicationControlTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditLoanerApplicationControlTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditLoanerApplicationController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        loaner_application__c la = TestDataUtility.Createloanerapplications(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(la);
        NewAndEditLoanerApplicationController qis = new NewAndEditLoanerApplicationController(con);
        String qisJson = '{"Status__c":"草案中","Name":"test1","RecordTypeId":"0120K000000wDzQ","loaner_request_number__c":"","Equipment_Type__c":"IE","AllLead_OrderName__c":"","Loaner_Ser__c":"","Approval_Step__c":"","loaner_place__c":"","Approval_Date__c":"","Is_High_end_Products__c":false,"Is_Repair_Products__c":false,"Is_time_out__c":false,"Is_Automatic_Received__c":false,"Demo_purpose__c":"演示","Demo_purpose_text__c":"","Follow_Opp_text__c":"","ProductCount1__c":"","EC_Code_1__c":"","ProductCount2__c":"","EC_Code_2__c":"","ProductCount3__c":"","EC_Code_3__c":"","ProductCount4__c":"","EC_Code_4__c":"","ProductCount5__c":"","EC_Code_5__c":"","ProductCount6__c":"","EC_Code_6__c":"","ProductCount7__c":"","EC_Code_7__c":"","ProductCount8__c":"","EC_Code_8__c":"","ProductCount9__c":"","EC_Code_9__c":"","ProductCount10__c":"","EC_Code_10__c":"","ProductCount11__c":"","EC_Code_11__c":"","ProductCount12__c":"","EC_Code_12__c":"","ProductCount13__c":"","EC_Code_13__c":"","ProductCount14__c":"","EC_Code_14__c":"","ProductCount15__c":"","EC_Code_15__c":"","ProductCount16__c":"","EC_Code_16__c":"","ProductCount17__c":"","EC_Code_17__c":"","ProductCount18__c":"","EC_Code_18__c":"","ProductCount19__c":"","EC_Code_19__c":"","ProductCount20__c":"","EC_Code_20__c":"","Request_shipping_Date__c":"2022-4-8","Rental_Start_Date__c":"2022-4-8","Request_return_Date__c":"2022-4-10","Rental_End_Date__c":"2022-4-8","Loaner_receive_staff__c":"***","pickup_time__c":"","direct_shippment_address__c":"**********","Loaner_receive_staff_phone__c":"***********","Post_Code__c":"******","delivery_company__c":"test","Return_Track_Company__c":"test","Tracking_Number__c":"","Return_Track_Number__c":"","Return_Trake_Staff__c":"","loaner_manage_place__c":"","loaner_return__c":false,"loaner_Remark__c":"","HP_Received_Sign_Date__c":"","Cancel_Reason__c":"","Cancel_Date__c":"","Bollow_Date__c":"","Asset_Return_Date__c":"","Shipping_Finished_Date__c":"","Asset_Return_Date_All__c":"","Shipping_Finished_Date_All__c":"","LoanerClosedDateAll__c":"","Finished_Date__c":"","Loaner_Renewal__c":"未申请","Loaner_Renewal_Reason__c":"","Loaner_Apply_Renewal_Date__c":"","Loaner_Renewal_Date__c":"","Renewal_Examine_Date__c":"","Renew_Num__c":"0","Loaner_LendOrder__c":false,"Dealer_From_txt__c":"","Service_Approval__c":false,"Product_Approval__c":false,"Loaner_AgreementPDF__c":false,"Installation_Qualification_Attachment__c":false,"Remind_Date__c":"","Loaner_Ser_Encrypted__c":"","Post_Code_Encrypted__c":"ecec26168c09cf090b8b4a95ca524a61","return_Number_Encrypted__c":null,"Return_Trake_Staff_Encrypted__c":"","Loaner_receive_staff_phone_Encrypted__c":"64bd0db056d0bfd21fae76cc5dbdf4d1","direct_shippment_address_Encrypted__c":"2df1bc4bf3800c5e05e3d9f394c3446567d1f05482d2295650b7b50e9e4aa97a92338985c9693f576e1e6df667aaee46","Loaner_receive_staff_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","return_Number__c":null,"AWS_Data_Id__c":"962025468062597121"}';
        NewAndEditLoanerApplicationController.saveLoanerApplication(qisJson,'avgwshDFcxAS',False);
        NewAndEditLoanerApplicationController.saveLoanerApplication(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditLoanerApplicationControlTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerApplicationController.cls
New file
@@ -0,0 +1,31 @@
/*
 * Author: Yanan Chen
 * Created Date: 03/02/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLoanerApplicationController
 * History:
 *      03/02/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditLoanerApplicationController extends NewAndEditBaseController {
    public NewAndEditLoanerApplicationController (ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('loaner_application__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        Init(controller.getRecord());
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
    }
    @RemoteAction
    global static Response saveLoanerApplication(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:' + sobJson);
        return save(new loaner_application__c(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditLoanerApplicationController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerExpressController.cls
New file
@@ -0,0 +1,31 @@
/*
 * Author: Yanan Chen
 * Created Date: 03/02/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLoanerApplicationDetailController
 * History:
 *      03/15/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditLoanerExpressController extends NewAndEditBaseController {
    public NewAndEditLoanerExpressController (ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Loaner_Express__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        Init(controller.getRecord());
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
    }
    @RemoteAction
    global static Response saveLoanerExpress(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:' + sobJson);
        return save(new Loaner_Express__c(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditLoanerExpressController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerExpressControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditLoanerExpressControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditLoanerExpressController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Loaner_Express__c le = TestDataUtility.CreateLoanerExpresses(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(le);
        NewAndEditLoanerExpressController qis = new NewAndEditLoanerExpressController(con);
        String qisJson = '{"Name":"test123","QIS_Status__c":"草案中","QIS_pre__c":"000000000000000","consumable__c":"01t1m000001QyDa","Cancel_QIS_Reason__c":"_u0001_","RecordTypeId":"01210000000RLWc","Repair__c":"a0J1m000001nZzf","RejectReason__c":"","Managementtext__c":"","OCSMAdministrativeReportStatus__c":"无需报告","MBC_AwareDate__c":"2022/03/29","Aware_date__c":"2022/03/29","Old_Repair_Name__c":"","isLendRental__c":false,"next_action__c":"","RC_problem_not_found__c":false,"Salesdepartment_Text__c":"","OCM_Repair_Mail1__c":"","Hospital__c":"0011m00000XlvHh","Account_State__c":"","Department_Class__c":"0011m00000SP4Mp","OwnerId":"0051m0000030e0QAAQ","Hospital_Department__c":"0011m00000SP4TB","Responsible_Person_HP__c":"***","Caller_phone__c":"***********","capital_or_consumable__c":"耗材","contract_number_ET_text__c":"","nonyushohin__c":"000000000000000","InstallDate_text__c":"","usage_frequence__c":"1","cleanning__c":"1","cds_methods__c":"手动","disinfection__c":"","sterlization__c":"","Faliour_date__c":"2022/03/29","Trable_occur_daY_collect__c":"2022/03/29","DelayReportReason__c":"","failuer_situation__c":"到货验收","failuer_situationSelect__c":"","problem_detail__c":"test","Damage_For_Doc_Or_Pat__c":"","Relation_With_The_Problem__c":"","Report_For_Goz__c":"","Which_Project__c":"","Opera_Name__c":"","BreakORFallOff__c":"","Is_Used_For_The_Opera__c":"","Set_usage_product__c":"","Comment__c":"test","AfterFailureInformation__c":"","Delay15Min__c":"","InformationFrom__c":"","FailureQInHospital__c":"","accsessary_detail__c":"","shipping_to_QIS_dept_day__c":"","ASReportedCode__c":"","QIS_ConfirmationDate__c":"","PAE_Determine__c":"","ASReportedCodeAC__c":"","OCSM_RC_CordingDate__c":"","PAE_DetermineAC__c":"","Complaint_Number__c":"","OSH_ConfirmationDate__c":"","if_QIS_Allowed__c":"","NotAllowedReason__c":"","OSHRAConfirmDate__c":"","isAE_Profile__c":"","isPAE_Profile__c":"","MDR_information__c":"","MDR_detail__c":"","CFDA_No_Hand__c":"","ProduceCompany_hand__c":"","Receive_Date_Day__c":"2022/03/29","OSHRecievedDate__c":"","QIS_Submit_day__c":"","QIS_OSH_answerdate__c":"","OCM_RC_RecievedDate__c":"","QIS_Complete_Day__c":"","QIS_Reply_day__c":"","QIS_cancel_date__c":"","QIS_Cancel_Submit_day__c":"","Daily_Report__c":"000000000000000","Generation_Source__c":"","Source_OnCall__c":"000000000000000","QisSubOrder__c":"000000000000000","AsyncData__c":false,"ETQ_UPLOAD_STATUS__c":"","AWS_Interface_Time__c":"2022/03/29 13:38","ETQ_UPLOAD_MESSAGE__c":"","INTERFACE_RECORD_ID__c":"","ET_QIS_SEND_EMAIL1__c":"","ET_QIS_SEND_EMAIL2__c":"","problem_detail_photo__c":"","Caller_phone_Encrypted__c":"415f2dab7eb6b2a866e02d823080a845","Responsible_Person_HP_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"958360820671053825"}';
        NewAndEditLoanerExpressController.saveLoanerExpress(qisJson,'avgwshDFcxAS',False);
        NewAndEditLoanerExpressController.saveLoanerExpress(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditLoanerExpressControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerUserController.cls
New file
@@ -0,0 +1,41 @@
/*
 * Author: Yanan Chen
 * Created Date: 03/03/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditLoanerUserController
 * History:
 *      03/03/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditLoanerUserController extends NewAndEditBaseController {
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditLoanerUserController (ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('loaner_user__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        LookUpOverrideFields.add('Contact__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        // SObject obj = controller.getRecord();
        // if(obj.Id == null){
        //     //初始化加载值
        //     obj.put('OwnerId',UserInfo.getUserId());
        // }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveLoanerUser(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:' + sobJson);
        return save(new loaner_user__c(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditLoanerUserController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditLoanerUserControllerTest.cls
New file
@@ -0,0 +1,19 @@
@isTest
public class NewAndEditLoanerUserControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditLoanerUserController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        loaner_user__c lu = TestDataUtility.CreateLoanerUsers(1)[0];
        Test.startTest();
        ApexPages.StandardController sc =  new ApexPages.StandardController(lu);
        NewAndEditLoanerUserController qis = new NewAndEditLoanerUserController(sc);
        String qisJson = '{"Name":"test123","QIS_Status__c":"草案中","QIS_pre__c":"000000000000000","consumable__c":"01t1m000001QyDa","Cancel_QIS_Reason__c":"_u0001_","RecordTypeId":"01210000000RLWc","Repair__c":"a0J1m000001nZzf","RejectReason__c":"","Managementtext__c":"","OCSMAdministrativeReportStatus__c":"无需报告","MBC_AwareDate__c":"2022/03/29","Aware_date__c":"2022/03/29","Old_Repair_Name__c":"","isLendRental__c":false,"next_action__c":"","RC_problem_not_found__c":false,"Salesdepartment_Text__c":"","OCM_Repair_Mail1__c":"","Hospital__c":"0011m00000XlvHh","Account_State__c":"","Department_Class__c":"0011m00000SP4Mp","OwnerId":"0051m0000030e0QAAQ","Hospital_Department__c":"0011m00000SP4TB","Responsible_Person_HP__c":"***","Caller_phone__c":"***********","capital_or_consumable__c":"耗材","contract_number_ET_text__c":"","nonyushohin__c":"000000000000000","InstallDate_text__c":"","usage_frequence__c":"1","cleanning__c":"1","cds_methods__c":"手动","disinfection__c":"","sterlization__c":"","Faliour_date__c":"2022/03/29","Trable_occur_daY_collect__c":"2022/03/29","DelayReportReason__c":"","failuer_situation__c":"到货验收","failuer_situationSelect__c":"","problem_detail__c":"test","Damage_For_Doc_Or_Pat__c":"","Relation_With_The_Problem__c":"","Report_For_Goz__c":"","Which_Project__c":"","Opera_Name__c":"","BreakORFallOff__c":"","Is_Used_For_The_Opera__c":"","Set_usage_product__c":"","Comment__c":"test","AfterFailureInformation__c":"","Delay15Min__c":"","InformationFrom__c":"","FailureQInHospital__c":"","accsessary_detail__c":"","shipping_to_QIS_dept_day__c":"","ASReportedCode__c":"","QIS_ConfirmationDate__c":"","PAE_Determine__c":"","ASReportedCodeAC__c":"","OCSM_RC_CordingDate__c":"","PAE_DetermineAC__c":"","Complaint_Number__c":"","OSH_ConfirmationDate__c":"","if_QIS_Allowed__c":"","NotAllowedReason__c":"","OSHRAConfirmDate__c":"","isAE_Profile__c":"","isPAE_Profile__c":"","MDR_information__c":"","MDR_detail__c":"","CFDA_No_Hand__c":"","ProduceCompany_hand__c":"","Receive_Date_Day__c":"2022/03/29","OSHRecievedDate__c":"","QIS_Submit_day__c":"","QIS_OSH_answerdate__c":"","OCM_RC_RecievedDate__c":"","QIS_Complete_Day__c":"","QIS_Reply_day__c":"","QIS_cancel_date__c":"","QIS_Cancel_Submit_day__c":"","Daily_Report__c":"000000000000000","Generation_Source__c":"","Source_OnCall__c":"000000000000000","QisSubOrder__c":"000000000000000","AsyncData__c":false,"ETQ_UPLOAD_STATUS__c":"","AWS_Interface_Time__c":"2022/03/29 13:38","ETQ_UPLOAD_MESSAGE__c":"","INTERFACE_RECORD_ID__c":"","ET_QIS_SEND_EMAIL1__c":"","ET_QIS_SEND_EMAIL2__c":"","problem_detail_photo__c":"","Caller_phone_Encrypted__c":"415f2dab7eb6b2a866e02d823080a845","Responsible_Person_HP_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"958360820671053825"}';
        NewAndEditLoanerUserController.saveLoanerUser(qisJson,'avgwshDFcxAS',False);
        NewAndEditLoanerUserController.saveLoanerUser(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditLoanerUserControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditOpportunityController.cls
New file
@@ -0,0 +1,44 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/23/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditOpportunityController
 * History:
 *      02/23/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditOpportunityController extends NewAndEditBaseController {
    // public String contactId{get; set;}
    // public Contact contact{get; private set;}
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditOpportunityController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Opportunity').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        LookUpOverrideFields.add('EndUser__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveOpportunity(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:'+sobJson);
        return save(new Opportunity(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditOpportunityController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditOpportunityControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditOpportunityControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditOpportunityController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Opportunity opp = TestDataUtility.CreateOpportunitys(1)[0];
        Test.startTest();
        ApexPages.StandardController sc =  new ApexPages.StandardController(opp);
        NewAndEditOpportunityController qis = new NewAndEditOpportunityController(sc);
        qis.contactId = 'test';
        String qisJson = '{"Is_Decided__c":false,"the_Upload_of_quotation_number__c":"","Cancel_Fail_Approve__c":"","SAP_QuotationCode__c":"","compo_opp__c":false,"CanChangeOpp__c":true,"Name":"test1","AccountId":"0010l00001Q1r4e","RecordTypeId":"012280000005hjO","Type":"","ApprovalStatus_D__c":"Draft","ProductSegment__c":"IE","SpecialPriceApproveStatus__c":"","BudgetAmount__c":"","Machine_Parts__c":"Machine","Amount":"","CurrencyIsoCode":"CNY","customerType__c":"","IsFirstDecide__c":false,"IE_need_business_approve__c":false,"IE_Discount_Special__c":"","IE_ShippingHandling__c":"","IE_local_cost__c":"","IE_Custom_Price__c":"","IE_Payment_terms__c":"","StockAnswerSummary__c":"","Phase1Date__c":"","InquiryResult__c":"","Phase2Date__c":"","ExpectedOrderDate__c":"","Phase3Date__c":"","ExpectedDeliveryDate__c":"","Order_Date__c":"","DeliveryDate__c":"","InquiryResultOrder__c":"","LeadSource":"","TradeType__c":"Taxation","CustomerSourceIE__c":"","SalesChannel__c":"dealer","Trade_Type_D__c":"Taxation","Dealer__c":"0010l00001Pj768","DealerSalesStaffName__c":"***","DealerService__c":"***","SubDealer__c":"test","Dealer_Sales_Staff_Name_D__c":"***","Dealer_Service_D__c":"***","Competitor_Product__c":"","CompetitorProductCode__c":"","Competitor_Product2__c":"","CompetitorProductCode2__c":"","Competitor_Product3__c":"","CompetitorProductCode3__c":"","Competitor_Product4__c":"","CompetitorProductCode4__c":"","Competitor_Product5__c":"","CompetitorProductCode5__c":"","Competitor_Product6__c":"","CompetitorProductCode6__c":"","Competitor_Product7__c":"","CompetitorProductCode7__c":"","Competitor_Product8__c":"","CompetitorProductCode8__c":"","CompetitorCompany__c":"_0001_","LostAmount__c":"","LostCompetitorProduct__c":"","InquiryResultLost__c":"","LostReason__c":"","LostReasonText__c":"","CancelReason__c":"","InquiryResultCancel__c":"","CancelReasonText__c":"","Have_Computer__c":false,"Remark__c":"","NewInquiryDate__c":"2022-4-8","StageName":"Prospect Created","Probability":"","OppUpdateDateTime__c":"","CloseDate":"2022-4-8","ProductSegmentCompetitor__c":"","IsNew__c":false,"OpportunityAmount_text__c":"","OpportunityLineItem_text__c":"","OpportunityLineItemOT_text__c":"","IsSendEmail__c":true,"IsUpdate__c":false,"OppUpdateDate__c":"","DealerSalesStaffName_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","Dealer_Sales_Staff_Name_D_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","DealerService_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","Dealer_Service_D_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"961991622629785601"}';
        NewAndEditOpportunityController.saveOpportunity(qisJson,'avgwshDFcxAS',False);
        NewAndEditOpportunityController.saveOpportunity(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditOpportunityControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditOrderController.cls
New file
@@ -0,0 +1,46 @@
/*
 * Author: Su cuiping
 * Created Date: 03/01/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditOrderController
 *
 * */
global class NewAndEditOrderController extends NewAndEditBaseController {
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditOrderController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Order').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        //Get Account Id from url param
        // System.debug('accountType = ' + );
        if(!Test.isRunningTest()){
            controller.addFields(fieldList);
        }
        LookUpOverrideFields.add('EndUserD__c');
        LookUpOverrideFields.add('EndUser__c');
        LookUpOverrideFields.add('ShipToContactId');
        LookUpOverrideFields.add('SpecialDeliveryContact2__c');
        LookUpOverrideFields.add('SpecialDeliveryContact2_D__c');
        Init(controller.getRecord());
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId',UserInfo.getUserId());
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveOrder(String OrderJson, String transId, Boolean isNew){
        return save(new Order(), OrderJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditOrderController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditOrderControllerTest.cls
New file
@@ -0,0 +1,19 @@
@isTest
public class NewAndEditOrderControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditOrderController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Order od = TestDataUtility.CreateOrders(1)[0];
        Test.startTest();
        ApexPages.StandardController sc =  new ApexPages.StandardController(od);
        NewAndEditOrderController qis = new NewAndEditOrderController(sc);
        qis.contactId = 'test';
        String qisJson = '{"Name":"test123","ApproveStatus__c":"Draft","AccountId":"0010l00001Q1r4e","EndUserD__c":"0030l00000mqae5AAA","SpecialDeliveryAccount_D__c":"0010l00001Q1r4e","TradeMagNo__c":"","CurrencyIsoCode":"CNY","TradeMagCategory__c":"","confirm__c":false,"Status__c":"Active","IsOrderPassed__c":false,"IsSpPassed__c":false,"IsNew__c":false,"CustomerContractPrice__c":"","SAP_Order__c":"","OlympusContractPrices__c":"","SAP_Contract__c":"","PaymentCondition_D__c":"","AlongProduct__c":"","Olympus_Price_BeforeDiscount_D__c":"","EffectiveDate":"2022-4-8","Discount_D__c":"","ServiceFee__c":"","Cost__c":"","ForeignTradeCompany_D__c":"0010l00001Q1Jxd","SpecialDeliveryAccountText__c":"","Shipment_Term_D__c":"","SpecialDeliveryContactText__c":"","Shipment_Term2_D__c":"","Shipping_Address_Text__c":"","ShippedDate__c":"","OrderDate__c":"","InstalledDate__c":"","WarrantyStartDateFromOCN__c":"","CancelReason__c":"","SplitReason__c":"","Split_Approved__c":false,"ChangeReason__c":"","ChangeContent__c":"","Contract_Status__c":"Active","RecordTypeId":"01228000000NJt6","OrderUpdateDateTime__c":"","Status":"Draft","Description":"","PDF_By_Add_Encrypted__c":null,"PDF_By_Tel_Encrypted__c":null,"PDF_Sign_Name_Encrypted__c":null,"PDF_Sign_Title_Encrypted__c":null,"SpecialDeliveryAddress_D_Encrypted__c":null,"SpecialDeliveryAddress_Encrypted__c":null,"PDF_C_CONTACT_Encrypted__c":null,"PDF_C_Consignee_Encrypted__c":null,"PDF_C_FAX_Encrypted__c":null,"PDF_C_TEL_Encrypted__c":null,"PDF_C_THECONSIGNE_Encrypted__c":null,"PDF_F_ContactPerson_Encrypted__c":null,"PDF_F_FAX_Encrypted__c":null,"PDF_F_TEL_Encrypted__c":null,"PDF_S_TEL_Encrypted__c":null,"PDF_N_CONTACT_Encrypted__c":null,"PDF_N_FAX_Encrypted__c":null,"PDF_N_NotifyParty_Encrypted__c":null,"SpecialDeliveryContact_D_Encrypted__c":null,"SpecialDeliveryContact_Encrypted__c":null,"Shipping_Address_Text_Encrypted__c":"","SpecialDeliveryContactText_Encrypted__c":"","SpecialDeliveryPhone_D_Encrypted__c":null,"SpecialDeliveryPhone_Encrypted__c":null,"PDF_By_Add__c":null,"PDF_By_Tel__c":null,"PDF_Sign_Name__c":null,"PDF_Sign_Title__c":null,"SpecialDeliveryAddress_D__c":null,"SpecialDeliveryAddress__c":null,"PDF_C_CONTACT__c":null,"PDF_C_Consignee__c":null,"PDF_C_FAX__c":null,"PDF_C_TEL__c":null,"PDF_C_THECONSIGNE__c":null,"PDF_F_ContactPerson__c":null,"PDF_F_FAX__c":null,"PDF_S_TEL__c":null,"PDF_N_CONTACT__c":null,"PDF_N_NotifyParty__c":null,"SpecialDeliveryContact_D__c":null,"SpecialDeliveryContact__c":null,"SpecialDeliveryPhone_D__c":null,"SpecialDeliveryPhone__c":null,"AWS_Data_Id__c":"962013895902363649"}';
        NewAndEditOrderController.saveOrder(qisJson,'avgwshDFcxAS',False);
        NewAndEditOrderController.saveOrder(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditOrderControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditQuotesController.cls
New file
@@ -0,0 +1,42 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-04-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global class NewAndEditQuotesController extends NewAndEditBaseController {
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditQuotesController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Quotes__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        //Get Account Id from url param
        // System.debug('accountType = ' + );
        if(!Test.isRunningTest()){
            controller.addFields(fieldList);
        }
        LookUpOverrideFields.add('CONTACT_NAME__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
             //初始化加载值
             obj.put('OwnerId',UserInfo.getUserId());
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveQuotes(String QuotesJson, String transId, Boolean isNew){
        return save(new Quotes__c(), QuotesJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditQuotesController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditQuotesControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditQuotesControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditQuotesController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Quotes__c uf = TestDataUtility.CreateQuotes(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(uf);
        NewAndEditQuotesController qis = new NewAndEditQuotesController(con);
        qis.contactId = 'Test';
        String qisJson = '{"Name":"test123","CurrencyIsoCode":"CNY","TOTAL_TRANSACTION_ITEM_WEIGHT_KGS__c":"","InvalidData__c":false,"TOTAL__c":"","VERTICAL_MARKET_SEGMENT_SO__c":"","TAX_RATE__c":"","THROW_MESSAGE__c":false,"TERMS_OVERRIDE__c":false,"STATUS__c":"","TERMS__c":"","SELECT_MESSAGE__c":"","TAX_OVERRIDE__c":false,"REVISION_NEEDED__c":"","TAX_ID__c":"","SALES_TEAM_AUTO_ASSIGN_ON_SAVE__c":false,"TAX_CODE__c":"","RATE__c":"","TAX__c":"","QUOTE_TITLE__c":"","SWO_NUMBER__c":"","PRODUCT_SEGMENT__c":"","SUBTOTAL__c":"","PROBABILITY__c":"","SHIP_VIA__c":"","PO__c":"","SHIP_TO_SELECT__c":"","PKMS_PO_FOR_RECEIPT__c":"","SHIP_TO_ENTITY_USE_CODE__c":"","ORDER_TYPE__c":"","SHIP_TO__c":"","NSN__c":"","SHIPPING_TAX_RATE__c":"","notSaveEmail__c":true,"SHIPPING_TAX_CODE__c":"","NO_CHARGE_TYPE__c":"","SHIPPING_COST__c":"","IS_SELLER_IMPORTER_OF_RECORD__c":false,"SHIPPING_CARRIER__c":"","INITIATE_APPROVAL_ROUTING__c":false,"SALES_TEAM_AUTO_ASSIGNMENT_OVERRIDE__c":false,"GSA_ORDER__c":false,"RMA_NOTES__c":"","FDA_REPORT_COMPLETE__c":false,"QuotesType__c":"","EST_EXTENDED_COST__c":"","DISCOUNT_STATUS_ROUTING__c":"","OPPORTUNITY__c":"","DISCOUNT__c":"","ONLINE_BILLING_ADDRESS__c":"","BILLING_SCHEDULE__c":"","ONLINE_BILLING__c":false,"BILL_TO_ENTITY_USE_CODE__c":"","LOCATION__c":"","CATEGORY_1_INDUSTRY_SO__c":"","LEAD_TIME__c":"","COLLECTION_STATUS__c":"","LEAD_SOURCE__c":"","INVOICE_MESSAGING__c":"","CONTRACT_NAME__c":"","INCOTERM__c":"","CURRENCY__c":"","GOVERNMENT_ORDER__c":false,"DATE__c":"","EXPIRES__c":"","DISCOUNT_ITEM__c":"","EXP_CLOSE__c":"","EST_GROSS_PROFIT_PERCENT__c":"","EST_GROSS_PROFIT__c":"","DISCOUNT_WORKFLOW_TYPE__c":"","DISCOUNT_STATUS__c":"","BILL_TO__c":"","BILL_TO_SELECT__c":"","CATEGORY_2_USE_SO__c":"","CONTACT_PHONE__c":"","CUSTOMER_MESSAGE__c":"","BILL_TO_Encrypted__c":"","SHIP_TO_Encrypted__c":"","AWS_Data_Id__c":"961999748590469121"}';
        NewAndEditQuotesController.saveQuotes(qisJson,'avgwshDFcxAS',False);
        NewAndEditQuotesController.saveQuotes(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditQuotesControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditRepairController.cls
New file
@@ -0,0 +1,38 @@
/**
 * @description       :
 * @author            : ChangeMeIn@UserSettingsUnder.SFDoc
 * @group             :
 * @last modified on  : 03-04-2022
 * @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
**/
global class NewAndEditRepairController extends NewAndEditBaseController {
    public Contact contactAWSDataId {get; set;}
    public Repair__c repair{get; set;}
    public String staticResourceContact {get; set;}
    public NewAndEditRepairController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('Repair__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        //Get Account Id from url param
        // System.debug('accountType = ' + );
        if(!Test.isRunningTest()){
            controller.addFields(fieldList);
        }
        Init(controller.getRecord());
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        SObject obj = controller.getRecord();
        System.debug('obj.Id = ' + obj.Id);
        repair = [Select Id, ContactD__c From Repair__c WHERE ID =:obj.Id];
        System.debug('repair.ContactD__c = ' + repair.ContactD__c);
        contactAWSDataId = [SELECT ID, AWS_Data_Id__c FROM Contact WHERE ID =:repair.ContactD__c];
        System.debug('contactAWSDataId.AWS_Data_Id__c = ' + contactAWSDataId.AWS_Data_Id__c );
    }
    @RemoteAction
    global static Response saveRepair(String RepairJson, String transId, Boolean isNew){
        return save(new Repair__c(), RepairJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditRepairController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditRepairControllerTest.cls
New file
@@ -0,0 +1,25 @@
@isTest
public class NewAndEditRepairControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditRepairController() {
        Contact con = TestDataUtility.CreateContacts(1)[0];
        con.AWS_Data_Id__c = '1234567890';
        update con;
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        Repair__c rep = TestDataUtility.CreateRepairs(1)[0];
        rep.ContactD__c = con.Id;
        update rep;
        Test.startTest();
        ApexPages.StandardController sc =  new ApexPages.StandardController(rep);
        NewAndEditRepairController qis = new NewAndEditRepairController(sc);
        String qisJson = '{"Name":"test123"}';
        NewAndEditRepairController.saveRepair(qisJson,'avgwshDFcxAS',False);
        NewAndEditRepairController.saveRepair(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditRepairControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditUserFaultInfoController.cls
New file
@@ -0,0 +1,40 @@
/*
 * Author: Yanan Chen
 * Created Date: 02/28/2022
 * Purpose: Utility class for describe layouts
 * Test Class: NewAndEditUserFaultInfoController
 * History:
 *      02/28/2022 - Yanan Chen - Initial Code.
 *
 * */
global class NewAndEditUserFaultInfoController extends NewAndEditBaseController {
    public String PIPL_Input_Account_Error_Msg{set;get;}
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public NewAndEditUserFaultInfoController(ApexPages.StandardController controller){
        List<String> fieldList = new List<String>(Schema.getGlobalDescribe().get('User_FaultInfo__c').getDescribe().fields.getMap().keyset());
        // Add fields to controller. This is to avoid the SOQL error in visualforce page
        if(!Test.isRunningTest()){
            controller.addFields(fieldList); // contact lookup
        }
        LookUpOverrideFields.add('CONTACT__c');
        Init(controller.getRecord());
        //添加项
        PIPL_Input_Account_Error_Msg = label.PIPL_Input_Account_Error_Msg;
        SObject obj = controller.getRecord();
        if(obj.Id == null){
            //初始化加载值
            obj.put('OwnerId', UserInfo.getUserId());
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    global static Response saveUserFaultInfo(String sobJson, String transId, Boolean isNew){
        system.debug('JSON Payload:'+sobJson);
        return save(new User_FaultInfo__c(), sobJson, transId, isNew);
    }
}
force-app/main/default/classes/NewAndEditUserFaultInfoController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewAndEditUserFaultInfoControllerTest.cls
New file
@@ -0,0 +1,20 @@
@isTest
public class NewAndEditUserFaultInfoControllerTest {
    @TestSetup
    static void makeData(){
        TestDataUtility.CreatePIPolicyConfiguration();
    }
    static testMethod void NewAndEditLoanerApplicationController() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreateMetaDataUtilityHttpMock());
        loaner_application__c la = TestDataUtility.Createloanerapplications(1)[0];
        Test.startTest();
        ApexPages.StandardController con =  new ApexPages.StandardController(la);
        NewAndEditUserFaultInfoController qis = new NewAndEditUserFaultInfoController(con);
        String qisJson = '{"Name":"test123","QIS_Status__c":"草案中","QIS_pre__c":"000000000000000","consumable__c":"01t1m000001QyDa","Cancel_QIS_Reason__c":"_u0001_","RecordTypeId":"01210000000RLWc","Repair__c":"a0J1m000001nZzf","RejectReason__c":"","Managementtext__c":"","OCSMAdministrativeReportStatus__c":"无需报告","MBC_AwareDate__c":"2022/03/29","Aware_date__c":"2022/03/29","Old_Repair_Name__c":"","isLendRental__c":false,"next_action__c":"","RC_problem_not_found__c":false,"Salesdepartment_Text__c":"","OCM_Repair_Mail1__c":"","Hospital__c":"0011m00000XlvHh","Account_State__c":"","Department_Class__c":"0011m00000SP4Mp","OwnerId":"0051m0000030e0QAAQ","Hospital_Department__c":"0011m00000SP4TB","Responsible_Person_HP__c":"***","Caller_phone__c":"***********","capital_or_consumable__c":"耗材","contract_number_ET_text__c":"","nonyushohin__c":"000000000000000","InstallDate_text__c":"","usage_frequence__c":"1","cleanning__c":"1","cds_methods__c":"手动","disinfection__c":"","sterlization__c":"","Faliour_date__c":"2022/03/29","Trable_occur_daY_collect__c":"2022/03/29","DelayReportReason__c":"","failuer_situation__c":"到货验收","failuer_situationSelect__c":"","problem_detail__c":"test","Damage_For_Doc_Or_Pat__c":"","Relation_With_The_Problem__c":"","Report_For_Goz__c":"","Which_Project__c":"","Opera_Name__c":"","BreakORFallOff__c":"","Is_Used_For_The_Opera__c":"","Set_usage_product__c":"","Comment__c":"test","AfterFailureInformation__c":"","Delay15Min__c":"","InformationFrom__c":"","FailureQInHospital__c":"","accsessary_detail__c":"","shipping_to_QIS_dept_day__c":"","ASReportedCode__c":"","QIS_ConfirmationDate__c":"","PAE_Determine__c":"","ASReportedCodeAC__c":"","OCSM_RC_CordingDate__c":"","PAE_DetermineAC__c":"","Complaint_Number__c":"","OSH_ConfirmationDate__c":"","if_QIS_Allowed__c":"","NotAllowedReason__c":"","OSHRAConfirmDate__c":"","isAE_Profile__c":"","isPAE_Profile__c":"","MDR_information__c":"","MDR_detail__c":"","CFDA_No_Hand__c":"","ProduceCompany_hand__c":"","Receive_Date_Day__c":"2022/03/29","OSHRecievedDate__c":"","QIS_Submit_day__c":"","QIS_OSH_answerdate__c":"","OCM_RC_RecievedDate__c":"","QIS_Complete_Day__c":"","QIS_Reply_day__c":"","QIS_cancel_date__c":"","QIS_Cancel_Submit_day__c":"","Daily_Report__c":"000000000000000","Generation_Source__c":"","Source_OnCall__c":"000000000000000","QisSubOrder__c":"000000000000000","AsyncData__c":false,"ETQ_UPLOAD_STATUS__c":"","AWS_Interface_Time__c":"2022/03/29 13:38","ETQ_UPLOAD_MESSAGE__c":"","INTERFACE_RECORD_ID__c":"","ET_QIS_SEND_EMAIL1__c":"","ET_QIS_SEND_EMAIL2__c":"","problem_detail_photo__c":"","Caller_phone_Encrypted__c":"415f2dab7eb6b2a866e02d823080a845","Responsible_Person_HP_Encrypted__c":"dcce196c4cfc273a83777852ddd486ab","AWS_Data_Id__c":"958360820671053825"}';
        NewAndEditUserFaultInfoController.saveUserFaultInfo(qisJson,'avgwshDFcxAS',False);
        NewAndEditUserFaultInfoController.saveUserFaultInfo(qisJson,'avgwshDFcxAS',True);
        Test.stopTest();
    }
}
force-app/main/default/classes/NewAndEditUserFaultInfoControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/NewOpportunityController.cls
@@ -16,6 +16,9 @@
    public Boolean isIEDealer{get; set; }
    public String staticResource {get; set;}
    public String opportunityAWSDataId{get; set;}
    public NewOpportunityController() {
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
        String path = URL.getCurrentRequestUrl().getPath();
@@ -94,6 +97,7 @@
            opp.Dealer__c = dealerId;
        }
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Opportunity'));
        return null;
    }
force-app/main/default/classes/NewReplacementOpportunityController.cls
@@ -13,6 +13,8 @@
    public String rtUrl { get; set; }
    public String ProductSegment { get; set; }
    public String staticResource {get; set;}
    public String opportunityAWSDataId{get; set;}
    public NewReplacementOpportunityController() {
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
@@ -70,7 +72,7 @@
        if (UserInfo.getUserType() == 'PowerPartner' && acc.ProductSegment__c != 'BS') {
            opp.Dealer__c = dealerId;
        }
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Opportunity'));
        return null;
    }
force-app/main/default/classes/PIHelperTest.cls
@@ -1,3 +1,45 @@
public class PIHelperTest {
@isTest
private class PIHelperTest {
    static testMethod void getPIIntegrationInfo() {
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
        String sobjectType = 'Contact';
        List<AWS_Integration_Info__mdt> awsConfigurationList = [SELECT App_Id__c,Token_URL__c,App_Secret__c,Host_URL__c FROM AWS_Integration_Info__mdt  WHERE DeveloperName = 'AWS_Default_Configuration'];
        Test.startTest();
        PIHelper.getPIIntegrationInfo(sobjectType);
        Test.stopTest();
    }
    static testMethod void saveTransLog() {
        Test.startTest();
        PIHelper.saveTransLog('module','vadsjngrqvjca','avgwshDFcxAS', 'DSAGSFBQdfdsoav','test','0','testmsg');
        Test.stopTest();
    }
    /*static testMethod void confirmTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        List<PIHelper.idList> idList = new List<PIHelper.idList>();
        PIHelper.idList pid = new PIHelper.idList();
        pid.awsId = 'vadsjngrqvjca';
        pid.sfRecordId = 'avgwshDFcxAS';
        idList.add(pid);
        PIHelper.confirmTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS' ,'DSAGSFBQdfdsoav','https://sfpi-mebg-test.olympuschina.com/api/contact/insert',idList);
        Test.stopTest();
    }*/
    /*static testMethod void confirmFileTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        PIHelper.confirmFileTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS','DSAGSFBQdfdsoav','https://sfpi-mebg-test.olympuschina.com/api/contact/insert');
        Test.stopTest();
    }*/
    /*static testMethod void insertConfirmTrans() {
        Test.setMock(HttpCalloutMock.class, new TestDataUtility.CreatePIHelperHttpMock());
        Test.startTest();
        List<PIHelper.idList> idList = new List<PIHelper.idList>();
        PIHelper.idList pid = new PIHelper.idList();
        pid.awsId = 'vadsjngrqvjca';
        pid.sfRecordId = 'avgwshDFcxAS';
        idList.add(pid);
        PIHelper.insertConfirmTrans('module',1,'vadsjngrqvjca' ,'avgwshDFcxAS' ,0,'https://sfpi-mebg-test.olympuschina.com/api/contact/insert',idList);
        Test.stopTest();
    }*/
}
force-app/main/default/classes/SearchContactController.cls
New file
@@ -0,0 +1,68 @@
/*
 * Author: Bubba Li
 * Created Date: 02/08/2022
 * Purpose: SearchContactController
 * Test Class: SearchContactController
 * History:
 *      02/08/2022 - Bubba Li - Initial Code.
 *
 * */
public without sharing class SearchContactController {
    public String searchKeyWord{set;get;}
    public String staticResource {get; set;}
    public String contactAWSIds {set;get;}
    public String contactsInfo {set;get;}
    public String PIPL_Search_Contact_Label{set;get;}
    public SearchContactController() {
        String accountId = ApexPages.currentPage().getParameters().get('accountId');
        PIPL_Search_Contact_Label = Label.PIPL_Search_Contact_Label;
        //1. Query Contact by accountId
        List<Contact> conList = new List<Contact>();
        system.debug('Account Id from Front-end:'+accountId);
        if(String.isNotBlank(accountId) && String.isNotEmpty(accountId)){
            String accountIdStr = '';
            String[] accountIds = accountId.split(',');
            List<String> accountIdList = new List<String>();
            for(String s : accountIds){
                accountIdList.add(s);
            }
            conList = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AccountId in:accountIdList and AWS_Data_Id__c!='']);
            System.debug('conList:'+conList);
        }
        //2. Prepare the Contact Info
        Map<String,Contact> awsIdToContactMap = new Map<String,Contact>();
        List<String> conAWSIds = new List<String>();
        for(Contact con:conList){
            conAWSIds.add(con.AWS_Data_Id__c);
            awsIdToContactMap.put(con.AWS_Data_Id__c,con);
        }
        contactsInfo = JSON.serialize(awsIdToContactMap);
        contactAWSIds = JSON.serialize(conAWSIds);
        staticResource = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
    }
    @RemoteAction
    public static Response searchContacts(String awsContactIds) {
        Response resp = new Response();
        resp.status = 'fail';
        if(String.isBlank(awsContactIds)||String.isEmpty(awsContactIds)){
            return resp;
        }
        List<String> awsDataIds = (List<String>) JSON.deserialize(awsContactIds, List<String>.class);
        Map<String,Contact> awsIdToContactMapTemp = new Map<String,Contact>();
        List<Contact> conListTemp = new List<Contact>([select Id,AWS_Data_Id__c from Contact where AWS_Data_Id__c in:awsDataIds]);
        for(Contact con:conListTemp){
            awsIdToContactMapTemp.put(con.AWS_Data_Id__c,con);
        }
        if(awsIdToContactMapTemp.keySet().size()>0){
            resp.status = 'success';
            resp.message = JSON.serialize(awsIdToContactMapTemp);
        }
        return resp;
    }
    public class Response{
        public String message{set;get;}
        public String status{set;get;}
    }
}
force-app/main/default/classes/SearchContactController.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SearchContactControllerTest.cls
New file
@@ -0,0 +1,23 @@
@isTest
private class SearchContactControllerTest {
    @TestSetup
    static void makeData(){
    }
    static testMethod void testMethod1() {
        TestDataUtility.CreatePIPolicyConfiguration('Contact');
        Contact con = TestDataUtility.CreateContacts(1)[0];
        con.AWS_Data_Id__c = 'davdsvgrqcx';
        update con;
        List<String> awsList = new List<String>();
        awsList.add(con.AWS_Data_Id__c);
        String awsListJson = JSON.serialize(awsList);
        String url = ApexPages.currentPage().getParameters().put('accountId',con.AccountId);
        Test.startTest();
        SearchContactController scc = new SearchContactController();
        SearchContactController.searchContacts(awsListJson);
        scc.searchKeyWord = 'test';
        Test.stopTest();
    }
}
force-app/main/default/classes/SearchContactControllerTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SoqlHelper.cls
New file
@@ -0,0 +1,136 @@
public  class SoqlHelper {
    public static string DistinctQueryFields(string sql)
    {
        string query_fields = sql;
        if (query_fields == null) {
            return null;
        }
        query_fields = query_fields.trim();
        Integer sel_i = query_fields.indexOfIgnoreCase('select ');
        string sel = 'select ';
        if ( sel_i < 0) {
            sel = '';
        }
        string whe = '';
        Integer whe_i = query_fields.indexOfIgnoreCase(' from ');
        if ( whe_i >= 0) {
            whe = query_fields.substring(whe_i);
        }
        string query = query_fields.substring(sel_i < 0 ? 0 : sel.length(), whe_i < 0 ? query_fields.length() : whe_i);
        Set<string> ss = new Set<string>();
        for(string f : query.split(',')){
            string s = f.trim().toLowerCase();
            //System.debug('s='+s);
            ss.add(s);
        }
        return sel + QueryFields(ss) + whe;
    }
    public static string WId(string wid){
        return '\'' + wid + '\'';
    }
    public static string QueryFields(Set<string> lo){
        return QueryFields(new List<string>(lo));
    }
    public static string QueryFields(List<object> lo){
        return string.join(lo, ',');
    }
    public static string ToInCondition(List<AggregateResult> lar ,string key)
    {
        if(lar==null || lar.size() == 0)
        {
            return null;
        }
        string ss = ' ( ';
        boolean b = true;
        for(AggregateResult ar : lar)
        {
            if(ar.get(key)==null)continue;
            if( b )
            {
                b = false;
                ss += '\''+ar.get(key)+'\'';
            }
            else
            {
                ss += ',\''+ar.get(key)+'\'';
            }
        }
        ss+=') ';
        return ss;
    }
    public static string ToInCondition(Set<string> so){
        return ToInCondition(new List<string>(so));
    }
    public static string ToInCondition(List<object> lo)
    {
        Set<object> so = new Set<object>(lo);
        lo = new List<object>(so);
        return '(\''+ string.join(lo, '\',\'')+'\')';
    }
    public static void InsertList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        insert so_list;
    }
    public static void UpdateList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        update so_list;
    }
    /*public static Map<string,Database.UpsertResult> UpsertList(List<Sobject> so_list, Schema.SObjectField field)
    {
        Map<string,Database.UpsertResult> mid = new Map<string,Database.UpsertResult>();
        if(so_list == null || so_list.size() == 0)return mid;
        List<Database.UpsertResult> urList2 = Database.upsert( so_list, field, false);
        Set<String> accBasicRecordIdSet = new Set<String>();
        integer index = 0;
        string errorString = '';
        string field_str = field.getDescribe().getName();
        for(Database.UpsertResult ur : urList2){
            if(!ur.IsSuccess()){
                object fv = so_list[index].get(field_str);
                mid.put(fv+'',ur);
                errorString = '';
                for(Database.Error errs: ur.getErrors()){
                    errorString += errs.getMessage() + ';';
                }
                //LogHelper.CreateRunTimeLog('runtime error', errorString, false, fv+'');
            }
            index++;
        }
        return mid;
    }*/
    public static void DeleteList(List<Sobject> so_list)
    {
        if(so_list == null || so_list.size() == 0)return;
        delete so_list;
    }
    @future
    public static void DeleteListAsync(List<Id> id_list)
    {
        if(id_list == null || id_list.size() == 0)return;
        Database.delete(id_list);
    }
}
force-app/main/default/classes/SoqlHelper.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/SoqlHelperTest.cls
New file
@@ -0,0 +1,46 @@
@isTest
private class SoqlHelperTest {
    static testMethod void testMethod1() {
        String sql = 'SELECT Id,Name FROM Contact WHERE Name != null Limit 1';
        Account accupdate = TestDataUtility.CreateAccounts(1)[0];
        accupdate.Name = 'update1';
        List<Account> updateAccList = new List<Account>();
        //Profile p = [select Id from Profile where Name = 'System Administrator'];
        Profile p = [select Id from Profile where Name = 'Chatter Free User'];
        User hpOwner = new User( LastName = 'TestUserA', FirstName = 'owner', Alias = 'hp', CommunityNickname = 'hpOwner', Email = 'olympus_hpowner@sunbridge.com', Username = 'olympus_hpowner@sunbridge.com', IsActive = true, EmailEncodingKey = 'ISO-2022-JP', TimeZoneSidKey = 'Asia/Tokyo', LocaleSidKey = 'ja_JP', LanguageLocaleKey = 'ja', ProfileId = p.id);
        List<User> userList = new List<User>();
        userList.add(hpOwner);
        Contact con = TestDataUtility.CreateContacts(1)[0];
        List<String> conidList = new List<String>();
        conidList.add(con.Id);
        Set<String> strSet = new Set<String>();
        strSet.add('test1');
        strSet.add('test2');
        List<AggregateResult> lartest = new List<AggregateResult>();
        //Repair__c repair1 = new Repair__c();
        //repair1.Name = 'test';
        //repair1.RecordTypeId = '0120K000000wOGcQAM';
        //insert repair1;
        lartest = [select count(Id) total from Repair__c where RecordTypeId != null group by RecordTypeId];
        system.debug('lartest:'+lartest);
        String key = 'test';
        Test.startTest();
        //ToInCondition
        //UpsertList
        SoqlHelper.ToInCondition(strSet);
        SoqlHelper.ToInCondition(lartest, key);
        SoqlHelper.DistinctQueryFields(sql);
        SoqlHelper.WId(sql);
        SoqlHelper.InsertList(userList);
        SoqlHelper.UpdateList(updateAccList);
        SoqlHelper.DeleteList(updateAccList);
        SoqlHelper.DeleteListAsync(conidList);
        Test.stopTest();
    }
}
force-app/main/default/classes/SoqlHelperTest.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/TSRepairController.cls
@@ -6,6 +6,7 @@
    public String repairId {get; set;}
    public TS_Repair__c tsr {get; set;}
    public String datestr;
    public Integer num {get; set{ num = value;}} //添加产品时使用
@@ -44,6 +45,9 @@
    public Map<String, List<BusinessActivity__c>> businessActivityListToMap;
    //  王鹏伟定义变量开始
    // 前台点击按钮修改状态
    public String status {get; set;}
@@ -51,6 +55,14 @@
    //onclickType=0时只能点击草案,申请;onclickType=1时只能点击驳回,批准
    public String onclickType {get; set;} //onclickType=0时
    //  王鹏伟定义变量结束
    // Add by zhj for PIPL 20220309 Start
    public String contactId{set;get;}//For Lookup field
    public String staticResourceContact {get; set;}
    public String contactNameValue{set;get;}
    public String contactIdValue{set;get;}
    // Add by zhj for PIPL 20220309 End
    public TSRepairController() {
        baseUrl = URL.getSalesforceBaseUrl().toExternalForm();
@@ -75,6 +87,7 @@
        datestr =  System.currentPageReference().getParameters().get('date');
    }
    public PageReference init() {
        errorMessageMap  = new Map<String, List<String>>();
@@ -134,7 +147,8 @@
            }
        }
        //contact信息(搜索查询query url用)
        staticResourceContact = JSON.serialize(PIHelper.getPIIntegrationInfo('Contact'));
        return null;
    }
@@ -692,6 +706,7 @@
            updateUserFaultInfo.UserFaultInfoNextService__c = ba.BusinessANextService__c ;//下次服务时间
            updateUserFaultInfo.UFAccount__c = ba.BusinessAAccount__c ;//客户单位(查找)
            updateUserFaultInfo.UserFaultInfoCustomerUnit__c = ba.BusinessACustomerUnit__c ;//客户单位(文本)
            if(String.isNotBlank(contactIdValue)&&String.isNotEmpty(contactIdValue)){}
            updateUserFaultInfo.UFContact__c = ba.BusinessAContact__c ;//联系人
            updateUserFaultInfo.UFPhone__c = ba.BusinessAPhone_F__c ;//联系电话
force-app/main/default/classes/TestDataUtility.cls
New file
@@ -0,0 +1,649 @@
@isTest
public class TestDataUtility {
    public static void CreatePIPolicyConfiguration(){
        CreatePIPolicyConfigurations(null);
    }
    public static void CreatePIPolicyConfiguration(string sobject_name){
        CreatePIPolicyConfigurations(new string []{sobject_name});
    }
    public static void CreatePIPolicyConfigurations(List<String> sobjectTypes){
        String piJson = '[{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XWzKAAW"},"Sobject_Type__c":"SWO__c","New_URL__c":"/ssbgapi/swo/insert","Read_URL__c":"/ssbgapi/swo/query","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/swo/undelete","Id":"a0x0l000001XWzKAAW","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XTYDAA4"},"Sobject_Type__c":"User_FaultInfo__c","New_URL__c":"/ssbgapi/userfaultinfo/insert","Read_URL__c":"/ssbgapi/userfaultinfo/query","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/userfaultinfo/undelete","Id":"a0x0l000001XTYDAA4","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XVeVAAW"},"Sobject_Type__c":"Order","New_URL__c":"/ssbgapi/order/insert","Read_URL__c":"/ssbgapi/order/query","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/order/undelete","Id":"a0x0l000001XVeVAAW","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XX2TAAW"},"Sobject_Type__c":"loaner_application__c","New_URL__c":"/ssbgapi/loanerapplication/insert","Read_URL__c":"/ssbgapi/loanerapplication/query","Search_URL__c":"/ssbgapi/loanerapplication/search","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/loanerapplication/undelete","Id":"a0x0l000001XX2TAAW","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XozZAAS"},"Sobject_Type__c":"SBG027","New_URL__c":"/ssbgapi/sbg/027","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Id":"a0x0l000001XozZAAS","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XxDXAA0"},"Sobject_Type__c":"Mail","New_URL__c":"/ssbgapi/mail/sendEmail","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Id":"a0x0l000001XxDXAA0","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XWzeAAG"},"Sobject_Type__c":"Quotes__c","New_URL__c":"/ssbgapi/quotes/insert","Read_URL__c":"/ssbgapi/quotes/query","Search_URL__c":"/ssbgapi/quotes/search","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/quotes/undelete","Id":"a0x0l000001XWzeAAG","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XswlAAC"},"Sobject_Type__c":"Mail_Merge__c","New_URL__c":"/ssbgapi/mail/sendEmail","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Id":"a0x0l000001XswlAAC","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XB50AAG"},"Sobject_Type__c":"Opportunity","New_URL__c":"/ssbgapi/opportunity/insert","Read_URL__c":"/ssbgapi/opportunity/query","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/opportunity/undelete","Id":"a0x0l000001XB50AAG","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XxD8AAK"},"Sobject_Type__c":"Document","New_URL__c":"/api/file/upload","Read_URL__c":"/api/file/preview?key=","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/api/file/download?key=","Id":"a0x0l000001XxD8AAK","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XlVuAAK"},"Sobject_Type__c":"Repair__c","New_URL__c":"/ssbgapi/repair/insert","Read_URL__c":"/ssbgapi/repair/query","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/repair/undelete","Id":"a0x0l000001XlVuAAK","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XlbnAAC"},"Sobject_Type__c":"loaner_user__c","New_URL__c":"/ssbgapi/loaneruser/insert","Read_URL__c":"/ssbgapi/loaneruser/query","Search_URL__c":"/ssbgapi/loaneruser/search","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/loaneruser/undelete","Id":"a0x0l000001XlbnAAC","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XlZNAA0"},"Sobject_Type__c":"SBG007","New_URL__c":"/ssbgapi/sbg/007","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Id":"a0x0l000001XlZNAA0","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XAcZAAW"},"Sobject_Type__c":"Contact","New_URL__c":"/ssbgapi/contact/insert","Read_URL__c":"/ssbgapi/contact/query","Search_URL__c":"/ssbgapi/contact/search","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Undelete_URL__c":"/ssbgapi/contact/undelete","Id":"a0x0l000001XAcZAAW","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Policy_Configuration__c","url":"/services/data/v54.0/sobjects/PI_Policy_Configuration__c/a0x0l000001XqaGAAS"},"Sobject_Type__c":"SBG001","New_URL__c":"/ssbgapi/sbg/001","TransactionURL__c":"https://sfpi-ssbg-test.olympuschina.com:8080/ssbgapi/tx/confirm","Id":"a0x0l000001XqaGAAS","CurrencyIsoCode":"CNY"}]';
        List<PI_Policy_Configuration__c> piList = (List<PI_Policy_Configuration__c>)JSON.deserialize(piJson,List<PI_Policy_Configuration__c>.class);
        List<PI_Policy_Configuration__c> insertPiList = new List<PI_Policy_Configuration__c>();
        for(PI_Policy_Configuration__c pi : piList){
            PI_Policy_Configuration__c ipi = new PI_Policy_Configuration__c();
            ipi.Delete_URL__c = pi.Delete_URL__c;
            ipi.Enable_Encrypt__c = pi.Enable_Encrypt__c;
            ipi.New_URL__c = pi.New_URL__c;
            ipi.Read_URL__c = pi.Read_URL__c;
            ipi.Search_URL__c = pi.Search_URL__c;
            ipi.Sobject_Type__c = pi.Sobject_Type__c;
            ipi.Undelete_URL__c = pi.Undelete_URL__c;
            ipi.Update_URL__c = pi.Update_URL__c;
            //ipi.View_Unified_Contact_URL__c = pi.View_Unified_Contact_URL__c;
            //ipi.Whether_Enable_Migration__c = pi.Whether_Enable_Migration__c;
            if(sobjectTypes==null || sobjectTypes.contains(pi.Sobject_Type__c)){
                insertPiList.add(ipi);
            }
        }
        insert insertPiList;
        Map<String,String> typeIdMap = new Map<String,String>();//key: type value: id
        for(PI_Policy_Configuration__c pi:insertPiList){
            typeIdMap.put(pi.Sobject_Type__c,pi.Id);
        }
        String pidJson = '[{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gUcLAAU"},"PI_Policy_Configuration_Name__c":"User_FaultInfo__c","PI_Policy_Configuration__c":"a0x0l000001XTYDAA4","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"INBOUND_EMAIL_ADDRESS__c","AWS_Field_API__c":"inboundEmailAddress","Id":"a0y0l000001gUcLAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gc42AAA"},"PI_Policy_Configuration_Name__c":"Quotes__c","PI_Policy_Configuration__c":"a0x0l000001XWzeAAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"CONTACT_EMAIL__c","AWS_Field_API__c":"contactEmail","Id":"a0y0l000001gc42AAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpuDAAQ"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"from","AWS_Field_API__c":"FROM__c","Id":"a0y0l000001gpuDAAQ","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gb86AAA"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Shipping_Address_Text__c","AWS_Field_API__c":"shippingAddressText","Id":"a0y0l000001gb86AAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbEsAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_N_CONTACT__c","AWS_Field_API__c":"pdfNContact","Id":"a0y0l000001gbEsAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbCIAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryContact_D__c","AWS_Field_API__c":"specialDeliveryContactD","Id":"a0y0l000001gbCIAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbDBAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_N_NotifyParty__c","AWS_Field_API__c":"pdfNNotifyParty","Id":"a0y0l000001gbDBAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbJyAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_F_ContactPerson__c","AWS_Field_API__c":"pdfFContactPerson","Id":"a0y0l000001gbJyAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcK5AAI"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Loaner_receive_staff__c","AWS_Field_API__c":"loanerReceiveStaff","Id":"a0y0l000001gcK5AAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKPAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"return_Number__c","AWS_Field_API__c":"returnNumber","Id":"a0y0l000001gcKPAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001ggpjAAA"},"PI_Policy_Configuration_Name__c":"SWO__c","PI_Policy_Configuration__c":"a0x0l000001XWzKAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"CONTACT_NAME_HIDDEN__c","AWS_Field_API__c":"contactNameHidden","Id":"a0y0l000001ggpjAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSexAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"OtherPhoneD__c","AWS_Field_API__c":"otherPhoneD","Id":"a0y0l000001gSexAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSbZAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"LastName","AWS_Field_API__c":"lastName","Id":"a0y0l000001gSbZAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSduAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Title","AWS_Field_API__c":"title","Id":"a0y0l000001gSduAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeJAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address1D__c","AWS_Field_API__c":"address1D","Id":"a0y0l000001gSeJAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeTAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address3D__c","AWS_Field_API__c":"address3D","Id":"a0y0l000001gSeTAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSdpAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"TitleD__c","AWS_Field_API__c":"titleD","Id":"a0y0l000001gSdpAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSe4AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"EnglishAddress__c","AWS_Field_API__c":"englishAddress","Id":"a0y0l000001gSe4AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSe5AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address1__c","AWS_Field_API__c":"address1","Id":"a0y0l000001gSe5AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeYAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Fax","AWS_Field_API__c":"fax","Id":"a0y0l000001gSeYAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSf7AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"OtherPhone","AWS_Field_API__c":"otherPhone","Id":"a0y0l000001gSf7AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gc47AAA"},"PI_Policy_Configuration_Name__c":"Quotes__c","PI_Policy_Configuration__c":"a0x0l000001XWzeAAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"BILL_TO__c","AWS_Field_API__c":"billTo","Id":"a0y0l000001gc47AAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gUcQAAU"},"PI_Policy_Configuration_Name__c":"User_FaultInfo__c","PI_Policy_Configuration__c":"a0x0l000001XTYDAA4","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"UFPhone__c","AWS_Field_API__c":"ufPhone","Id":"a0y0l000001gUcQAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gc3nAAA"},"PI_Policy_Configuration_Name__c":"Quotes__c","PI_Policy_Configuration__c":"a0x0l000001XWzeAAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"CONTACT_PHONE__c","AWS_Field_API__c":"contactPhone","Id":"a0y0l000001gc3nAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gc43AAA"},"PI_Policy_Configuration_Name__c":"Quotes__c","PI_Policy_Configuration__c":"a0x0l000001XWzeAAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SHIP_TO__c","AWS_Field_API__c":"shipTo","Id":"a0y0l000001gc43AAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbLEAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_Sign_Title__c","AWS_Field_API__c":"pdfSignTitle","Id":"a0y0l000001gbLEAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbL4AAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryAddress__c","AWS_Field_API__c":"specialDeliveryAddress","Id":"a0y0l000001gbL4AAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gb5lAAA"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryPhone_D__c","AWS_Field_API__c":"specialDeliveryPhoneD","Id":"a0y0l000001gb5lAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbKpAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_C_FAX__c","AWS_Field_API__c":"pdfCFax","Id":"a0y0l000001gbKpAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbBcAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryContact__c","AWS_Field_API__c":"specialDeliveryContact","Id":"a0y0l000001gbBcAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gc3xAAA"},"PI_Policy_Configuration_Name__c":"Quotes__c","PI_Policy_Configuration__c":"a0x0l000001XWzeAAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"CONTACT_FAX__c","AWS_Field_API__c":"contactFax","Id":"a0y0l000001gc3xAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbLJAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_Sign_Name__c","AWS_Field_API__c":"pdfSignName","Id":"a0y0l000001gbLJAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbKkAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_C_TEL__c","AWS_Field_API__c":"pdfCTel","Id":"a0y0l000001gbKkAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbKuAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_C_Consignee__c","AWS_Field_API__c":"pdfCConsignee","Id":"a0y0l000001gbKuAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbHcAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_F_TEL__c","AWS_Field_API__c":"pdfFTe","Id":"a0y0l000001gbHcAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbKfAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_C_THECONSIGNE__c","AWS_Field_API__c":"pdfCTheconsigne","Id":"a0y0l000001gbKfAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gb5gAAA"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryPhone__c","AWS_Field_API__c":"specialDeliveryPhone","Id":"a0y0l000001gb5gAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gb6FAAQ"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryContactText__c","AWS_Field_API__c":"specialDeliveryContactText","Id":"a0y0l000001gb6FAAQ","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbI8AAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_F_FAX__c","AWS_Field_API__c":"pdfFFax","Id":"a0y0l000001gbI8AAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbDuAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_N_FAX__c","AWS_Field_API__c":"dfNFax","Id":"a0y0l000001gbDuAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbGoAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_S_TEL__c","AWS_Field_API__c":"pdfSTel","Id":"a0y0l000001gbGoAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbLOAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_By_Tel__c","AWS_Field_API__c":"pdfByTel","Id":"a0y0l000001gbLOAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbKzAAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_C_CONTACT__c","AWS_Field_API__c":"pdfCContact","Id":"a0y0l000001gbKzAAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbL9AAI"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"SpecialDeliveryAddress_D__c","AWS_Field_API__c":"specialDeliveryAddressD","Id":"a0y0l000001gbL9AAI","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gbLTAAY"},"PI_Policy_Configuration_Name__c":"Order","PI_Policy_Configuration__c":"a0x0l000001XVeVAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PDF_By_Add__c","AWS_Field_API__c":"pdfByAdd","Id":"a0y0l000001gbLTAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpotAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"allMemberName","AWS_Field_API__c":"ALL_MEMBER_NAME_Encrypted__c","Id":"a0y0l000001gpotAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpouAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"allMember","AWS_Field_API__c":"ALL_MEMBER_Encrypted__c","Id":"a0y0l000001gpouAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpovAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"bcc","AWS_Field_API__c":"BCC_Encrypted__c","Id":"a0y0l000001gpovAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpowAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"cc","AWS_Field_API__c":"CC_Encrypted__c","Id":"a0y0l000001gpowAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpoxAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"recipient","AWS_Field_API__c":"RECIPIENT_Encrypted__c","Id":"a0y0l000001gpoxAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpoyAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"bccName","AWS_Field_API__c":"bccName__c","Id":"a0y0l000001gpoyAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpozAAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"ccName","AWS_Field_API__c":"ccName__c","Id":"a0y0l000001gpozAAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gpp0AAA"},"PI_Policy_Configuration_Name__c":"Mail_Merge__c","PI_Policy_Configuration__c":"a0x0l000001XswlAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"toName","AWS_Field_API__c":"toName__c","Id":"a0y0l000001gpp0AAA","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gT5TAAU"},"PI_Policy_Configuration_Name__c":"Opportunity","PI_Policy_Configuration__c":"a0x0l000001XB50AAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Dealer_Sales_Staff_Name_D__c","AWS_Field_API__c":"dealerSalesStaffNameD","Id":"a0y0l000001gT5TAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gT5JAAU"},"PI_Policy_Configuration_Name__c":"Opportunity","PI_Policy_Configuration__c":"a0x0l000001XB50AAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Dealer_Service_D__c","AWS_Field_API__c":"dealerServiceD","Id":"a0y0l000001gT5JAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKKAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Return_Trake_Staff__c","AWS_Field_API__c":"returnTrakeStaff","Id":"a0y0l000001gcKKAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKZAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Loaner_Ser__c","AWS_Field_API__c":"loanerSer","Id":"a0y0l000001gcKZAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKAAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"direct_shippment_address__c","AWS_Field_API__c":"directShippmentAddress","Id":"a0y0l000001gcKAAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKFAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Loaner_receive_staff_phone__c","AWS_Field_API__c":"loanerReceiveStaffPhone","Id":"a0y0l000001gcKFAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcKUAAY"},"PI_Policy_Configuration_Name__c":"loaner_application__c","PI_Policy_Configuration__c":"a0x0l000001XX2TAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Post_Code__c","AWS_Field_API__c":"postCode","Id":"a0y0l000001gcKUAAY","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gT5OAAU"},"PI_Policy_Configuration_Name__c":"Opportunity","PI_Policy_Configuration__c":"a0x0l000001XB50AAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"DealerService__c","AWS_Field_API__c":"dealerService","Id":"a0y0l000001gT5OAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gT5YAAU"},"PI_Policy_Configuration_Name__c":"Opportunity","PI_Policy_Configuration__c":"a0x0l000001XB50AAG","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"DealerSalesStaffName__c","AWS_Field_API__c":"dealerSalesStaffName","Id":"a0y0l000001gT5YAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gcrBAAQ"},"PI_Policy_Configuration_Name__c":"loaner_user__c","PI_Policy_Configuration__c":"a0x0l000001XlbnAAC","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"ContactNumber__c","AWS_Field_API__c":"contactNumber","Id":"a0y0l000001gcrBAAQ","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeiAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"EmailD__c","AWS_Field_API__c":"emailD","Id":"a0y0l000001gSeiAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSbjAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PostcodeD__c","AWS_Field_API__c":"postcodeD","Id":"a0y0l000001gSbjAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeEAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address3__c","AWS_Field_API__c":"address3","Id":"a0y0l000001gSeEAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSeOAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address2D__c","AWS_Field_API__c":"address2D","Id":"a0y0l000001gSeOAAU","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSesAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"MobilePhoneD__c","AWS_Field_API__c":"mobilePhoneD","Id":"a0y0l000001gSesAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSenAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Email","AWS_Field_API__c":"email","Id":"a0y0l000001gSenAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSbeAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Postcode__c","AWS_Field_API__c":"postcode","Id":"a0y0l000001gSbeAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSe9AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Address2__c","AWS_Field_API__c":"address2","Id":"a0y0l000001gSe9AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSf2AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"PhoneD__c","AWS_Field_API__c":"phoneD","Id":"a0y0l000001gSf2AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSf3AAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"MobilePhone","AWS_Field_API__c":"mobilePhone","Id":"a0y0l000001gSf3AAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSdzAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"ContactEnglishName__c","AWS_Field_API__c":"contactEnglishName","Id":"a0y0l000001gSdzAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSedAAE"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"FaxD__c","AWS_Field_API__c":"faxD","Id":"a0y0l000001gSedAAE","CurrencyIsoCode":"CNY"},{"attributes":{"type":"PI_Field_Policy_Detail__c","url":"/services/data/v54.0/sobjects/PI_Field_Policy_Detail__c/a0y0l000001gSfCAAU"},"PI_Policy_Configuration_Name__c":"Contact","PI_Policy_Configuration__c":"a0x0l000001XAcZAAW","Enable_Encrypt__c":true,"Field_Type__c":"String","SF_Field_API_Name__c":"Phone","AWS_Field_API__c":"phone","Id":"a0y0l000001gSfCAAU","CurrencyIsoCode":"CNY"}]';
        List<PI_Field_Policy_Detail__c> pidList = (List<PI_Field_Policy_Detail__c>)JSON.deserialize(pidJson,List<PI_Field_Policy_Detail__c>.class);
        List<PI_Field_Policy_Detail__c> insertPidList = new List<PI_Field_Policy_Detail__c>();
        for(PI_Field_Policy_Detail__c pid:pidList){
            if (!typeIdMap.containsKey((pid.PI_Policy_Configuration_Name__c))){
                continue;
            }
            PI_Field_Policy_Detail__c ipid = new PI_Field_Policy_Detail__c();
            ipid.Enable_Encrypt__c = pid.Enable_Encrypt__c;
            ipid.Field_Type__c = pid.Field_Type__c;
            //ipid.Order_Number__c = pid.Order_Number__c;
            ipid.PI_Policy_Configuration__c = typeIdMap.get(pid.PI_Policy_Configuration_Name__c);
            ipid.SF_Field_API_Name__c = pid.SF_Field_API_Name__c;
            ipid.AWS_Field_API__c = pid.AWS_Field_API__c;
            ipid.SF_Field_Encrypted_API__c = pid.SF_Field_Encrypted_API__c;
            ipid.AWS_Encrypted_Field_API__c = pid.AWS_Encrypted_Field_API__c;
            insertPidList.add(ipid);
        }
        insert insertPidList;
    }
    //create sample user
    public static List<User> CreateUsers(Integer num){
        Map<Id,Profile> profileList = new Map<Id, Profile>([SELECT Id, Name FROM Profile]) ;
        Map<String, Profile> profileMap = new Map<String, Profile>();
        Profile p = [select Id from Profile where Name = 'System Administrator'];
        for(Profile profileTemp : profileList.values()){
            profileMap.put(profileTemp.Name, profileTemp);
        }
        List<User> userList=new List<User>();
         for(Integer i = 0 ;i<num;i++){
             User u = new User( Alias = 'test',
                                 Email = 'testuser'+i+'@olympus.com',
                                 Emailencodingkey = 'UTF-8',
                                 Lastname = 'TestUser'+i,
                                 Languagelocalekey = 'zh_CN',
                                 Localesidkey = 'zh_CN',
                                 Profileid = p.id,
                                 Country = 'China',
                                 IsActive = true,
                                 Timezonesidkey = 'America/Sao_Paulo',
                                 Username = 'testuser'+i+'@olympus.com'
                                 //,Job_Category__c = '销售服务'
            );
            userList.add(u);
         }
        insert userList;
        //根据简档名取对应userList  Map<String,List<User>>
        // Map<String, List<User>> sampleUserMap = new Map<String, List<User>>();
        // for(User userTemp : userList){
        //     String profileName = profileList.get(userTemp.Profileid).Name ;
        //     if(sampleUserMap.containsKey(profileName)) {
        //         sampleUserMap.get(profileName).add(userTemp);
        //     }else{
        //         List<User> userTempList = new List<User>();
        //         userTempList.add(userTemp);
        //         sampleUserMap.put(profileName, userTempList);
        //     }
        // }
        // return sampleUserMap;
        //直接返回userlist
        return userList;
    }
    public static List<Account> CreateAccounts(Integer num){
        List<RecordType> rectIE = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer IE'];
        List<Account> acclist = new List<Account>();
        String[] ieSubUse = new String[] {'LED','FPD','半导体','电子部品','电子类_其他','金属','汽车','石油地质','五金模具','重工设备','材料类_其他'};
        for (Integer i = 0; i < num; i++) {
            Account acc1 = new Account();
            acc1.Name = 'TestAccount'+String.valueOf(Datetime.now().minute())+String.valueOf(datetime.now().second())+i;
            acc1.FacilityName__c = 'Account';
            acc1.DivisionName__c = ieSubUse[i];
            acc1.RecordTypeId = rectIE[0].Id;
            acc1.ProductSegment__c = 'IE';
            acc1.Sub_UseD__c = ieSubUse[i];
            acc1.Sub_Use__c = ieSubUse[i];
            acc1.PostCode__c = '000000';
            acclist.add(acc1);
        }
        insert acclist;
        return acclist;
    }
    public static List<Contact> CreateContacts(Integer num){
        List<Account> accList = new List<Account>();
        accList = [Select id From Account];
        if(accList.size()==0){
            accList = CreateAccounts(1);
        }
        List<Contact> conList = new List<Contact>();
        for(Integer i=0;i<num;i++){
            Contact con = new Contact();
            con.AccountId = accList[0].Id;
            con.FirstName = '責任者';
            con.LastName = 'test'+i+'医院';
            //con.Strategic_dept_Class__c = accList[0].Id;
            conList.add(con);
        }
        insert conList;
        return conList;
    }
    public static List<Opportunity> CreateOpportunitys(Integer num){
        //new Contact
        Account acc = new Account();
        if([SELECT Id,Name FROM Account LIMIT 1].size()>0){
            acc = [SELECT Id,Name FROM Account LIMIT 1];
        }else{
            acc = CreateAccounts(1)[0];
        }
        List<Opportunity> oppList = new List<Opportunity>();
        // List<RecordType> rectOpp = [select id from RecordType where IsActive = true and SobjectType = 'Opportunity'];
        for(Integer i=0;i<num;i++){
            Opportunity opp = new Opportunity(
            Name = 'test opp',
            AccountId = acc.Id,
            RecordTypeId = System.Label.SSBD_Replacement,
            OwnerId = UserInfo.getUserId(),
            StageName = 'Phase3',//Prospect Created
            CurrencyIsoCode = 'CNY',
            ProductSegment__c = 'IE',
            TradeType__c = 'Taxation',
            // ForeignTradeCompany_D__c = acc.Id,
            CloseDate = Date.today(),
            NewInquiryDate__c = Date.today().addDays(-2),
            ExpectedOrderDate__c = Date.today().addDays(2),
            SalesChannel__c = 'direct'
        );
            oppList.add(opp);
        }
        insert oppList;
        return oppList;
    }
    public static List<Task> CreateTasks(Integer num){
        List<Task> taList = new List<Task>();
        Account acc = CreateAccounts(1)[0];
        Opportunity opp = CreateOpportunitys(1)[0];
        for(Integer i=0;i<num;i++){
            Task ta = new Task();
             //ta.account__c = acc.id;
            // ta.name = 'testTask'+i;
            // ta.taskStatus__c = '01 分配';
            // ta.assignee__c = UserInfo.getUserId();
            //ta.recordtypeId = Schema.SObjectType.task__c.getRecordTypeInfosByDeveloperName().get('OPD').getRecordTypeId();
            //ta.distributionCount__c = 1;
            //ta.taskDifferent__c = '被动任务';
            //ta.OpportunityId__c = opp.Id;
             //taList.add(ta);
        }
        insert taList;
        return taList;
    }
    public static List<Asset> CreateAssets(Integer num){
        // 省
        /*Address_Level__c al = new Address_Level__c();
        al.Name = '東京';
        al.Level1_Code__c = 'CN-99';
        al.Level1_Sys_No__c = '999999';
        insert al;
        // 市
        Address_Level2__c al2 = new Address_Level2__c();
        al2.Level1_Code__c = 'CN-99';
        al2.Level1_Sys_No__c = '999999';
        al2.Level1_Name__c = '東京';
        al2.Name = '渋谷区';
        al2.Level2_Code__c = 'CN-9999';
        al2.Level2_Sys_No__c = '9999999';
        al2.Address_Level__c = al.id;
        insert al2;*/
        // 病院を作る
        //ControllerUtil.EscapeNFM001Trigger = true;
        //StaticParameter.EscapeNFM001Trigger = true;
        //StaticParameter.EscapeAccountTrigger = true;
        //StaticParameter.EscapeNFM001AgencyContractTrigger = true;
        Account hospital = new Account();
        hospital.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'HP'].id;
        System.debug('病院完了!');
        hospital.Name = 'test hospital';
        //hospital.Is_Active__c = '有効';
        //hospital.Attribute_Type__c = '卫生部';
        //hospital.Speciality_Type__c = '综合医院';
        //hospital.Grade__c = '一级';
        //hospital.OCM_Category__c = 'SLTV';
        //hospital.Is_Medical__c = '医疗机构';
        //hospital.State_Master__c = al.id;
        //hospital.City_Master__c = al2.id;
        //hospital.Town__c = '东京';
        insert hospital;
        System.debug('病院 insert 完了!');
        // 戦略科室を得る
        Account strategicDep = new Account();
        strategicDep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_Class_OTH'].id;
        strategicDep.Name = 'Olympus社内 其他';
        //strategicDep.Department_Class_Label__c = '其他';
        //strategicDep.Hospital__c = hospital.Id;
        strategicDep.ParentId = hospital.Id;
        insert strategicDep;
        // 診療科を作る
        Account dep = new Account();
        dep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_OTH'].id;
        dep.Name = 'test dep';
        //dep.AgentCode_Ext__c = '99998';
        dep.ParentId = strategicDep.Id;
        //dep.Department_Class__c = strategicDep.Id;
        //dep.Hospital__c = hospital.Id;
        insert dep;
        System.debug('診療科 insert 完了!');
        // 产品
        Product2 pro1 = new Product2(Name='name01',IsActive=true,Family='GI');
        insert new Product2[] {pro1};
        List<Asset> asList = new List<Asset>();
        for(Integer i=0;i<num;i++){
            Asset assetA1 = new Asset();
            //assetA1.RecordTypeId = System.Label.Asset_RecordType;
            assetA1.SerialNumber = 'ass'+i;
            assetA1.Name = 'ass'+i;
            assetA1.AccountId = dep.Id;
            //assetA1.Department_Class__c = strategicDep.Id;
            //assetA1.Hospital__c = hospital.Id;
            assetA1.Product2Id = pro1.Id;
            assetA1.Quantity = 1;
            assetA1.Status = '有库存';
            //assetA1.Manage_type__c = '个体管理';
            //assetA1.Loaner_accsessary__c = false;
            //assetA1.Out_of_wh__c = 0;
            //assetA1.Salesdepartment__c = '1.华北营业本部';
            //assetA1.Internal_asset_location__c = '北京 备品中心';
            //assetA1.Product_category__c = 'GI';
            assetA1.Equipment_Type__c = '产品试用';
            //assetA1.SalesProvince__c = '北京';
            asList.add(assetA1);
        }
        insert asList;
        return asList;
    }
    public static List<loaner_application__c> CreateLoanerApplications(Integer num){
        List<RecordType> rectLo = [select Id from RecordType where IsActive = true and SobjectType = 'loaner_application__c' and Name = 'IE'];
        List<loaner_application__c> laList = new List<loaner_application__c>();
        for(Integer i =0;i<num;i++){
            loaner_application__c loaner = new loaner_application__c();
            loaner.Name = 'TEST'+i;
            loaner.RecordTypeId = rectLo[0].id;
            loaner.EC_CODE_1__C = 'DV2-CAMELEONS-CUBE';
            loaner.DEMO_PURPOSE__C = '演示';
            loaner.Request_shipping_Date__c = Date.today().addDays(10);
            loaner.Request_return_Date__c = Date.today().addDays(10);
            loaner.Status__c = '部分发货';
            loaner.Return_Track_Company__c = '物流公司';
            loaner.pickup_time__c  = Date.today();
            loaner.Rental_Start_Date__c = Date.today().addDays(1);
            loaner.Rental_End_Date__c  = Date.today().addDays(2);
            //loaner.Return_Trake_Staff__c = '返品人';
            laList.add(loaner);
        }
        insert laList;
        return laList;
    }
    public static List<Loaner_Express__c> CreateLoanerExpresses(Integer num){
        //new loaner_application__c
        loaner_application__c la = new loaner_application__c();
        if([SELECT Id FROM loaner_application__c LIMIT 1].size()>0){
            la = [SELECT Id FROM loaner_application__c LIMIT 1];
        }else{
            la = Createloanerapplications(1)[0];
        }
        List<Loaner_Express__c> leList = new List<Loaner_Express__c>();
        for(Integer i =0;i<num;i++){
            Loaner_Express__c le = new Loaner_Express__c(
                Name = 'test'+i,
                loaner_application__c = la.Id,
                NotReceivingNum__c = 3
            );
            leList.add(le);
        }
        insert leList;
        return leList;
    }
    public static List<loaner_application_detail__c> CreateLoanerApplicationDetails(Integer num){
        //new account
        List<RecordType> rectCo = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer IE'];
        Account acc = new Account();
        acc.RecordTypeId = rectCo[0].Id;
        acc.Name         = '客户テスト1';
        acc.DivisionName__c = 'DivisionName__c';
        acc.FacilityName__c = 'FacilityName__c';
        acc.PostCode__c='000000';
        insert acc;
        //new asset
        Asset asset = new Asset();
        asset.Name = 'テスト機器1';
        asset.AccountId = acc.Id;
        asset.SerialNumber = 'testserial';
        insert asset;
        //new loaner_application__c
        loaner_application__c la = new loaner_application__c();
        if([SELECT Id FROM loaner_application__c LIMIT 1].size()>0){
            la = [SELECT Id FROM loaner_application__c LIMIT 1];
        }else{
            la = Createloanerapplications(1)[0];
        }
        List<loaner_application_detail__c> ladList = new List<loaner_application_detail__c>();
        for(Integer i =0;i<num;i++){
            loaner_application_detail__c detail = new loaner_application_detail__c();
            detail.loaner_application__c = la.Id;
            detail.loaner__c = asset.id;
            detail.name = 'Test'+i;
            detail.RAESD_STATUS__C = '欠品中';
            //detail.Loaner_Express__c = le.id;
            //loaner.Return_Trake_Staff__c = '返品人';
            ladList.add(detail);
        }
        insert ladList;
        return ladList;
    }
    public static List<User_FaultInfo__c> CreateUserFaultInfos(Integer num){
        List<User_FaultInfo__c> ufList = new List<User_FaultInfo__c>();
        for(Integer i=0;i<num;i++){
            User_FaultInfo__c uf = new User_FaultInfo__c();
            uf.ORIGIN__c = 'Web';
            uf.SUBJECT__c = 'test'+i;
            uf.OFFICE_OWNER__c = 'Beijing';
            uf.Product_Type__c = 'NDT';
            uf.TYPE__c = 'Service';
            uf.LOGISTICS_SHIPMENT_TYPE__c = 'Domestic';
            uf.STATUS__c = 'Not Started';
            uf.PRIORITY__c = 'High';
            ufList.add(uf);
        }
        insert ufList;
        return ufList;
    }
    public static List<Quotes__c> CreateQuotes(Integer num){
        List<Quotes__c> qList = new List<Quotes__c>();
        for(Integer i=0;i<num;i++){
            Quotes__c quotes = new Quotes__c();
            quotes.QuotesType__c = '零件报价单';
            quotes.DATE__c = Date.today();
            quotes.LEAD_TIME__c = '1 week';
            quotes.STATUS__c = 'Qualifying';
            quotes.LOCATION__c = 'China - Service';
            quotes.TERMS__c = '1% 10 Net 30';
            quotes.EXPIRES__c = Date.today();
            quotes.EXP_CLOSE__c = Date.today();
            quotes.ORDER_TYPE__c = 'LS Core Clinical';
            qList.add(quotes);
        }
        insert qList;
        return qList;
    }
    public static List<Repair__c> CreateRepairs (Integer num){
        List<Repair__c> repList = new List<Repair__c>();
        for(Integer i =0;i<num;i++){
            Repair__c rep = new Repair__c();
            rep.Name='test'+i;
            rep.ServicePlace__c='现场';
            repList.add(rep);
        }
        insert repList;
        return repList;
    }
    public static List<loaner_user__c> CreateLoanerUsers(Integer num){
        //new Contact
        Contact con = new Contact();
        if([SELECT Id,Name,AccountId FROM Contact LIMIT 1].size()>0){
            con = [SELECT Id,Name,AccountId FROM Contact LIMIT 1];
        }else{
            con = CreateContacts(1)[0];
        }
        //new loaner_application__c
        loaner_application__c la = new loaner_application__c();
        if([SELECT Id FROM loaner_application__c LIMIT 1].size()>0){
            la = [SELECT Id FROM loaner_application__c LIMIT 1];
        }else{
            la = Createloanerapplications(1)[0];
        }
        List<loaner_user__c> luList = new List<loaner_user__c>();
        for(Integer i=0;i<num;i++){
            loaner_user__c lu = new loaner_user__c();
            lu.Customer__c = con.AccountId;
            lu.Contact__c = con.id;
            lu.loaner_application__c = la.id;
            lu.Remarks__c = 'Test'+i;
            luList.add(lu);
        }
        insert luList;
        return luList;
    }
    public static List<Order> CreateOrders(Integer num){
        //new Contact
        Contact con = new Contact();
        if([SELECT Id,Name,AccountId FROM Contact LIMIT 1].size()>0){
            con = [SELECT Id,Name,AccountId FROM Contact LIMIT 1];
        }else{
            con = CreateContacts(1)[0];
        }
        //new Opportunity
        Opportunity opp = new Opportunity();
        if([SELECT Id,Name FROM Opportunity LIMIT 1].size()>0){
            opp = [SELECT Id,Name FROM Opportunity LIMIT 1];
        }else{
            opp = CreateOpportunitys(1)[0];
        }
        // opp.StageName = 'Phase3';
        // update opp;
        //new Order
        List<Order> odList = new List<Order>();
        for(Integer i=0;i<num;i++){
            Order od = new Order(
            Name = 'TestOrder'+i,
            Status = 'Draft',
            Status__c = 'Active',
            AccountId = con.AccountId,
            ApproveStatus__c = 'Draft',
            OpportunityId = opp.Id,
            // ForeignTradeCompany_D__c = con.AccountId,
            EffectiveDate = Date.today(),
            IE_SP5_D__c = true,
            IE_SP8__c = true,
            SpecialDeliveryAccount_D__c = con.AccountId,
            SpecialDeliveryContact2_D__c = con.Id,
            EndUser__c = con.Id
        );
            odList.add(od);
        }
        insert odList;
        return odList;
    }
    public static List<CampaignMember> CreateCampaignMember(Integer num){
        List<CampaignMember> addList = new List<CampaignMember>();
        //Repair__c rp = CreateRepairs(1)[0];
        Campaign Cam= new Campaign();
        Cam.Name = '学会 培训名称';
        //Cam.Live_Demo_report__c = '学会 培训-测试用';
        //Cam.HostName__c = '小明明明';//会议主办方
        //Cam.cooperatorCompany__c = '会议承办方';//会议承办方
        insert Cam;
        Contact contact4= new Contact();
        //contact4.AccountId = rp.Account__c;
        contact4.FirstName = '小明明明';
        contact4.LastName = 'test4经销商';
        insert contact4;
        for(Integer i=0;i<num;i++){
            CampaignMember add = new CampaignMember();
            add.ContactId = contact4.id;//客户人员, Contact
            //add.MobilePhone__c = '123123666'+i;
            add.CampaignId = Cam.Id;
            addList.add(add);
        }
        insert addList;
        return addList;
    }
    public static List<case> CreateCase(Integer num){
        List<case> addList = new List<case>();
        //Repair__c rp = CreateRepairs(1)[0];
        Account aC = CreateAccounts(1)[0];
        Contact contact5= new Contact();
        //contact5.AccountId = rp.Account__c;
        contact5.FirstName = '小明明明明';
        contact5.LastName = 'test4经销商';
        insert contact5;
        for(Integer i=0;i<num;i++){
            case add = new case();
            add.ContactId = contact5.id;//客户人员姓名, Contact
            //add.Account__c = aC.Id;//客户名称, Account
            add.Subject = 'Test For Case'+i;
            addList.add(add);
        }
        insert addList;
        return addList;
    }
    public static List<Event> CreateEvent(Integer num){
        List<Event> addList = new List<Event>();
        for(Integer i=0;i<num;i++){
            Event add = new Event();
            add.Type = '電話';
            add.Description = 'Test for Event'+i;
            add.DurationInMinutes = 1;//持续时间
            add.ActivityDateTime = Datetime.valueOf('2022-03-17 00:00:00');
            addList.add(add);
        }
        insert addList;
        return addList;
    }
    public static List<Lead> CreateLead(Integer num){
        List<Lead> addList = new List<Lead>();
        //Repair__c rp = CreateRepairs(1)[0];
        /*Asset ast = CreateAssets(1)[0];
        Account strategicDep = new Account();
        strategicDep.recordtypeId = [Select Id FROM RecordType WHERE IsActive = true and SobjectType = 'Account' and DeveloperName = 'Department_Class_OTH'].id;
        strategicDep.Name = 'Olympus社内 其他';
        strategicDep.Department_Class_Label__c = '其他';
        strategicDep.Hospital__c = ast.Hospital__c;
        strategicDep.ParentId = ast.Hospital__c;
        insert strategicDep;
       战略科室分类要和母公司一样     描述    Not(IsBlank(Hospital__c))
                                            && Parent.Parent.RecordTypeId = '01210000000QemG'
                                            && Department_Class__c <> ParentId
        不能更改战略科室的客户名              RecordTypeId != '01210000000QemG' && ISBLANK(Parent.ParentId)
                                      && Parent.RecordTypeId = '01210000000QemG' && ISCHANGED(Name) && !Sys_Dept_Name_Change_Chk__c
        战略科室的医院要和科室的医院一致        IF(Parent.Parent.RecordTypeId = '01210000000QemG',IF(Hospital__c <> Parent.ParentId,TRUE,FALSE),FALSE)
*/
        Account aC = CreateAccounts(1)[0];
        //Contact contactTest = CreateContacts(1)[0];
        //aC.Department_Class__c = '0010l00001PQF0SAAX';
        //aC.ParentId = '0010l00001PQF0SAAX';
        //update aC;
        Contact contact12= new Contact();
        contact12.AccountId = aC.Id;
        contact12.FirstName = '小明明明明';
        contact12.LastName = 'test12经销商';
        insert contact12;
        Account acc = [SELECT Id,Name,parentId,Parent.Parent.RecordTypeId FROM Account WHERE Id =:contact12.AccountId ];
        //acc.Department_Class__c = acc.parentId;
        System.debug('acc-----------'+acc);
        System.debug('acc.parentId-----------'+acc.parentId);
        System.debug('acc.Parent.Parent.RecordTypeId-----------'+acc.Parent.Parent.RecordTypeId);
        update acc;
        //战略科室分类要和母公司一样: []
        //Not(IsBlank(Hospital__c)) && Parent.Parent.RecordTypeId = '01210000000QemG' && Department_Class__c <> ParentId
        for(Integer i=0;i<num;i++){
            Lead add = new Lead();
            add.Phone = '123123666'+i;//电话
            //add.Hospital_Name__c = acc.Id;//客户
            //add.Contact_Name__c = contact12.Id;//客户姓名
            //add.Department_Class__c = acc.Department_Class__c;
            //Hospital_Name__c = Contact_Name__r.AccountId   潜在客户: 医院名 ID等于客户姓名: 客户名 ID
            //Hospital_Name__r.Department_Class__c != Department_Class__c
            //LastName, Company
            add.LastName = 'TestLName'+i;
            add.Company = 'TestCompany';
            addList.add(add);
        }
        insert addList;
        //    与医院名的战略科室分类不一致
        //  AND(NOT(ISBLANK(Hospital_Name__c)),Hospital_Name__r.Department_Class__c != Department_Class__c, $User.Batch_User__c ==FALSE)
        //Hospital_Name__c 不为空 时 需要让 Hospital_Name__r.Department_Class__c == Department_Class__c
        return addList;
    }
/*****************************/
    public class CreatePIHelperHttpMock implements HttpCalloutMock {
        public HTTPResponse respond(HTTPRequest req) {
            Map<String, Object> testMap = new Map<String, Object>();
            testMap.put('Account',CreateAccounts(1)[0]);
            testMap.put('success',true);
            String mapJson = JSON.serialize(testMap);
            HttpResponse res = new HttpResponse();
            res.setHeader('Content-Type', 'text/html');
            res.setBody(mapJson);
            res.setStatusCode(200);
            return res;
        }
    }
    public class CreateMetaDataUtilityHttpMock implements HttpCalloutMock {
        public HTTPResponse respond(HTTPRequest req) {
            HttpResponse res = new HttpResponse();
            res.setHeader('Content-Type', 'text/html');
            res.setBody('{"size":2,"totalSize":2,"done":true,"queryLocator":null,"entityTypeName":"ProfileLayout","records":[{"attributes":{"type":"ProfileLayout","url":"/services/data/v41.0/tooling/sobjects/ProfileLayout/01G1000000hlD1YEAU"},"Layout":{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000009iAb5AAE"},"Name":".客户人员レイアウト","TableEnumOrId":"01I10000000er3hEAA"},"ProfileId":"00e10000000NawVAAS","Profile":{"attributes":{"type":"Profile","url":"/services/data/v41.0/tooling/sobjects/Profile/00e10000000NawVAAS"},"Name":"901_经销商社区普通权限"},"RecordTypeId":null},{"attributes":{"type":"ProfileLayout","url":"/services/data/v41.0/tooling/sobjects/ProfileLayout/01G1000000hlD7CEAU"},"Layout":{"attributes":{"type":"Layout","url":"/services/data/v41.0/tooling/sobjects/Layout/00h10000009iAb5AAE"},"Name":".客户人员レイアウト","TableEnumOrId":"01I10000000er3hEAA"},"ProfileId":"00e10000000NawVAAS","Profile":{"attributes":{"type":"Profile","url":"/services/data/v41.0/tooling/sobjects/Profile/00e10000000NawVAAS"},"Name":"901_经销商社区普通权限"},"RecordTypeId":"012100000006KW5AAM"}]}');
            res.setStatusCode(200);
            res.setStatus('OK');
            return res;
        }
    }
    public class BaseHttpMock implements HttpCalloutMock {
        String body ='';
        String status = '';
        String statusCode = '';
        public BaseHttpMock(String body,String status,String statusCode){
            this.body = body;
            this.status = status;
            this.statusCode = statusCode;
        }
        public HTTPResponse respond(HTTPRequest req) {
            HttpResponse res = new HttpResponse();
            res.setHeader('Content-Type', 'application/json');
            res.setBody(body);
            res.setStatusCode(200);
            res.setStatus('OK');
            return res;
        }
    }
}
force-app/main/default/classes/TestDataUtility.cls-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/TydelikeAccControllerTest.cls
@@ -1,60 +1,56 @@
@isTest
private class TydelikeAccControllerTest {
public class TydelikeAccControllerTest {
    static testMethod void testMethod1() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
            acc1.AssetBS3D__c = '123456';
            acc1.AssetBS2D__c = '123456';
            acc1.OCNServiceStaff__c = UserInfo.getUserId();
            acc1.AssetBS1D__c = '123456';
            acc1.ManagementCode_Ext__c = '123456';
            acc1.Sub_UseD__c = 'LED';
            acc1.AssetBS4D__c = '123456';
            acc1.EnglishNameD__c = '123456';
            acc1.DepartmentNameD__c = '123456';
            acc1.FacilityNameD__c = '123456';
            acc1.IndustryCD__c = 'Education';
            acc1.MarketVerticalsD__c = 'Education';
            acc1.CancelReasonD__c = '123456';
            acc1.ExportRegulatedCustomer__c = true;
            acc1.Province__c = '北京';
            acc1.Whether_OEM__c = true;
            acc1.GlobalAccountName__c = '123456';
            acc1.NationalEnterpriseUser__c = true;
            acc1.DivisionName_D__c = '123456';
            acc1.UseD__c = '(Education)Education';
            acc1.UserType__c = 'OEM客户';
            acc1.WebsiteD__c = 'http://1';
            acc1.KeyAccount__c = 'Large Account';
            acc1.ProductSegment__c = 'BS';
            acc1.FaxD__c = '123456';
            acc1.Remark__c = '123456';
            acc1.DealerSelectOwner__c = UserInfo.getUserId();
            acc1.PhoneD__c = '15555555555';
        insert acc1;
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
            tycon1.EnglishAddress__c = '111111';
            tycon1.ContactEnglishName__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        PageReference page = new PageReference('/apex/TydelikeAcc?tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeAccController controller = new TydelikeAccController();
        controller.init();
        controller.save();
        TydelikeAccount__c tyactest = new TydelikeAccount__c();
        tyactest.Name = 'test';
        tyactest.AssetBS3D__c = 'test';
        tyactest.AssetBS2D__c = 'test';
        tyactest.AssetBS1D__c = 'test';
        tyactest.AssetBS5D__c = 'test';
        tyactest.ManagementCode_Ext__c = 'test';
        tyactest.Sub_UseD__c = 'LED';
        tyactest.EnglishNameD__c = 'test';
        tyactest.DepartmentNameD__c = 'test';
        tyactest.FacilityNameD__c = 'test';
        tyactest.MarketVerticalsD__c = 'Education';
        tyactest.CancelReasonD__c = 'test';
        tyactest.ExportRegulatedCustomer__c = false;
        tyactest.Province__c = '北京';
        tyactest.Whether_OEM__c = false;
        tyactest.GlobalAccountName__c = 'test';
        tyactest.DivisionName_D__c = 'test';
        tyactest.UseD__c = 'IVF';
        //tyactest.WebsiteD__c = '';
        tyactest.TyCity__c = 'PII';
        tyactest.TyAddress__c = 'PII';
        tyactest.TyPostCode__c = 'PII';
        tyactest.ProductSegment__c = 'BS';
        tyactest.FaxD__c = 'test';
        tyactest.Remark__c = 'PII';
        //tyactest.DealerSelectOwner__c = 'OT-IT';
        tyactest.PhoneD__c = '13455556666';
        tyactest.NationalEnterpriseUser__c = false;
        tyactest.AssetBS4D__c = 'test';
        insert tyactest;
        TydelikeContact__c tycotest = new TydelikeContact__c();
        tycotest.Name = 'test';
        tycotest.TyAddress__c = 'test';
        tycotest.TyFaxD__c = 'test';
        tycotest.TyPhoneD__c = '13566667777';
        tycotest.TyPostcode__c = '5000000';
        tycotest.EnglishAddress__c = 'test';
        tycotest.ContactEnglishName__c = 'test';
        insert tycotest;
        String url = ApexPages.currentPage().getParameters().put('tyacId',tyactest.Id);
        url = ApexPages.currentPage().getParameters().put('tycoId',tycotest.Id);
        Test.startTest();
        TydelikeAccController scc = new TydelikeAccController();
        scc.init();
        scc.save();
        Test.stopTest();
    }
}
force-app/main/default/classes/TydelikeAccControllerTest.cls-meta.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>41.0</apiVersion>
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/classes/TydelikeConControllerTest.cls
@@ -1,236 +1,47 @@
@isTest
private class TydelikeConControllerTest {
public class TydelikeConControllerTest {
    static testMethod void testMethod1() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
        insert acc1;
        Account acctest = TestDataUtility.CreateAccounts(1)[0];
        acctest.ProductSegment__c = 'BS';
        update acctest;
        TydelikeContact__c tycotest = new TydelikeContact__c();
        tycotest.Name = 'test';
        tycotest.TyAddress__c = 'test';
        tycotest.TyFaxD__c = 'test';
        tycotest.TyPhoneD__c = '13566667777';
        tycotest.TyPostcode__c = '5000000';
        tycotest.EnglishAddress__c = 'test';
        tycotest.ContactEnglishName__c = 'test';
        insert tycotest;
        TydelikeAccount__c tyaccount = new TydelikeAccount__c();
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
            tycon1.EnglishAddress__c = '111111';
            tycon1.ContactEnglishName__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        List<RecordType> rectDealer = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Dealer'];
        List<RecordType> rectBS = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer BS'];
        Account buyer = new Account(
            Name = '*',
            FacilityName__c = 'buyer',
            PostCode__c = '123456',
            RecordTypeId = rectDealer[0].Id,
            ProductSegment__c = 'BS'
        );
        insert buyer;
        System.debug(buyer);
        /*Account accBS = new Account(
            Name = '12343',
            RecordTypeId = rectBS[0].Id,
            OwnerId = UserInfo.getUserId(),
            DivisionName_D__c = '010',
            FacilityNameD__c = '011',
            DepartmentNameD__c = '001',
            Province__c = '北京',
            CityD__c = 'beijing',
            Address1D__c = '7hao',
            UserType__c = 'OEM客户',
            MarketVerticalsD__c = 'Education',
            IndustryBD__c = 'Education',
            UseD__c = 'Education',
            DivisionName__c = '010',
            FacilityName__c = '011',
            DepartmentName__c = '001',
            City__c = 'beijing',
            Address1__c = '7hao',
            MarketVerticals__c = 'Education',
            IndustryB__c = 'Education',
            Use__c = 'Education',
            ProductSegment__c = 'BS'
        );
        insert accBS;
        System.debug(accBS);*/
        PageReference page = new PageReference('/apex/TydelikeCon?accName=' + buyer.Name + '&tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeConController controller = new TydelikeConController();
        controller.init();
        controller.save();
        String url = ApexPages.currentPage().getParameters().put('accName',acctest.Name);
        url = ApexPages.currentPage().getParameters().put('tycoId',tycotest.Id);
        url = ApexPages.currentPage().getParameters().put('tyacId',tyaccount.Id);
        Test.startTest();
        TydelikeConController scc = new TydelikeConController();
        scc.acc = acctest;
        scc.tya = tyaccount;
        scc.init();
        scc.save();
        acctest.ProductSegment__c = 'IE';
        update acctest;
        scc.init();
        acctest.ProductSegment__c = 'NDT';
        update acctest;
        scc.init();
        acctest.ProductSegment__c = 'ANI';
        update acctest;
        scc.init();
        acctest.ProductSegment__c = 'RVI';
        update acctest;
        scc.init();
        Test.stopTest();
    }
     static testMethod void testMethod2() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
        insert acc1;
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        List<RecordType> rectDealer = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Dealer'];
        List<RecordType> rectBS = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer BS'];
        Account buyer = new Account(
            Name = '*',
            FacilityName__c = 'buyer',
            PostCode__c = '123456',
            RecordTypeId = rectDealer[0].Id,
            ProductSegment__c = 'IE'
        );
        insert buyer;
        System.debug(buyer);
        PageReference page = new PageReference('/apex/TydelikeCon?accName=' + buyer.Name + '&tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeConController controller = new TydelikeConController();
        controller.init();
        controller.save();
    }
     static testMethod void testMethod3() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
        insert acc1;
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        List<RecordType> rectDealer = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Dealer'];
        List<RecordType> rectBS = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer BS'];
        Account buyer = new Account(
            Name = '*',
            FacilityName__c = 'buyer',
            PostCode__c = '123456',
            RecordTypeId = rectDealer[0].Id,
            ProductSegment__c = 'NDT'
        );
        insert buyer;
        System.debug(buyer);
        PageReference page = new PageReference('/apex/TydelikeCon?accName=' + buyer.Name + '&tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeConController controller = new TydelikeConController();
        controller.init();
        controller.save();
    }
     static testMethod void testMethod4() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
        insert acc1;
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        List<RecordType> rectDealer = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Dealer'];
        List<RecordType> rectBS = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer BS'];
        Account buyer = new Account(
            Name = '*',
            FacilityName__c = 'buyer',
            PostCode__c = '123456',
            RecordTypeId = rectDealer[0].Id,
            ProductSegment__c = 'ANI'
        );
        insert buyer;
        System.debug(buyer);
        PageReference page = new PageReference('/apex/TydelikeCon?accName=' + buyer.Name + '&tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeConController controller = new TydelikeConController();
        controller.init();
        controller.save();
    }
     static testMethod void testMethod5() {
        TydelikeAccount__c acc1 = new TydelikeAccount__c();
            acc1.name = '**';
            acc1.OwnerId = UserInfo.getUserId();
            acc1.TyCity__c = '北京';
            acc1.OfSkrap__c = false;
            acc1.TyAddress__c = '11111';
            acc1.TyPostCode__c = '123456';
        insert acc1;
        TydelikeContact__c tycon1 = new TydelikeContact__c();
            tycon1.name = '*';
            tycon1.OfSkrap__c = false;
            tycon1.TydelikeAccount__c = acc1.Id;
            tycon1.TyAddress__c = '11111';
            tycon1.TyFaxD__c = '1111';
            tycon1.TyPhoneD__c = '15555555555';
            tycon1.TyPostcode__c = '111111';
        insert tycon1;
        System.debug(tycon1);
        List<RecordType> rectDealer = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Dealer'];
        List<RecordType> rectBS = [select Id from RecordType where IsActive = true and SobjectType = 'Account' and Name = 'Customer BS'];
        Account buyer = new Account(
            Name = '*',
            FacilityName__c = 'buyer',
            PostCode__c = '123456',
            RecordTypeId = rectDealer[0].Id,
            ProductSegment__c = 'RVI'
        );
        insert buyer;
        System.debug(buyer);
        PageReference page = new PageReference('/apex/TydelikeCon?accName=' + buyer.Name + '&tyacId=' + acc1.Id + '&tycoId=' + tycon1.Id);
        System.Test.setCurrentPage(page);
        TydelikeConController controller = new TydelikeConController();
        controller.init();
        controller.save();
    }
}
force-app/main/default/classes/TydelikeConControllerTest.cls-meta.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>41.0</apiVersion>
    <apiVersion>54.0</apiVersion>
    <status>Active</status>
</ApexClass>
force-app/main/default/pages/NewAndEditContact.page
New file
@@ -0,0 +1,477 @@
<!--
@description       :
@author            : ChangeMeIn@UserSettingsUnder.SFDoc
@group             :
@last modified on  : 03-08-2022
@last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Contact" extensions="NewAndEditContactController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                            //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                            if(ele && data.object[f]){
                                let arr = data.object[f].split(';');
                                // 给隐藏的select赋值
                                for(let op of ele.options){
                                    op.selected = arr.indexOf(op.value)>-1;
                                }
                                // 利用按钮给显示的select赋值
                                let ra = document.getElementById(ele.id + '_right_arrow');
                                if(ra){
                                    ra.click();
                                }
                            }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditContactController.saveContact",
            insertMethod:"NewAndEditContactController.saveContact"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='MobilePhone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //     result[field_api_name] = e1.value;
                // }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Contact[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                        required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
            if(IsFormElement(e)){
                api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //3. Set Readonly Attribute
                document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
                if({!isNewMode}){
                    document.getElementById("page:form:block:j_id50:0:j_id51:j_id52:0:j_id53_lkid").value = '{!account.Id}';
                    document.getElementById("page:form:block:j_id50:0:j_id51:j_id52:0:j_id53_lkold").value = '{!account.Name}';
                    document.getElementById("page:form:block:j_id50:0:j_id51:j_id52:0:j_id53").value = '{!account.Name}';
                    document.getElementById("page:form:block:j_id50:0:j_id51:j_id52:5:j_id53").value = '{!account.PhoneD__c}';
                    document.getElementById("page:form:block:j_id50:0:j_id51:j_id52:8:j_id53").value = '{!account.FaxD__c}';
                    document.getElementById("page:form:block:j_id50:1:j_id51:j_id52:0:j_id53").value = '{!account.PostCodeD__c}';
                    document.getElementById("page:form:block:j_id50:2:j_id51:j_id52:0:j_id53").value = '{!account.Address1D__c}';
                }
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditContact.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditContact</label>
</ApexPage>
force-app/main/default/pages/NewAndEditLoanerAppDetail.page
New file
@@ -0,0 +1,6 @@
<apex:page >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>
force-app/main/default/pages/NewAndEditLoanerAppDetail.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditLoanerAppDetail</label>
</ApexPage>
force-app/main/default/pages/NewAndEditLoanerApplication.page
New file
@@ -0,0 +1,474 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 03-03-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="loaner_application__c" extensions="NewAndEditLoanerApplicationController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                              if(ele && data.object[f]){
                                  let arr = data.object[f].split(';');
                                  // 给隐藏的select赋值
                                  for(let op of ele.options){
                                      op.selected = arr.indexOf(op.value)>-1;
                                  }
                                  // 利用按钮给显示的select赋值
                                  let ra = document.getElementById(ele.id + '_right_arrow');
                                  if(ra){
                                      ra.click();
                                  }
                              }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditLoanerApplicationController.saveLoanerApplication",
            insertMethod:"NewAndEditLoanerApplicationController.saveLoanerApplication"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
              NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
              UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
    function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            // let textEmail = "[data-id='Email']";
            let textReturnPhone = "[data-id='return_Number__c']";
            let textPhone = "[data-id='Loaner_receive_staff_phone__c']";
            //Email
            // let email = document.querySelector(textEmail);
            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
            //     error_msg += ';邮件格式错误';
            // }
            let returnPhone = document.querySelector(textReturnPhone);
            if(returnPhone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(returnPhone.value)){
                error_msg += ';    返品人电话号码错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';    收件人电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //     result[field_api_name] = e1.value;
                // }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!loaner_application__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                        required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
                var init_nodes = document.getElementsByClassName("PIBackApi");
                var api_id_map={};
                for(let e of init_nodes){
                if(IsFormElement(e)){
                    api_id_map[GetEleApiName(e)] = e.id;
                    }
                }
                console.log(api_id_map);
                sfdcPage.appendToOnloadQueue(function () {
                    //1. Set Last Name label
                    //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                    //2. Query AWS Data by dataId
                    console.log('Mode for Sobject Page:' + {!isNewMode});
                    if (!{!isNewMode}) {
                        blockme();
                        QuerySobjectFromAWS();
                    }
                    //3. Set Readonly Attribute
                    document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                    document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
                });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditLoanerApplication.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditLoanerApplication</label>
</ApexPage>
force-app/main/default/pages/NewAndEditLoanerExpress.page
New file
@@ -0,0 +1,6 @@
<apex:page >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>
force-app/main/default/pages/NewAndEditLoanerExpress.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditLoanerExpress</label>
</ApexPage>
force-app/main/default/pages/NewAndEditLoanerUser.page
New file
@@ -0,0 +1,544 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 03-04-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="loaner_user__c" extensions="NewAndEditLoanerUserController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                               if(ele && data.object[f]){
                                   let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                   for(let op of ele.options){
                                       op.selected = arr.indexOf(op.value)>-1;
                                   }
                                   // 利用按钮给显示的select赋值
                                   let ra = document.getElementById(ele.id + '_right_arrow');
                                   if(ra){
                                       ra.click();
                                   }
                               }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditLoanerUserController.saveLoanerUser",
            insertMethod:"NewAndEditLoanerUserController.saveLoanerUser"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            // let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='ContactNumber__c']";
            //Email
            // let email = document.querySelector(textEmail);
            // if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
            //     error_msg += ';邮件格式错误';
            // }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';联系电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. loaner_user__c to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        //替换vlookup
        // var newSearchContactWindow = null;
        // function replaceSearchContactLookup() {
        //     if (!{!isNewMode}) {
        //         //1. Query Contact from AWS by AWSDataId
        //         queryContactName()
        //     }
        //     if(document.querySelector("[data-id='Contact__c']") != null){
        //         let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact('page:form:contactId')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
        //         let lookUpNode = htmlToElement(contactHtmlString);
        //         console.log(lookUpNode);
        //         let parentNode = document.querySelector("[data-id='Contact__c']").parentNode;
        //         document.querySelector("[data-id='Contact__c']").removeAttribute("onchange");
        //         parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Contact__c']").parentNode.children[2]);
        //     }
        // }
        // function htmlToElement(html) {
        //     var template = document.createElement('template');
        //     html = html.trim(); // Never return a text node of whitespace as the result
        //     template.innerHTML = html;
        //     return template.content.firstChild;
        // }
        // function queryContactName() {
        //     let sfId = document.getElementById(document.querySelector("[data-id='Contact__c']").id + '_lkid').value;
        //     let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
        //     let dataId = contactsInfo[sfId];
        //     let url = staticResourcesContact.queryUrl + '?dataId=' + dataId;
        //     fetch(url, {
        //         method: 'GET',
        //         headers: {
        //             'Content-Type': 'application/json',
        //             'pi-token': staticResources.token
        //         }
        //     }).then((data) => {
        //         return data.json();
        //     }).then((result) => {
        //         document.querySelector("[data-id='Contact__c']").value = result.object.lastName;
        //     })
        // }
        // //自定义lookup查询
        // function searchContact(contactNodeId){
        //     let accountValue = "";
        //     if (document.querySelector("[data-id='AccountId']")) {
        //         let accountNodeId = document.querySelector("[data-id='AccountId']").id + '_lkid';
        //         accountValue = document.getElementById(accountNodeId).value;
        //     }
        //     console.log(accountValue);
        //     if(accountValue !='000000000000000'){
        //         let baseUrl = "/apex/SearchContactPage";
        //         let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
        //         let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
        //         newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
        //         if (window.focus) {
        //             newSearchContactWindow.focus();
        //         }
        //         return false;
        //     }else{
        //         alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
        //     }
        // }
        // function closePopupWindow() {
        //     if (null != newSearchContactWindow) {
        //         newSearchContactWindow.close();
        //     }
        //     let contactInfoStr = document.getElementById('page:form:contactId').value;
        //     console.log('closePopup:'+contactInfoStr);
        //     let contactInfo = JSON.parse(contactInfoStr);
        //     let contactNodeId = document.querySelector("[data-id='Contact__c']").id + '_lkid';
        //     document.getElementById(contactNodeId).value = contactInfo.ContactId;
        //     document.querySelector("[data-id='Contact__c']").value = contactInfo.Name;
        // }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <!-- <apex:inputHidden value="{!contactId}" id="contactId"/> -->
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!loaner_user__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                        required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                    api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //Replace Vlookup Field
                // replaceSearchContactLookup();
                //3. Set Readonly Attribute
                // document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                // document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditLoanerUser.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditLoanerUser</label>
</ApexPage>
force-app/main/default/pages/NewAndEditOpportunity.page
New file
@@ -0,0 +1,559 @@
<!--
    @description       :
    @author            : ChangeMeIn@UserSettingsUnder.SFDoc
    @group             :
    @last modified on  : 03-08-2022
    @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Opportunity" extensions="NewAndEditOpportunityController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                                if(ele && data.object[f]){
                                    let arr = data.object[f].split(';');
                                   // 给隐藏的select赋值
                                    for(let op of ele.options){
                                        op.selected = arr.indexOf(op.value)>-1;
                                    }
                                    // 利用按钮给显示的select赋值
                                    let ra = document.getElementById(ele.id + '_right_arrow');
                                    if(ra){
                                        ra.click();
                                    }
                                }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditOpportunityController.saveOpportunity",
            insertMethod:"NewAndEditOpportunityController.saveOpportunity"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='MobilePhone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. opportunity to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        //替换vlookup
        var newSearchContactWindow = null;
        var closeField = '';
        function replaceSearchContactLookup() {
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            if(document.querySelector("[data-id='EndUser__c']") != null){
                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'EndUser__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='EndUser__c']").parentNode;
                document.querySelector("[data-id='EndUser__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='EndUser__c']").parentNode.children[2]);
            }
            // if(document.querySelector("[data-id='Applicanter__c']") != null){
            //     let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'Applicanter__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
            //     let lookUpNode = htmlToElement(contactHtmlString);
            //     console.log(lookUpNode);
            //     let parentNode = document.querySelector("[data-id='Applicanter__c']").parentNode;
            //     document.querySelector("[data-id='Applicanter__c']").removeAttribute("onchange");
            //     parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='Applicanter__c']").parentNode.children[2]);
            // }
        }
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='EndUser__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = contactsInfo[sfId];
            let queryContactBack = function(data){
                //To Do later
                console.log('ContactData = ' + data.object);
                document.querySelector("[data-id='EndUser__c']").value = data.object.lastName;
            }
            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            // queryContactNameFetch(dataId, 'EndUser__c');
        }
        // function queryContactNameFetch(dataId, filedId){
        //     let queryContactBack = function(data){
        //         //To Do later
        //         console.log('ContactData = ' + data.object);
        //         document.querySelector("[data-id="+filedId+"]").value = data.object.lastName;
        //     }
        //     AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
        // }
        //自定义lookup查询
        function searchContact(contactNodeId,field){
            closeField = field;
            let accountValue = "";
            if (document.querySelector("[data-id='AccountId']")) {
                let accountNodeId = document.querySelector("[data-id='AccountId']").id + '_lkid';
                accountValue = document.getElementById(accountNodeId).value;
            }
            console.log(accountValue);
            if(accountValue !='000000000000000'){
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }else{
                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Opportunity[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                         required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                     api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //Replace Vlookup Field
                replaceSearchContactLookup();
                //3. Set Readonly Attribute
                document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditOpportunity.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditOpportunity</label>
</ApexPage>
force-app/main/default/pages/NewAndEditOrder.page
New file
@@ -0,0 +1,728 @@
<!--
@description       :
@author            : ChangeMeIn@UserSettingsUnder.SFDoc
@group             :
@last modified on  : 03-08-2022
@last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Order" extensions="NewAndEditOrderController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                            if(ele && data.object[f]){
                                let arr = data.object[f].split(';');
                                // 给隐藏的select赋值
                                for(let op of ele.options){
                                    op.selected = arr.indexOf(op.value)>-1;
                                }
                                // 利用按钮给显示的select赋值
                                let ra = document.getElementById(ele.id + '_right_arrow');
                                if(ra){
                                    ra.click();
                                }
                            }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditOrderController.saveOrder",
            insertMethod:"NewAndEditOrderController.saveOrder"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='MobilePhone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //  result[field_api_name] = e1.value;
                // }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        //替换vlookup
        var newSearchContactWindow = null;
        var closeField = '';
        function replaceSearchContactLookup() {
            let contactHtmlString = '';
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            if(document.querySelector("[data-id='EndUserD__c']") != null){
                contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\', \'EndUserD__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='EndUserD__c']").parentNode;
                document.querySelector("[data-id='EndUserD__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='EndUserD__c']").parentNode.children[2]);
            }
            if(document.querySelector("[data-id='EndUser__c']") != null){
                contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\', \'EndUser__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='EndUser__c']").parentNode;
                document.querySelector("[data-id='EndUser__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='EndUser__c']").parentNode.children[2]);
            }
            if(document.querySelector("[data-id='ShipToContactId']") != null){
                contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\', \'ShipToContactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='ShipToContactId']").parentNode;
                document.querySelector("[data-id='ShipToContactId']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='ShipToContactId']").parentNode.children[2]);
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2__c']") != null){
                contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\', \'SpecialDeliveryContact2__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='SpecialDeliveryContact2__c']").parentNode;
                document.querySelector("[data-id='SpecialDeliveryContact2__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='SpecialDeliveryContact2__c']").parentNode.children[2]);
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2_D__c']") != null){
                contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\', \'SpecialDeliveryContact2_D__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='SpecialDeliveryContact2_D__c']").parentNode;
                document.querySelector("[data-id='SpecialDeliveryContact2_D__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='SpecialDeliveryContact2_D__c']").parentNode.children[2]);
            }
        }
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function queryContactName() {
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            if(document.querySelector("[data-id='EndUserD__c']") != null){
                let sfId = document.getElementById(document.querySelector("[data-id='EndUserD__c']").id + '_lkid').value;
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    console.log('ContactData = ' + data.object);//To Do later
                    document.querySelector("[data-id='EndUserD__c']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
            if(document.querySelector("[data-id='EndUser__c']") != null){
                let sfId = document.getElementById(document.querySelector("[data-id='EndUser__c']").id + '_lkid').value;
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    console.log('ContactData = ' + data.object);//To Do later
                    document.querySelector("[data-id='EndUser__c']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
            if(document.querySelector("[data-id='ShipToContactId']") != null){
                let sfId = document.getElementById(document.querySelector("[data-id='ShipToContactId']").id + '_lkid').value;
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    console.log('ContactData = ' + data.object);//To Do later
                    document.querySelector("[data-id='ShipToContactId']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2__c']") != null){
                let sfId = document.getElementById(document.querySelector("[data-id='SpecialDeliveryContact2__c']").id + '_lkid').value;
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    console.log('ContactData = ' + data.object);//To Do later
                    document.querySelector("[data-id='SpecialDeliveryContact2__c']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2_D__c']") != null){
                let sfId = document.getElementById(document.querySelector("[data-id='SpecialDeliveryContact2_D__c']").id + '_lkid').value;
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    console.log('ContactData = ' + data.object);//To Do later
                    document.querySelector("[data-id='SpecialDeliveryContact2_D__c']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
        }
        //自定义lookup查询
        function searchContact(contactNodeId, field){
            closeField = field;
            if(field == 'SpecialDeliveryContact2__c'){
                let accountValue = "";
                let SpecialDeliveryAccountValue = "";
                let SpecialDeliveryAccountNodeId = "";
                let ForeignTradeCompanyValue = "";
                let ForeignTradeCompanyNodeId = "";
                if (document.querySelector("[data-id='SpecialDeliveryAccount__c']")) {
                    SpecialDeliveryAccountNodeId = document.querySelector("[data-id='SpecialDeliveryAccount__c']").id + '_lkid';
                    console.log('SpecialDeliveryAccountNodeId: ' + SpecialDeliveryAccountNodeId);
                    SpecialDeliveryAccountValue = document.getElementById(SpecialDeliveryAccountNodeId).value;
                    console.log(SpecialDeliveryAccountValue);
                    if (SpecialDeliveryAccountValue!= '' && SpecialDeliveryAccountValue != '000000000000000'){
                        accountValue = ',' + SpecialDeliveryAccountValue;
                    }
                }
                if (document.querySelector("[data-id='ForeignTradeCompany__c']")) {
                    ForeignTradeCompanyNodeId = document.querySelector("[data-id='ForeignTradeCompany__c']").id + '_lkid';
                    console.log('ForeignTradeCompanyNodeId: ' + ForeignTradeCompanyNodeId);
                    ForeignTradeCompanyValue = document.getElementById(ForeignTradeCompanyNodeId).value;
                    console.log(ForeignTradeCompanyValue);
                    if (ForeignTradeCompanyValue!= '' && ForeignTradeCompanyValue != '000000000000000'){
                        accountValue += ','+ForeignTradeCompanyValue;
                    }
                    accountValue = accountValue.substring(1);
                }
                if (accountValue != ''){
                    let baseUrl = "/apex/SearchContactPage";
                    let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                    let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                    newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                    if (window.focus) {
                        newSearchContactWindow.focus();
                    }
                    return false;
                }else{
                    let accountValue = "";
                    if (SpecialDeliveryAccountValue != '000000000000000'){
                        accountValue = SpecialDeliveryAccountValue;
                    }else {
                        accountValue = ForeignTradeCompanyValue;
                    }
                    let baseUrl = "/apex/SearchContactPage";
                    let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                    let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                    newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                    if (window.focus) {
                        newSearchContactWindow.focus();
                    }
                    return false;
                }
            } else if (field == 'SpecialDeliveryContact2_D__c'){
                let accountValueD = "";
                let SpecialDeliveryAccountDValue = "";
                let SpecialDeliveryAccountDNodeId = "";
                let ForeignTradeCompanyDValue = "";
                let ForeignTradeCompanyDNodeId = "";
                if (document.querySelector("[data-id='SpecialDeliveryAccount_D__c']")) {
                    SpecialDeliveryAccountDNodeId = document.querySelector("[data-id='SpecialDeliveryAccount_D__c']").id + '_lkid';
                    console.log('SpecialDeliveryAccountDNodeId: ' + SpecialDeliveryAccountDNodeId);
                    SpecialDeliveryAccountDValue = document.getElementById(SpecialDeliveryAccountDNodeId).value;
                    console.log(SpecialDeliveryAccountDValue);
                    if (SpecialDeliveryAccountDValue!= '' && SpecialDeliveryAccountDValue != '000000000000000'){
                        accountValueD = ',' + SpecialDeliveryAccountDValue;
                    }
                }
                if (document.querySelector("[data-id='ForeignTradeCompany_D__c']")) {
                    ForeignTradeCompanyDNodeId = document.querySelector("[data-id='ForeignTradeCompany_D__c']").id + '_lkid';
                    console.log('ForeignTradeCompanyDNodeId: ' + ForeignTradeCompanyDNodeId);
                    ForeignTradeCompanyDValue = document.getElementById(ForeignTradeCompanyDNodeId).value;
                    console.log(ForeignTradeCompanyDValue);
                    if (ForeignTradeCompanyDValue!= '' && ForeignTradeCompanyDValue != '000000000000000'){
                        accountValueD += ','+ForeignTradeCompanyDValue;
                    }
                    accountValueD = accountValueD.substring(1);
                }
                if (accountValueD != ''){
                    let baseUrl = "/apex/SearchContactPage";
                    let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValueD;
                    let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                    newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                    if (window.focus) {
                        newSearchContactWindow.focus();
                    }
                    return false;
                }else{
                    let accountValueD = "";
                    if (SpecialDeliveryAccountDValue != '000000000000000'){
                        accountValueD = SpecialDeliveryAccountDValue;
                    }else {
                        accountValueD = ForeignTradeCompanyDValue;
                    }
                    let baseUrl = "/apex/SearchContactPage";
                    let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValueD;
                    let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                    newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                    if (window.focus) {
                        newSearchContactWindow.focus();
                    }
                    return false;
                }
            } else {
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId="+contactNodeId;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2__c']") != null){
                if (null != newSearchContactWindow) {
                    newSearchContactWindow.close();
                }
                let contactInfoStr = document.getElementById('page:form:contactId').value;
                console.log('closePopup:'+contactInfoStr);
                let contactInfo = JSON.parse(contactInfoStr);
                let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
                document.getElementById(contactNodeId).value = contactInfo.ContactId;
                document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
            }
            if(document.querySelector("[data-id='SpecialDeliveryContact2_D__c']") != null){
                if (null != newSearchContactWindow) {
                    newSearchContactWindow.close();
                }
                let contactInfoStr = document.getElementById('page:form:contactId').value;
                console.log('closePopup:'+contactInfoStr);
                let contactInfo = JSON.parse(contactInfoStr);
                let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
                document.getElementById(contactNodeId).value = contactInfo.ContactId;
                document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
            }
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Order[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                        required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                    api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //Replace Vlookup Field
                replaceSearchContactLookup();
                //3. Set Readonly Attribute
                document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditOrder.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditOrder</label>
</ApexPage>
force-app/main/default/pages/NewAndEditQuotes.page
New file
@@ -0,0 +1,547 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 03-04-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Quotes__c" extensions="NewAndEditQuotesController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.medicalStaffFullName = leadPIData.lastName;// 完成field update workflow
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                                if(ele && data.object[f]){
                                    let arr = data.object[f].split(';');
                                    // 给隐藏的select赋值
                                    for(let op of ele.options){
                                        op.selected = arr.indexOf(op.value)>-1;
                                    }
                                    // 利用按钮给显示的select赋值
                                    let ra = document.getElementById(ele.id + '_right_arrow');
                                    if(ra){
                                        ra.click();
                                    }
                                }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditQuotesController.saveQuotes",
            insertMethod:"NewAndEditQuotesController.saveQuotes"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='MobilePhone']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
                // let e1 = document.getElementById(api_id_map[field_api_name]);
                // if(!result[field_api_name] && e1 && e1.value){
                //  result[field_api_name] = e1.value;
                // }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. lead to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        //替换vlookup
        var newSearchContactWindow = null;
        var closeField = '';
        function replaceSearchContactLookup() {
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            if(document.querySelector("[data-id='CONTACT_NAME__c']") != null){
                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='CONTACT_NAME__c']").parentNode;
                document.querySelector("[data-id='CONTACT_NAME__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='CONTACT_NAME__c']").parentNode.children[2]);
            }
        }
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function queryContactName() {
            let sfId = document.getElementById(document.querySelector("[data-id='CONTACT_NAME__c']").id + '_lkid').value;
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let dataId = contactsInfo[sfId];
            let queryContactBack = function(data){
                //To Do later
                console.log('ContactData = ' + data.object);
                document.querySelector("[data-id='CONTACT_NAME__c']").value = data.object.lastName;
            }
            AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
        }
        //自定义lookup查询
        function searchContact(contactNodeId,field){
            closeField = field;
            let accountValue = "";
            if (document.querySelector("[data-id='AccountId']")) {
                let accountNodeId = document.querySelector("[data-id='AccountId']").id + '_lkid';
                accountValue = document.getElementById(accountNodeId).value;
            }
            console.log(accountValue);
            if(accountValue !='000000000000000'){
                let baseUrl = "/apex/SearchContactPage";
                let suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }else{
                alertErrorMessage('{!PIPL_Input_Account_Error_Msg}');
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!Quotes__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                        required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                    api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //Replace Vlookup Field
                replaceSearchContactLookup();
                //3. Set Readonly Attribute
                document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditQuotes.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditQuotes</label>
</ApexPage>
force-app/main/default/pages/NewAndEditUserFaultInfo.page
New file
@@ -0,0 +1,579 @@
<apex:page standardController="User_FaultInfo__c" extensions="NewAndEditUserFaultInfoController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <script src="../../soap/ajax/53.0/connection.js" type="text/javascript"></script>
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <style>
        .disabledbutton {
            pointer-events: none;
            opacity: 0.4;
        }
    </style>
    <script>
        var config = {};
        config = {
            SobjectName : "{!SobjectName}",
            ApiPrefix:"{!ApiPrefix}",
            SaveAndNew:false,
            AWSToSobjectMap:{!AWSToSobjectMapJson},
            AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
            AWSToSobjectNonEncryptedMapKeySet:{!AWSToSobjectNonEncryptedMapKeySet},
            AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson},
            SobjectToAWSModel:function (sobjJson) {
                let leadPayloadList = [];
                let leadPIData = {};
                for(let f in config.AWSToSobjectMap){
                    if(sobjJson.hasOwnProperty(config.AWSToSobjectMap[f])){
                        leadPIData[f] = sobjJson[config.AWSToSobjectMap[f]]
                    }
                    else{
                        console.log(config.AWSToSobjectMap[f] + 'is not in sobjJson');
                    }
                }
                leadPIData.sfRecordId = '';
                console.log('Sobject PI Data:' + leadPIData);
                leadPayloadList.push(leadPIData);
                console.log(JSON.stringify(leadPayloadList));
                return JSON.stringify(leadPayloadList);
            },
            insertOrUpdateBack:function(payloadJson, r, isNewMode){
                for(let f in config.AWSToSobjectMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                for(let f in config.AWSToSobjectEncryptedMap){
                    if(r.object[0].hasOwnProperty(f)){
                        payloadJson[config.AWSToSobjectEncryptedMap[f]] = r.object[0][f];
                    }
                    else{
                        console.log(f + 'is not in r.object[0]');
                    }
                }
                //payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                if (isNewMode) {
                    payloadJson.AWS_Data_Id__c = r.object[0].dataId;
                } else {
                    payloadJson.AWS_Data_Id__c = '{!AWSDataId}';
                }
                return payloadJson;
            },
            queryBack:function (data) {
                console.log('data = ' + data);
                if(data.object){
                    for(let f of config.AWSToSobjectNonEncryptedMapKeySet){
                        let ele = document.getElementById(api_id_map[config.AWSToSobjectNonEncryptedMap[f]])
                        if(data.object.hasOwnProperty(f) && ele){
                            // 多选特殊处理
                            if(ele.type == 'select-multiple'){
                               //let me = GetEleByClass(config.ApiPrefix+'_'+field_api_name);
                                if(ele && data.object[f]){
                                    let arr = data.object[f].split(';');
                                    // 给隐藏的select赋值
                                    for(let op of ele.options){
                                        op.selected = arr.indexOf(op.value)>-1;
                                    }
                                    // 利用按钮给显示的select赋值
                                    let ra = document.getElementById(ele.id + '_right_arrow');
                                    if(ra){
                                        ra.click();
                                    }
                                }
                            }else{
                                ele.value = data.object[f];
                            }
                            if(ele.type.indexOf("select")>-1 && ele.value){
                                jQuery(ele).change()
                            }
                        }
                        else{
                            console.log(f + 'is not in data.object');
                        }
                    }
                }
                else{
                    console.log('data.object = ' + data.object);
                }
                // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                // document.querySelector("[data-id='Phone']").value = data.object.phone;
                // document.querySelector("[data-id='Email']").value = data.object.email;
            },
            updateMethod:"NewAndEditUserFaultInfoController.saveUserFaultInfo",
            insertMethod:"NewAndEditUserFaultInfoController.saveUserFaultInfo"
        }
        AWSService.sfSessionId = '{!GETSESSIONID()}';
        var staticResources = JSON.parse('{!staticResource}');
        var requiredFieldAPIList = JSON.parse('{!requiredFieldAPIListStr}');
        var fieldAPIToLabelMap = JSON.parse('{!fieldAPIToLabelMapStr}');
        var staticResourcesContact = JSON.parse('{!staticResourceContact}');
        console.log('{!staticResource}');
        var VLookUpFields = {! VLookUpFieldsJson};
        console.log('Vlookupfields:'+VLookUpFields);
        function ProcessPI(sobjJson, payloadForNewPI) {
            blockme();
            if ({!isNewMode}) {
                NewPIToAWS(sobjJson, payloadForNewPI)
            }else {
                UpdatePIToAWS(sobjJson, payloadForNewPI)
            }
        }
        var GetEleByClass = function(class_name){
            let eles = document.getElementsByClassName(class_name);
            if(eles.length > 0) return eles[0];
            return null;
        }
        var GetEleApiName = function(ele){
            for(let c of ele.classList){
                if(c.indexOf(config.ApiPrefix+'_')>-1){
                    return c.replace(config.ApiPrefix+'_','');
                }
            }
            return '';
        }
        function IsFormTag(tag_name){
            return ['input','select','textarea','div'].indexOf(tag_name.toLowerCase())>-1;
        }
        function IsFormElement(e){
            return IsFormTag(e.tagName);
        }
        function getPIPayload(sobjJson) {
            return config.SobjectToAWSModel(sobjJson);
        }
        function validateFieldValueFormate() {
            let error_msg = '';
            let textEmail = "[data-id='Email']";
            let textPhone = "[data-id='UFPhone__c']";
            //Email
            let email = document.querySelector(textEmail);
            if(email && !/^[\w-]{3,12}@[\da-zA-Z]{2,16}\.[a-zA-Z]+$/.test(email.value)){
                error_msg += ';邮件格式错误';
            }
            let phone = document.querySelector(textPhone);
            if(phone && !/^1[3|5|8|7][0-9]\d{4,8}$/.test(phone.value)){
                error_msg += ';电话号码错误';
            }
            for(let e of document.getElementsByTagName('select')){
                for(let op of e.options){
                    if(op.value == "*****" && op.selected){
                        error_msg += ';下拉框不能主动选择密文选项';
                    }
                }
            }
            if(error_msg.length>0 && error_msg[0]== ';'){
                error_msg = error_msg.substring(1);
            }
            return error_msg;
        }
        function getSobjectInformation() {
            //api_id_map
//let nodelist = document.getElementsByClassName(config.ApiPrefix);
            let result = {}
            for (let index in api_id_map) {
                let ele = document.getElementById(api_id_map[index]);
                let field_api_name = index;
                let tag_name = ele.tagName.toLowerCase();
                if(!IsFormTag(tag_name)){
                    console.log('tag_name='+tag_name+',field_api_name'+field_api_name+' is not a form element');
                    continue;
                }
                if (VLookUpFields.indexOf(field_api_name)>=0) {
                    console.log(ele.id.indexOf('lkwgt'));
                    if (ele.id.indexOf('lkwgt') == -1) {
                        if(field_api_name == 'ASSIGNED_TO__c'){
                            ele.id = ele.id.substring(-1,ele.id.length-4);
                        }
                        let vlookUpNodeId = ele.id + '_lkid';
                        let vlook_ele = document.getElementById(vlookUpNodeId);
                        let v = '';
                        if(vlook_ele){
                            v = vlook_ele.value;
                        }else{
                            v = ele.value;
                        }
                        if(v && v != "000000000000000"){
                            result[field_api_name] = v;
                        }
                    }
                } else if (ele.type == 'checkbox') {
                    result[field_api_name] = ele.checked;
                } else if (ele.type == 'select-multiple') {
                    //field_api_name
                    let multiple = field_api_name;
                    let targets = GetEleByClass(config.ApiPrefix+'_'+field_api_name).parentNode.children[1].children[0].children[1].children[2].children[0].innerText;
                    targets = targets.replace(/\n/g, ";");
                    console.log('targets = ' + targets);
                    result[field_api_name] = targets;
                } else {
                    result[field_api_name] = ele.value;
                }
            }
            return result;
        }
        function QuerySobjectFromAWS() {
            AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
        }
        function queryBack(data) {
            console.log('data = ' + data);
            config.queryBack(data);
            unblockUI();
        };
        function insertOrUpdateBack(payloadJson, result, isNewMode) {
            console.log(result);
            let r = result;
            console.log('Result from AWS' + r);
            console.log('payloadJson=' + payloadJson);
            return config.insertOrUpdateBack(payloadJson, r, isNewMode);
        }
        function redirectCallBack(sfId,errorMsg) {
            unblockUI();
            if(errorMsg){
                alertErrorMessage(errorMsg);
            }
            else{
                if(config.SaveAndNew){
                    window.open('{! SaveAndNewButtonUrl }','_self');
                }else{
                    window.open('/' + sfId, '_self');
                }
            }
        }
        function UpdatePIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.updateMethod;
            let obj = JSON.parse(payloadForNewPI);
            obj[0].dataId = '{!AWSDataId}';
            let payloadForNewPIJson = JSON.stringify(obj);
            AWSService.update(staticResources.updateUrl, sobjJson, payloadForNewPIJson, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, false, insertOrUpdateBack,redirectCallBack);
        }
        function NewPIToAWS(sobjJson, payloadForNewPI) {
            let controllerSaveMethod = config.insertMethod;
            AWSService.insert(staticResources.newUrl, sobjJson, payloadForNewPI, controllerSaveMethod, staticResources.token, staticResources.transactionUrl, true, insertOrUpdateBack,redirectCallBack);
        }
        function checkRequiredFieldMsg(formData) {
            let blankRequiredFields = '';
            for(i = 0;i<requiredFieldAPIList.length;i++){
                if(formData[requiredFieldAPIList[i]]){
                    continue;
                }else{
                    if(blankRequiredFields == ''){
                        blankRequiredFields =blankRequiredFields + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }else{
                        blankRequiredFields =blankRequiredFields+',' + fieldAPIToLabelMap[requiredFieldAPIList[i]];
                    }
                }
            }
            return blankRequiredFields;
        }
        function saveSobjectProcess(save_and_new) {
            if(save_and_new){
                config.SaveAndNew = true;
            }
            hiddenErrorMsgNode();
            //1. Get Sobject Information from Form
            let sobjJson = getSobjectInformation();
            //2. Validate the Sobject field value formate, for example the email formate or phone formate
            let validationResultMessage = validateFieldValueFormate();
            console.log(validationResultMessage);
            if (validationResultMessage) {
                //Popup error message.  - To Do After POC
                alertErrorMessage(validationResultMessage);
                return
            }
            // Check Required Field
            let checkRequiredFieldMsgResult = checkRequiredFieldMsg(sobjJson);
            if (checkRequiredFieldMsgResult) {
                alertErrorMessage('requiredErrorMsg' + checkRequiredFieldMsgResult);
                return
            }
            // //3. Prepare the payload for New PI API To AWS - To Do
            let payloadForNewPI = getPIPayload(sobjJson);
            // //4. Get Authentication Information for AWS
            // loadAWSAuthentication();
            // //5. User_FaultInfo__c to AWS
            ProcessPI(sobjJson, payloadForNewPI);
            // awsToken = TestToken;
            // NewPIToAWS(sobjJson,awsToken, payloadForNewPI)
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function hiddenErrorMsgNode() {
            let errorMsgNode = document.getElementById("page:form:block:msgContent");
            errorMsgNode.innerText = '';
            errorMsgNode.className = '';
        }
        //替换vlookup
        var newSearchContactWindow = null;
        var closeField = '';
        function replaceSearchContactLookup() {
            if (!{!isNewMode}) {
                //1. Query Contact from AWS by AWSDataId
                queryContactName()
            }
            if(document.querySelector("[data-id='CONTACT__c']") != null){
                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'CONTACT__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='CONTACT__c']").parentNode;
                document.querySelector("[data-id='CONTACT__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='CONTACT__c']").parentNode.children[2]);
            }
            if(document.querySelector("[data-id='UFContact__c']") != null){
                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'page:form:contactId\',\'UFContact__c\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.querySelector("[data-id='UFContact__c']").parentNode;
                document.querySelector("[data-id='UFContact__c']").removeAttribute("onchange");
                parentNode.replaceChild(lookUpNode, document.querySelector("[data-id='UFContact__c']").parentNode.children[2]);
            }
        }
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        function queryContactName() {
            if(document.querySelector("[data-id='CONTACT__c']") != null){
                queryContactNameFetch('CONTACT__c');
                // let sfId = document.getElementById(document.querySelector("[data-id='CONTACT__c']").id + '_lkid').value;
                // if(sfId != '000000000000000'){
                //     let dataId = contactsInfo[sfId];
                //     let queryContactBack = function(data){
                //         //To Do later
                //         console.log('ContactData = ' + data.object);
                //         document.querySelector("[data-id='CONTACT__c']").value = data.object.lastName;
                //     }
                //     AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
                // }
            }
            if(document.querySelector("[data-id='UFContact__c']") != null){
                queryContactNameFetch('UFContact__c');
            }
        }
        function queryContactNameFetch(filedId){
            let contactsInfo = JSON.parse('{!LookUpOverrideFieldsMapJson}');
            let sfId = document.getElementById(document.querySelector("[data-id='"+filedId+"']").id + '_lkid').value;
            if(sfId != '000000000000000'){
                let dataId = contactsInfo[sfId];
                let queryContactBack = function(data){
                    //To Do later
                    console.log('ContactData = ' + data.object);
                    document.querySelector("[data-id='"+filedId+"']").value = data.object.lastName;
                }
                AWSService.query(staticResourcesContact.queryUrl, dataId, queryContactBack, staticResources.token);
            }
        }
        //自定义lookup查询
        function searchContact(contactNodeId,field){
            closeField = field;
            let accountValue = "";
            let baseUrl = "/apex/SearchContactPage";
            let suffixUrl = "";
            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
            if (field = 'CONTACT__c') {
                if (document.querySelector("[data-id='COMPANY__c']")) {
                    let accountNodeId = document.querySelector("[data-id='COMPANY__c']").id + '_lkid';
                    accountValue = document.getElementById(accountNodeId).value;
                }
                console.log('COMPANY__c accountValue ' + accountValue);
                if(accountValue !='000000000000000'){
                    suffixUrl = "?contactId="+contactNodeId+"&accountId="+accountValue;
                    newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                    if (window.focus) {
                        newSearchContactWindow.focus();
                    }
                    return false;
                } else {
                    alertErrorMessage('请输入COMPANY !');
                }
            } else {
                suffixUrl = "?contactId="+contactNodeId;
                newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
                if (window.focus) {
                    newSearchContactWindow.focus();
                }
                return false;
            }
        }
        function closePopupWindow() {
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('page:form:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            let contactNodeId = document.querySelector("[data-id="+closeField+"]").id + '_lkid';
            document.getElementById(contactNodeId).value = contactInfo.ContactId;
            document.querySelector("[data-id="+closeField+"]").value = contactInfo.Name;
        }
    </script>
    <div class="bPageTitle">
        <div class="ptBody">
            <div class="content">
                <img src="/img/s.gif" alt="{! SobjectLabel}" class="pageTitleIcon" title="{! SobjectLabel}" />
                <h1 class="pageType">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>
                    <span class="titleSeparatingColon">:</span>
                </h1>
                <h2 class="pageDescription"> <apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText>{! SobjectLabel}</h2>
                <div class="blank">&nbsp;</div>
            </div>
            <div class="links">
                <a href="javascript:openPopupFocusEscapePounds(%27https://help.salesforce.com/apex/htdoor?loc=help&amp;target={!sobjectTypeValue}s_edit.htm&amp;section={!sobjectTypeValue}s&amp;language=zh_CN&amp;release=234.18.8&amp;instance=CS117&amp;showSplash=true%27, %27Help%27, 700, 600, %27width=700,height=600,resizable=yes,toolbar=yes,status=no,scrollbars=yes,menubar=yes,directories=no,location=no,dependant=no%27, false, false);"
                    title="此页面的帮助 (新窗口)">
                    <span class="helpLink">此页面的帮助</span>
                    <img src="/img/s.gif" alt="" class="helpIcon" />
                </a>
            </div>
        </div>
        <div class="ptBreadcrumb"></div>
    </div>
    <apex:form id="form">
        <apex:inputHidden value="{!contactId}" id="contactId"/>
        <apex:pageblock id="block">
            <div class="pbHeader">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />
                                <h2 class="mainTitle">{! SobjectLabel}<apex:outputText rendered="{!isNewMode}">{!$Label.New}</apex:outputText><apex:outputText rendered="{!not(isNewMode)}">{!$Label.Edit}</apex:outputText></h2>
                            </td>
                            <td class="pbButton" id="topButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess(1)" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <!-- Error Msg-->
            <div style="text-align: center;">
                <apex:outputPanel id="errorMsg">
                    <apex:pageMessages id="msgContent" escape="false" />
                </apex:outputPanel>
            </div>
            <!-- Iterate the layoutSections, which is a list of sections -->
            <apex:repeat value="{!layoutSections}" var="layoutSection">
                <apex:pageBlockSection title="{!layoutSection.name}" collapsible="{!layoutSection.allowCollapse}" columns="{!layoutSection.columns}">
                    <!--Each section has layoutFields, let's iterate them as well-->
                    <apex:repeat value="{!layoutSection.layoutFields}" var="layoutField">
                        <apex:inputField styleClass="{!ApiPrefix} {!ApiPrefix}_{!layoutField.fieldAPI}" html-data-id="{!layoutField.fieldAPI}" value="{!User_FaultInfo__c[layoutField.fieldAPI]}" rendered="{!not(layoutField.isPlaceHOlder)}"
                                         required="{!layoutField.isRequired}" />
                        <apex:pageblocksectionitem rendered="{!layoutField.isPlaceHolder}">
                        </apex:pageblocksectionitem>
                    </apex:repeat>
                </apex:pageBlockSection>
            </apex:repeat>
            <script>
            var init_nodes = document.getElementsByClassName("PIBackApi");
            var api_id_map={};
            for(let e of init_nodes){
                if(IsFormElement(e)){
                     api_id_map[GetEleApiName(e)] = e.id;
                }
            }
            console.log(api_id_map);
            sfdcPage.appendToOnloadQueue(function () {
                //1. Set Last Name label
                //document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[2].children[0].innerText = '姓名';
                //2. Query AWS Data by dataId
                console.log('Mode for Sobject Page:' + {!isNewMode});
                if (!{!isNewMode}) {
                    blockme();
                    QuerySobjectFromAWS();
                }
                //Replace Vlookup Field
                replaceSearchContactLookup();
                //3. Set Readonly Attribute
                document.querySelectorAll("[data-id='OwnerId']")[0].classList.add("disabledbutton");
                document.querySelectorAll("[data-id='OwnerId']")[1].classList.add("disabledbutton");
            });
            </script>
            <div class="pbBottomButtons">
                <table cellspacing="0" cellpadding="0" border="0">
                    <tbody>
                        <tr>
                            <td class="pbTitle">
                                <img src="/img/s.gif" alt="" class="minWidth" title="" width="1" height="1" />&nbsp;</td>
                            <td class="pbButtonb" id="bottomButtonRow">
                                <input class="btn" type="Button" value="{!$Label.Save}" onclick="saveSobjectProcess()" />
                                <input class="btn" type="Button" value="{!$Label.SaveAndNew}" onclick="saveSobjectProcess()" />
                                <apex:commandButton action="{!cancel}" value="{!$Label.Cancel}" />
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/NewAndEditUserFaultInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>NewAndEditUserFaultInfo</label>
</ApexPage>
force-app/main/default/pages/NewOpportunity.page
@@ -1,12 +1,58 @@
<apex:page id="Page" Controller="NewOpportunityController" sidebar="true" showHeader="true" action="{!init}">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var staticResource = JSON.parse('{!staticResource}');
        var txId = '';
        var DealerSalesStaffNameId = 'Page:mainForm:idSearchSetProduct:j_id53:j_id56:opp_DealerSalesStaffName';
        var DealerServiceId = 'Page:mainForm:idSearchSetProduct:j_id53:j_id62:opp_DealerService';
        var opportunityAWSDataId = 'Page:mainForm:idSearchSetProduct:j_id53:opportunityAWSDataId';
        function getPIData(){
            let opportunityPayloadList = [];
            let opportunityPIData = new Object();
            opportunityPIData.dealerSalesStaffName = document.getElementById(DealerSalesStaffNameId).value
            opportunityPIData.dealerService = document.getElementById(DealerServiceId).value
            opportunityPayloadList.push(opportunityPIData);
            return JSON.stringify(opportunityPayloadList);
        }
    function saveJs() {
        blockme();
        saveBtn();
        new Promise(function(resolve,reject){
            //加密
            let queryPostBack = function(data){
                document.getElementById(DealerSalesStaffNameId).value = data.object[0].dealerSalesStaffName;
                document.getElementById(DealerServiceId).value = data.object[0].dealerService;
                document.getElementById(opportunityAWSDataId).value = data.object[0].dataId;
                txId = data.txId;
                resolve('success');
            };
            AWSService.post(staticResource.newUrl,getPIData(),queryPostBack,staticResource.token);
        }).then(function(data){
            saveBtn();
            Trans();
        })
    }
    //aws 确认
    function Trans(){
        let b = HasError();
        if(b){
            //清空代理商销售担当者名
            document.getElementById(DealerSalesStaffNameId).value=''
            document.getElementById(DealerServiceId).value=''
        }
        AWSService.post(staticResource.transactionUrl, JSON.stringify({
                "txId":txId,
                "isSuccess":b ? 0 : 1
            }), function(result){
                console.log('Trans result = '+ JSON.stringify(result));
            }, staticResource.token);
    }
    function HasError(){
        let e = document.getElementById("Page:mainForm:message");
        return e.children[0]!=null;
    }
    function saveYesJs() {
@@ -154,6 +200,7 @@
                    <apex:outputLabel value="代理商服务担当者名" for="opp_DealerService"/>
                    <apex:inputField value="{!opp.DealerService__c}" id="opp_DealerService"/>
                </apex:pageBlockSectionItem>
                <apex:inputHidden id="opportunityAWSDataId" value="{!opp.AWS_Data_Id__c}"/>
            </apex:pageBlockSection>
            <apex:pageBlockSection title="竞争者信息" columns="2">
@@ -335,6 +382,7 @@
                    <apex:outputLabel value="代理商服务担当者名." for="opp_DealerService"/>
                    <apex:inputField value="{!opp.Dealer_Service_D__c}" id="opp_DealerService"/>
                </apex:pageBlockSectionItem>
                <apex:inputHidden id="opportunityAWSDataId" value="{!opp.AWS_Data_Id__c}"/>
            </apex:pageBlockSection>
            <apex:pageBlockSection title="竞争者信息" columns="2">
force-app/main/default/pages/NewReplacementOpportunity.page
@@ -1,12 +1,54 @@
<apex:page id="Page" Controller="NewReplacementOpportunityController" sidebar="true" showHeader="true" action="{!init}">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <apex:stylesheet value="{!URLFOR($Resource.blockUIcss)}"/>
    <apex:includeScript value="{!URLFOR($Resource.jquery183minjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.PleaseWaitDialog)}"/>
    <script>
        var staticResource = JSON.parse('{!staticResource}');
        var txId = '';
        function getPIData(){
            let opportunityPayloadList = [];
            let opportunityPIData = new Object();
            opportunityPIData.dealerSalesStaffName = document.getElementById('Page:mainForm:idSearchSetProduct:j_id35:j_id38:opp_DealerSalesStaffName').value
            opportunityPayloadList.push(opportunityPIData);
            return JSON.stringify(opportunityPayloadList);
        }
        function saveJs() {
            blockme();
            saveBtn();
            new Promise(function(resolve,reject){
                //加密
                let queryPostBack = function(data){
                    document.getElementById('Page:mainForm:idSearchSetProduct:j_id35:j_id38:opp_DealerSalesStaffName').value = data.object[0].dealerSalesStaffName;
                    document.getElementById('Page:mainForm:idSearchSetProduct:j_id35:opportunityAWSDataId').value = data.object[0].dataId;
                    txId = data.txId;
                    resolve('success');
                };
                AWSService.post(staticResource.newUrl,getPIData(),queryPostBack,staticResource.token);
            }).then(function(data){
                saveBtn();
                Trans();
            })
        }
        //aws 确认
        function Trans(){
            let b = HasError();
            if(b){
                //清空代理商销售担当者名
                document.getElementById('Page:mainForm:idSearchSetProduct:j_id35:j_id38:opp_DealerSalesStaffName').value=''
            }
            AWSService.post(staticResource.transactionUrl, JSON.stringify({
                    "txId":txId,
                    "isSuccess":b ? 0 : 1
                }), function(result){
                    console.log('Trans result = '+ JSON.stringify(result));
                }, staticResource.token);
        }
        function HasError(){
            let e = document.getElementById("Page:mainForm:message");
            return e.children[0]!=null;
        }
        function saveYesJs() {
@@ -30,7 +72,7 @@
    </script>
    <apex:form id="mainForm">
        <apex:actionFunction action="{!saveBtn}" name="saveBtn" reRender="mainForm,message" oncomplete="unblockUI();"/>
        <apex:actionFunction action="{!saveBtn}" name="saveBtn" reRender="mainForm,message" oncomplete="Trans();unblockUI();"/>
        <apex:actionFunction action="{!saveBtnYes}" name="saveBtnYes" reRender="mainForm,message" oncomplete="unblockUI();"/>
        <apex:actionFunction action="{!saveBtnNo}" name="saveBtnNo" reRender="mainForm,message" oncomplete="unblockUI();"/>
@@ -99,6 +141,7 @@
                    <apex:outputLabel value="代理商销售担当者名" for="opp_DealerSalesStaffName"/>
                    <apex:inputField value="{!opp.DealerSalesStaffName__c}" id="opp_DealerSalesStaffName" required="true"/>
                </apex:pageBlockSectionItem>
                <apex:inputHidden id="opportunityAWSDataId" value="{!opp.AWS_Data_Id__c}"/>
            </apex:pageBlockSection>
        </apex:pageBlock>
force-app/main/default/pages/SearchContactPage.page
New file
@@ -0,0 +1,189 @@
<apex:page controller="SearchContactController" showHeader="false" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <head>
    </head>
    <style>
        /* 1. 定义表单样式 To Do Later*/
        table {
            border-collapse: collapse;
            border-spacing: 0;
            width: 98%;
            margin-left: 5px;
        }
    </style>
    <body id="body" class="lookupTab">
        <script type="text/javascript">
            var staticResources = JSON.parse('{!staticResource}');
            var contactAWSIds = JSON.parse('{!contactAWSIds}');
            var contactsInfo = JSON.parse('{!contactsInfo}');
            var searchContactName = '';
            queryLeadFromAWS();
            function searchAWSContact(){
                console.log('Search process!');
                //1. reset table;
                resetTable();
                //2. get contact name value
                searchContactName = document.getElementById('page:form:lksrch').value;
                queryLeadFromAWS();
            }
            function resetTable(){
                let queryResult = document.getElementById('QueryResult');
                let table = document.getElementById('table');
                if(table){
                    queryResult.removeChild(table);
                }
            }
            function preparePayloadForSearchContact(){
                let searchPayload = new Object();
                searchPayload.dataIds = contactAWSIds;
                searchPayload.contactName = searchContactName;
                return JSON.stringify(searchPayload);
            }
            function queryLeadFromAWS() {
                //1. Prepare the payload for contact search
                let requestSearchPayload = preparePayloadForSearchContact();
                console.log('request payload body:'+requestSearchPayload);
                //2. Invoke AWS Service
                fetch(staticResources.searchUrl, {
                    method: 'POST',
                    body: requestSearchPayload,
                    headers: {
                        'Content-Type': 'application/json',
                        'pi-token': staticResources.token
                    }
                }).then((data) => {
                    return data.json();
                }).then((result) => {
                    if(result.object&&result.object.length>0){
                        initContactTable(result);
                    }
                })
            }
            function redirectToParentPage(obj,Phone,awsDataId) {
                var winMain = window.opener;
                if (null == winMain) {
                    winMain = window.parent.opener;
                }
                console.log('obj = ' + obj)
                let value = obj.currentTarget.innerText;
                let contactInfo = new Object();
                contactInfo.Name = obj.currentTarget.innerText;
                contactInfo.ContactId = obj.currentTarget.id;
                contactInfo.Phone = Phone;
                contactInfo.awsDataId = awsDataId;
                var selectedContactNode = winMain.document.getElementById('{!JSENCODE($CurrentPage.parameters.contactId)}');
                selectedContactNode.value = JSON.stringify(contactInfo);
                closeWindow();
            }
            function closeWindow() {
                var winMain = window.opener;
                if (null == winMain) {
                    winMain = window.parent.opener;
                }
                winMain.closePopupWindow();
                window.close();
            }
            function refreshTable(cols,contactInfoList){
                let myTableDiv = document.getElementById("QueryResult");
                let table = document.createElement('TABLE');
                table.border = '1';
                table.id = 'table'
                let tableBody = document.createElement('TBODY');
                table.appendChild(tableBody);
                let headerTR = document.createElement('TR');
                tableBody.appendChild(headerTR);
                for (let i = 0; i < cols.length; i++) {
                    let td = document.createElement('TH');
                    td.width = '75';
                    td.appendChild(document.createTextNode(cols[i]));
                    headerTR.appendChild(td);
                }
                //3. Init the AWS data
                for (let i = 0; i < contactInfoList.length; i++) {
                    let tr = document.createElement('TR');
                    tableBody.appendChild(tr);
                    let contactInfoTemp = contactInfoList[i]
                    for (let j = 0; j < cols.length; j++) {
                        let td = document.createElement('TD');
                        td.width = '75';
                        if(j == 0 && contactsInfo[contactInfoTemp.AWSDataId]){
                            td.id = contactsInfo[contactInfoTemp.AWSDataId].Id;
                        }
                        td.appendChild(document.createTextNode(contactInfoTemp[cols[j]]!=null?contactInfoTemp[cols[j]]:''));
                        if (cols[j] == 'Name') {
                            td.addEventListener("click", function (obj) {
                                console.log('contactInfoList[i] = ' + contactInfoList[i])
                                redirectToParentPage(obj,contactInfoList[i].Phone,contactInfoList[i].AWSDataId);
                            });
                        }
                        tr.appendChild(td);
                    }
                }
                myTableDiv.appendChild(table);
            }
            function initContactTable(data) {
                let cols = ['Name', 'Email', 'Phone'];
                let contactInfoList = [];
                let awsDataIds = [];
                for(var i=0;i<data.object.length;i++){
                    if(data.object[i].dataId){
                        let contactInfo = new Object();
                        contactInfo.Name = data.object[i].lastName;
                        contactInfo.Email = data.object[i].email;
                        contactInfo.Phone = data.object[i].phone;
                        contactInfo.AWSDataId = data.object[i].dataId;
                        awsDataIds.push(contactInfo.AWSDataId);
                        contactInfo.sfRecordId = '';
                        contactInfoList.push(contactInfo);
                    }
                }
                let AWSIdToSFIdMapValue = {};
                console.log(awsDataIds);
                //Invoke SF BackEnd
                Visualforce.remoting.Manager.invokeAction(
                    '{!$RemoteAction.SearchContactController.searchContacts}',
                    JSON.stringify(awsDataIds),
                    function (result, event) {
                        if(event.status){
                            if(result.status = 'success'){
                                contactsInfo = JSON.parse(result.message.replace(/(&quot\;)/g,"\""));
                                refreshTable(cols,contactInfoList);
                            }else{
                                console.log('No result');
                            }
                        }
                    },
                    { escape: true }
                );
            }
        </script>
        <apex:form id="form">
            <!-- Search Filter-->
            <div class="lookup">
                <div class="bPageTitle">
                    <div class="ptBody secondaryPalette">
                        <div class="content">
                            <img src="/img/s.gif" alt="" class="pageTitleIcon" title="" />
                            <h1>Lookup</h1>
                        </div>
                    </div>
                </div>
                <div class="pBody">
                    <label class="assistiveText" for="lksrch">Search</label>
                    <apex:inputText id="lksrch" html-placeholder="{!PIPL_Search_Contact_Label}" value="{!searchKeyWord}" />
                    <input value=" Go! " type="Button"  onclick="searchAWSContact()" styleClass="btn" />
                    <div class="bDescription">You can use "*" as a wildcard next to other characters to improve your search results.
                    </div>
                </div>
            </div>
            <div id="QueryResult">
            </div>
        </apex:form>
    </body>
</apex:page>
force-app/main/default/pages/SearchContactPage.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>SearchContactPage</label>
</ApexPage>
force-app/main/default/pages/TSRepair.page
@@ -8,6 +8,7 @@
    <apex:includeScript value="{!URLFOR($Resource.jquerysuggestjs)}"/>
    <apex:includeScript value="{!URLFOR($Resource.connection20)}"/>
    <apex:includeScript value="{!URLFOR($Resource.apex20)}"/>
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no"/>
    <style type="text/css"> 
        /*.sfdcBody {position: absolute;
@@ -103,6 +104,11 @@
    <!-- JS 方法 -->
    <script>
        var j$ = jQuery.noConflict();
        var closeField = '';
        var closePhone = '';
        var newSearchContactWindow = null;
        var staticResourceContact = JSON.parse('{!staticResourceContact}')
        j$(document).ready(function() {
                var status = '{!tsr.TSReportStatus__c}';
@@ -344,16 +350,137 @@
        }
        //20220310 zhj PIPL start
        function isError(){
            let h = HasError()
            if(h){
                unblockUI();
            }
        }
        function HasError(){
            // if (IsAddmessage) {
            //     return true;
            // }
            let e = document.getElementById("allPage:allForm:message");
            if (!e) {
                return false;
            }
            let divs = j$(e).find("div.message");
            for (let i = 0; i < divs.length; i++) {
                for (let j = 0; j < divs[i].classList.length; j++) {
                    for(let cls of divs[i].classList){
                        if (cls.indexOf('error')>-1) {
                            return true;
                        }
                    }
                }
            }
            return false;
        }
        function alertErrorMessage(errorMsg) {
            let errorMsgNode = document.getElementById("allPage:allForm:message");
            errorMsgNode.innerText = errorMsg;
            errorMsgNode.className = 'pbError';
        }
        function htmlToElement(html) {
            var template = document.createElement('template');
            html = html.trim(); // Never return a text node of whitespace as the result
            template.innerHTML = html;
            return template.content.firstChild;
        }
        var contactIdValue = '';
        function searchContact(contactNodeId,field1,field2,field3){
            closeField = field1;
            closePhone = field2;
            contactIdValue = field3;
            let baseUrl = "/apex/SearchContactPage";
            let suffixUrl = "?contactId="+contactNodeId;
            let newSearchContactParam = 'height=600,width=800,left=100,top=100,dialogHide=true,resizable=no,scrollbars=yes,toolbar=no,status=no';
            newSearchContactWindow = window.open(baseUrl+suffixUrl, 'Popup', newSearchContactParam);
            if (window.focus) {
                newSearchContactWindow.focus();
            }
            return false;
        }
        var currentLastName = '';
        var currentPhoneId = '';
        
        function replaceSearchContactLookup() {
            blockme();
            sforce.connection.sessionId = '{!GETSESSIONID()}';
            let queryContactBack = function(data,number){
                document.getElementById(currentLastName).value = data.object.lastName;
                document.getElementById(currentPhoneId).innerText = data.object.phone;
                number++;
                if(document.getElementById('allPage:allForm:RepairInfoList:'+number+':contactIdValue') != null && document.getElementById('allPage:allForm:RepairInfoList:'+number+':contactIdValue').value != ''){
                    currentLastName = 'allPage:allForm:RepairInfoList:'+number+':Contacts__c';
                    currentPhoneId = 'allPage:allForm:RepairInfoList:'+number+':j_id91';
                    let sfId = document.getElementById('allPage:allForm:RepairInfoList:'+number+':contactIdValue').value;
                    var queryStr = 'Select Id, AWS_Data_Id__c'
                                    +' from Contact  where id = \''
                                    + sfId +'\' ';
                    var reports = sforce.connection.query(queryStr);
                    var records = reports.getArray("records");
                    var awsDataId = records[0].AWS_Data_Id__c;
                    AWSService.queryTSRepair(staticResourceContact.queryUrl, awsDataId, queryContactBack, staticResourceContact.token,number);
                }
            }
            for(var i = 0;i<3;i++){
                let contactHtmlString = '<img src="/img/s.gif" onclick="searchContact(\'allPage:allForm:contactId\',\'allPage:allForm:RepairInfoList:'+i+':Contacts__c\',\'allPage:allForm:RepairInfoList:'+i+':j_id91\',\'allPage:allForm:RepairInfoList:'+i+':contactIdValue\')" alt="Reference Document Number Lookup" class="lookupIcon"  title="Reference Document Number Lookup (New Window)"/>';
                let lookUpNode = htmlToElement(contactHtmlString);
                console.log(lookUpNode);
                let parentNode = document.getElementById('allPage:allForm:RepairInfoList:'+i+':contactIdValue').parentNode;
                parentNode.appendChild(lookUpNode);
            }
            if(document.getElementById('allPage:allForm:RepairInfoList:0:contactIdValue').value != ''){
                currentLastName = 'allPage:allForm:RepairInfoList:0:Contacts__c';
                currentPhoneId = 'allPage:allForm:RepairInfoList:0:j_id91';
                //解密
                let sfId = document.getElementById('allPage:allForm:RepairInfoList:0:contactIdValue').value;
                var queryStr = 'Select Id, AWS_Data_Id__c'
                                +' from Contact  where id = \''
                                + sfId +'\' ';
                var reports = sforce.connection.query(queryStr);
                var records = reports.getArray("records");
                var awsDataId = records[0].AWS_Data_Id__c;
                AWSService.queryTSRepair(staticResourceContact.queryUrl, awsDataId, queryContactBack, staticResourceContact.token,0);
            }
            unblockUI();
        }
        function closePopupWindow() {
            console.log('closePopupWindow()')
            if (null != newSearchContactWindow) {
                newSearchContactWindow.close();
            }
            let contactInfoStr = document.getElementById('allPage:allForm:contactId').value;
            console.log('closePopup:'+contactInfoStr);
            let contactInfo = JSON.parse(contactInfoStr);
            document.getElementById(contactIdValue).value = contactInfo.ContactId;
            document.getElementById(''+closeField).value = contactInfo.Name;
            document.getElementById(''+closePhone).value = contactInfo.Phone;
            document.getElementById(''+closePhone).innerText = contactInfo.Phone;
        }
        //20220310 zhj PIPL end
    </script>
        <apex:form id="allForm">
            <apex:inputHidden value="{!contactId}" id="contactId"/>
             <!-- 王鹏伟 点击按钮更新状态开始 -->
            <apex:actionFunction name="setStatus" action="{!setStatus}" reRender="Activities,message,Activities1" oncomplete="unblockUI();">
           
                <apex:param name="status" assignTo="{!status}" value="" />
            </apex:actionFunction>
            <!-- 王鹏伟 点击按钮更新状态结束 -->
            <apex:actionFunction name="updateServiceCategory" action="{!updateServiceCategory}" rerender="Activities" onComplete="unblockUI();">
            <apex:actionFunction name="updateServiceCategory" action="{!updateServiceCategory}" rerender="Activities" onComplete="replaceSearchContactLookup();unblockUI();">
                <apex:param name="num" assignTo="{!num}" value="" />
            </apex:actionFunction>
@@ -545,7 +672,13 @@
                                        <apex:inputField id="BusinessACustomerUnit" value="{!repairInfo.ba.BusinessAAccount__c}" />
                                    </td>
                                    <th style="text-align: center;">联系人</th>
                                    <td align="left" ><apex:inputField value="{!repairInfo.ba.BusinessAContact__c}" style="width: 80%"/></td>
                                    <td align="left" >
                                        <!-- <apex:inputField value="{!repairInfo.ba.BusinessAContact__c}" style="width: 80%"/> -->
                                        <!-- Add By zhj for PIPL 20220309 Start -->
                                        <apex:inputText value="{!contactNameValue}" id="Contacts__c" style="width: 80%"/>
                                        <apex:inputHidden id="contactIdValue" value="{!repairInfo.ba.BusinessAContact__c}"/>
                                        <!-- Add By zhj for PIPL 20220309 end -->
                                    </td>
                                    <th style="text-align: center;">联系电话</th>
                                    <td align="left" ><apex:outputField value="{!repairInfo.ba.BusinessAPhone_F__c}"/></td>
                                </tr>
@@ -998,9 +1131,14 @@
                            <br/>
                            <br/>
                        </apex:repeat>
                </apex:outputPanel>
                <script>
                    console.log('appendToOnloadQueue')
                    sfdcPage.appendToOnloadQueue(function () {
                        replaceSearchContactLookup();
                    });
                </script>
            <apex:commandButton id="test" onclick="blockme();" action="{!addBusinessActivity}" reRender="Activities" value="添加业务活动"  oncomplete="unblockUI();" disabled="{!If(tsr.TSReportStatus__c = '申请中' || tsr.TSReportStatus__c = '确认' ,true , If((tsr.TSReportStatus__c = '草案中' || tsr.TSReportStatus__c = '驳回') && onclickType != '0',true,false))}"></apex:commandButton>
            <apex:commandButton id="save" onclick="blockme();" action="{!save}" reRender="message,allPanel,allForm" value="保存" style="width: 70px;" oncomplete="unblockUI();" disabled="{!If(tsr.TSReportStatus__c = '申请中' || tsr.TSReportStatus__c = '确认',true , If((tsr.TSReportStatus__c = '草案中' || tsr.TSReportStatus__c = '驳回') && onclickType != '0',true,false))}"></apex:commandButton>
            <apex:commandButton id="save" onclick="blockme();" action="{!save}" reRender="message,allPanel,allForm" value="保存" style="width: 70px;" oncomplete="unblockUI();isError();" disabled="{!If(tsr.TSReportStatus__c = '申请中' || tsr.TSReportStatus__c = '确认',true , If((tsr.TSReportStatus__c = '草案中' || tsr.TSReportStatus__c = '驳回') && onclickType != '0',true,false))}"></apex:commandButton>
        </apex:form>
</apex:page>
force-app/main/default/pages/TestLabel.page
New file
@@ -0,0 +1,3 @@
<apex:page >
    <input class="btn" type="Button" value="test" />
</apex:page>
force-app/main/default/pages/TestLabel.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>TestLabel</label>
</ApexPage>
force-app/main/default/pages/ViewContactDecryptInfo.page
New file
@@ -0,0 +1,63 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 02-22-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Contact" extensions="NewAndEditContactController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Contact[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewContactDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewContactDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewLoanerAppDetailDecryptInfo.page
New file
@@ -0,0 +1,6 @@
<apex:page >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>
force-app/main/default/pages/ViewLoanerAppDetailDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewLoanerAppDetailDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewLoanerApplicationDecryptInfo.page
New file
@@ -0,0 +1,63 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 03-03-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="loaner_application__c" extensions="NewAndEditLoanerApplicationController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!loaner_application__c[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewLoanerApplicationDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewLoanerApplicationDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewLoanerExpressDecryptInfo.page
New file
@@ -0,0 +1,6 @@
<apex:page >
  <!-- Begin Default Content REMOVE THIS -->
  <h1>Congratulations</h1>
  This is your new Page
  <!-- End Default Content REMOVE THIS -->
</apex:page>
force-app/main/default/pages/ViewLoanerExpressDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewLoanerExpressDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewLoanerUserDecryptInfo.page
New file
@@ -0,0 +1,64 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 03-03-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="loaner_user__c" extensions="NewAndEditLoanerUserController" id="page">
  <!-- Begin Default Content REMOVE THIS -->
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!loaner_user__c[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewLoanerUserDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewLoanerUserDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewOpportunityDecryptInfo.page
New file
@@ -0,0 +1,63 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 02-23-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="Opportunity" extensions="NewAndEditOpportunityController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Opportunity[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewOpportunityDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewOpportunityDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewOrderDecryptInfo.page
New file
@@ -0,0 +1,56 @@
<apex:page standardController="Order" extensions="NewAndEditOrderController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Order[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewOrderDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewOrderDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewQuotesDecryptInfo.page
New file
@@ -0,0 +1,56 @@
<apex:page standardController="Quotes__c" extensions="NewAndEditQuotesController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!Quotes__c[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewQuotesDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewQuotesDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewRepairDecryptInfo.page
New file
@@ -0,0 +1,42 @@
<apex:page standardController="Repair__c" extensions="NewAndEditRepairController" id="page">
    <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:outputField value="{!Repair__c.Telephonen__c}" />
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                var staticResourceContact = JSON.parse('{!staticResourceContact}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResourceContact.queryUrl, '{!contactAWSDataId.AWS_Data_Id__c}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    //if(!data.object){
                    //    console.log('data.object is ' + data.object);
                    //    return;
                    //}
                    console.log('data.object.Phone is ' + JSON.stringify(data.object));
                    document.getElementById("page:form:pageBlock:pageBlockSection:j_id1").innerText = data.object.phone;
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    //document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewRepairDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewRepairDecryptInfo</label>
</ApexPage>
force-app/main/default/pages/ViewUserFaultInfoDecryptInfo.page
New file
@@ -0,0 +1,63 @@
<!--
  @description       :
  @author            : ChangeMeIn@UserSettingsUnder.SFDoc
  @group             :
  @last modified on  : 02-28-2022
  @last modified by  : ChangeMeIn@UserSettingsUnder.SFDoc
-->
<apex:page standardController="User_FaultInfo__c" extensions="NewAndEditUserFaultInfoController" id="page">
  <apex:includeScript value="{! URLFOR($Resource.AWSService, 'AWSService.js') }"/>
    <apex:form id="form">
        <apex:pageblock id="pageBlock">
            <apex:pageBlockSection showHeader="false" title="" collapsible="true" columns="2" id="pageBlockSection">
                <!--Each section has layoutFields, let's iterate them as well-->
                <apex:repeat value="{!layoutEncryptedAPIList}" var="encryptedAPI">
                    <apex:outputField html-data-id="{!encryptedAPI}" title="{!ApiPrefix}{!encryptedAPI}" value="{!User_FaultInfo__c[encryptedAPI]}" />
                </apex:repeat>
            </apex:pageBlockSection>
            <script>
                var config = {
                    SobjectName : "{!SobjectName}",
                    ApiPrefix:"{!ApiPrefix}",
                    AWSToSobjectMap:{!AWSToSobjectMapJson},
                    AWSToSobjectNonEncryptedMap:{!AWSToSobjectNonEncryptedMapJson},
                    AWSToSobjectEncryptedMap:{!AWSToSobjectEncryptedMapJson}
                };
                var staticResources = JSON.parse('{!staticResource}');
                function QuerySobjectFromAWS() {
                    AWSService.query(staticResources.queryUrl, '{!AWSDataId}', queryBack, staticResources.token);
                }
                var queryBack = function queryBack(data) {
                    if(!data.object){
                        console.log('data.object is ' + data.object);
                        return;
                    }
                    for(let f in config.AWSToSobjectNonEncryptedMap){
                        let t = "[title='"+config.ApiPrefix+config.AWSToSobjectNonEncryptedMap[f]+"']";
                        let ele = document.querySelector(t);
                        if(ele){
                            ele.title = '';
                            if(data.object.hasOwnProperty(f)){
                                ele.innerHTML = data.object[f];
                            }
                            else{
                                console.log(f + 'is not in data.object');
                            }
                        }else{
                            console.log('selector='+t+' not found');
                        }
                    }
                    // 当不能自动正确替换加密数据时需要在此处添加js,硬编码处理
                    // document.querySelector("[data-id='LastName']").value = data.object.lastName;
                };
                sfdcPage.appendToOnloadQueue(function () {
                    console.log('sfdcPage.appendToOnloadQueue')
                    // document.querySelector("[data-id='LastName']").parentNode.parentNode.parentNode.children[0].innerText = '姓名'
                    QuerySobjectFromAWS();
                });
            </script>
        </apex:pageblock>
    </apex:form>
</apex:page>
force-app/main/default/pages/ViewUserFaultInfoDecryptInfo.page-meta.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexPage xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <availableInTouch>false</availableInTouch>
    <confirmationTokenRequired>false</confirmationTokenRequired>
    <label>ViewUserFaultInfoDecryptInfo</label>
</ApexPage>
force-app/main/default/staticresources/AWSService.resource-meta.xml
New file
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Public</cacheControl>
    <contentType>application/zip</contentType>
</StaticResource>
force-app/main/default/staticresources/AWSService/AWSService.js
New file
@@ -0,0 +1,222 @@
class AWSService {
    static sfSessionId = '';
    static insertModule = 'Insert AWS ';
    static updateModule = 'Update AWS ';
    static queryModule = 'Query AWS ';
    static searchModule = 'Search AWS ';
    static confirmTrans = 'Confirm Transaction To AWS';
    static successStatus = 'success';
    static failStatus = 'fail';
    static insertCalloutLog(module,url,request,response,status){
        if(this.sfSessionId){
            sforce.connection.sessionId = this.sfSessionId;
            let transLog = new sforce.SObject('Transaction_Log__c');
            transLog.AWS_Data_Id__c = '';
            transLog.Module__c = module;
            transLog.Interface_URL__c = url;
            transLog.Request__c = request;
            transLog.Response__c = response;
            transLog.Status__c = status;
            let insertLogResult = sforce.connection.create([transLog]);
            if(insertLogResult[0].getBoolean(this.successStatus)) {
                console.log('Insert Log Id: ' + insertLogResult[0].id);
                return insertLogResult[0].id;
            }else {
                console.log('Faield to insert log');
                return '';
            }
        }
    }
    //Search Contact
    static search(searchUrl,requestSearchPayload,searchBack,token) {
        fetch(searchUrl, {
            method: 'POST',
            body: requestSearchPayload,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((result) => {
            this.insertCalloutLog(this.searchModule,searchUrl,JSON.stringify(requestSearchPayload),JSON.stringify(result),this.successStatus);
            searchBack(result);
        }).catch(error => {
            this.insertCalloutLog(this.searchModule,searchUrl,JSON.stringify(requestSearchPayload),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    //query
    static query(queryURL, awsDataId, queryback, token) {
        fetch(queryURL + '?dataId=' + awsDataId, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((data) => {
            this.insertCalloutLog(this.queryModule,queryURL,queryURL + '?dataId=' + awsDataId,JSON.stringify(data),this.successStatus);
            queryback(data);
        }).catch(error => {
            this.insertCalloutLog(this.queryModule,queryURL,queryURL + '?dataId=' + awsDataId,JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    //queryTSRepair
    static queryTSRepair(queryURL, awsDataId, queryback, token,number) {
        fetch(queryURL + '?dataId=' + awsDataId, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            return data.json();
        }).then((data) => {
            this.insertCalloutLog(this.queryModule,queryURL,queryURL + '?dataId=' + awsDataId,JSON.stringify(data),this.successStatus);
            queryback(data,number);
        }).catch(error => {
            this.insertCalloutLog(this.queryModule,queryURL,queryURL + '?dataId=' + awsDataId,JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    //insert
    static insert(newURL, payloadJson, payloadForNewPI, controllerSaveMethod, token, transactionURL,isNewMode,insertOrUpdateBack,redirectCallBack) {
        console.log('Process New PI Data');
        console.log(JSON.stringify(payloadForNewPI));
        fetch(newURL, {
            method: 'POST',
            body: payloadForNewPI,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            console.log('data=' + JSON.stringify(data));
            return data.json();
        }).then((result) => {
            this.insertCalloutLog(this.insertModule,newURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            AWSService.back(result, payloadJson, transactionURL, token, controllerSaveMethod,isNewMode,insertOrUpdateBack,redirectCallBack);
        }).catch(error => {
            this.insertCalloutLog(this.insertModule,newURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    //update
    static update(updateURL, payloadJson, payloadForNewPI, controllerSaveMethod, token, transactionURL,isNewMode,insertOrUpdateBack,redirectCallBack) {
        console.log('Process New PI Data');
        console.log(JSON.stringify(payloadForNewPI));
        fetch(updateURL, {
            method: 'POST',
            body: payloadForNewPI,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            console.log('data=' + JSON.stringify(data));
            return data.json();
        }).then((result) => {
            this.insertCalloutLog(this.updateModule,updateURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            AWSService.back(result, payloadJson, transactionURL, token, controllerSaveMethod,isNewMode,insertOrUpdateBack,redirectCallBack);
        }).catch(error => {
            this.insertCalloutLog(this.updateModule,updateURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    //update
    static post(postURL, payloadForNewPI, callback, token) {
        console.log('Process New PI Data');
        console.log(JSON.stringify(payloadForNewPI));
        fetch(postURL, {
            method: 'POST',
            body: payloadForNewPI,
            headers: {
                'Content-Type': 'application/json',
                'pi-token': token
            }
        }).then((data) => {
            console.log('data=' + JSON.stringify(data));
            return data.json();
        }).then((result) => {
            this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(result),this.successStatus);
            callback(result);
        }).catch(error => {
            this.insertCalloutLog(this.insertModule,postURL,JSON.stringify(payloadForNewPI),JSON.stringify(error),this.failStatus);
            console.log(error);
        });
    }
    static sfdcBack = function sfdcBack(event, result, transId, token, transactionURL,redirectCallBack) {
        let sfId = '';
        if (event.status) {
            console.log('sf Id from SF Backend:' + JSON.stringify(result));
            if (result.status == 'success') {
                sfId = result.recordId;
                let transParameters = {
                    txId: transId,
                    sfRecordId:sfId,
                    isSuccess: 1
                };
                console.log(transParameters);
                fetch(transactionURL, {
                    method: 'POST',
                    body: JSON.stringify(transParameters),
                    headers: {
                        'Content-Type': 'application/json',
                        'pi-token': token
                    }
                }).then((result) => {
                    this.insertCalloutLog(this.confirmTrans,transactionURL,JSON.stringify(transParameters),JSON.stringify(result),this.successStatus);
                    redirectCallBack(sfId,'');
                }).catch(error => {
                    this.insertCalloutLog(this.confirmTrans,transactionURL,JSON.stringify(transParameters),JSON.stringify(error),this.failStatus);
                    console.log(error);
                });
            } else {
                let errorMsg = result.message;
                let transParameters = {
                    txId: transId,
                    sfRecordId:sfId,
                    isSuccess: 0
                };
                console.log(transParameters);
                fetch(transactionURL, {
                    method: 'POST',
                    body: JSON.stringify(transParameters),
                    headers: {
                        'Content-Type': 'application/json',
                        'pi-token': token
                    }
                }).then((result) => {
                    this.insertCalloutLog(this.confirmTrans,transactionURL,JSON.stringify(transParameters),JSON.stringify(result),this.successStatus);
                    redirectCallBack('',errorMsg);
                }).catch(error => {
                    this.insertCalloutLog(this.confirmTrans,transactionURL,JSON.stringify(transParameters),JSON.stringify(error),this.failStatus);
                    console.log(error);
                });
            }
        }
    }
    // AWSService.back(result, payloadJson, transactionURL, token, controllerSaveMethod);
    static back = function back(result, payloadJson, transactionURL, token, controllerSaveMethod,isNewMode,insertOrUpdateBack,redirectCallBack) {
        let payloadJsonStr = JSON.stringify(insertOrUpdateBack(payloadJson, result,isNewMode));
        let transId = result.txId + '';
        Visualforce.remoting.Manager.invokeAction(
            controllerSaveMethod, // example '{!$RemoteAction.NewAndEditLeadController.saveLead}'
            payloadJsonStr, transId, isNewMode,
            function (result, event) {
                AWSService.sfdcBack(event, result, transId, token, transactionURL,redirectCallBack);
            },
            { escape: true }
        );
    }
};
force-app/main/default/staticresources/html2canvas.js
New file
@@ -0,0 +1,10 @@
/*
  html2canvas 0.5.0-beta4 <http://html2canvas.hertzen.com>
  Copyright (c) 2017 Niklas von Hertzen
  2017-06-14 Custom build by Erik Koopmans, featuring latest bugfixes and features
  Released under MIT License
*/
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.html2canvas=a()}}(function(){var a;return function b(a,c,d){function e(g,h){if(!c[g]){if(!a[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};a[g][0].call(k.exports,function(b){var c=a[g][1][b];return e(c?c:b)},k,k.exports,b,a,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(b,c,d){(function(b){!function(e){function f(a){throw new RangeError(I[a])}function g(a,b){for(var c=a.length,d=[];c--;)d[c]=b(a[c]);return d}function h(a,b){var c=a.split("@"),d="";c.length>1&&(d=c[0]+"@",a=c[1]),a=a.replace(H,".");var e=a.split("."),f=g(e,b).join(".");return d+f}function i(a){for(var b,c,d=[],e=0,f=a.length;e<f;)b=a.charCodeAt(e++),b>=55296&&b<=56319&&e<f?(c=a.charCodeAt(e++),56320==(64512&c)?d.push(((1023&b)<<10)+(1023&c)+65536):(d.push(b),e--)):d.push(b);return d}function j(a){return g(a,function(a){var b="";return a>65535&&(a-=65536,b+=L(a>>>10&1023|55296),a=56320|1023&a),b+=L(a)}).join("")}function k(a){return a-48<10?a-22:a-65<26?a-65:a-97<26?a-97:x}function l(a,b){return a+22+75*(a<26)-((0!=b)<<5)}function m(a,b,c){var d=0;for(a=c?K(a/B):a>>1,a+=K(a/b);a>J*z>>1;d+=x)a=K(a/J);return K(d+(J+1)*a/(a+A))}function n(a){var b,c,d,e,g,h,i,l,n,o,p=[],q=a.length,r=0,s=D,t=C;for(c=a.lastIndexOf(E),c<0&&(c=0),d=0;d<c;++d)a.charCodeAt(d)>=128&&f("not-basic"),p.push(a.charCodeAt(d));for(e=c>0?c+1:0;e<q;){for(g=r,h=1,i=x;e>=q&&f("invalid-input"),l=k(a.charCodeAt(e++)),(l>=x||l>K((w-r)/h))&&f("overflow"),r+=l*h,n=i<=t?y:i>=t+z?z:i-t,!(l<n);i+=x)o=x-n,h>K(w/o)&&f("overflow"),h*=o;b=p.length+1,t=m(r-g,b,0==g),K(r/b)>w-s&&f("overflow"),s+=K(r/b),r%=b,p.splice(r++,0,s)}return j(p)}function o(a){var b,c,d,e,g,h,j,k,n,o,p,q,r,s,t,u=[];for(a=i(a),q=a.length,b=D,c=0,g=C,h=0;h<q;++h)p=a[h],p<128&&u.push(L(p));for(d=e=u.length,e&&u.push(E);d<q;){for(j=w,h=0;h<q;++h)p=a[h],p>=b&&p<j&&(j=p);for(r=d+1,j-b>K((w-c)/r)&&f("overflow"),c+=(j-b)*r,b=j,h=0;h<q;++h)if(p=a[h],p<b&&++c>w&&f("overflow"),p==b){for(k=c,n=x;o=n<=g?y:n>=g+z?z:n-g,!(k<o);n+=x)t=k-o,s=x-o,u.push(L(l(o+t%s,0))),k=K(t/s);u.push(L(l(k,0))),g=m(c,r,d==e),c=0,++d}++c,++b}return u.join("")}function p(a){return h(a,function(a){return F.test(a)?n(a.slice(4).toLowerCase()):a})}function q(a){return h(a,function(a){return G.test(a)?"xn--"+o(a):a})}var r="object"==typeof d&&d&&!d.nodeType&&d,s="object"==typeof c&&c&&!c.nodeType&&c,t="object"==typeof b&&b;t.global!==t&&t.window!==t&&t.self!==t||(e=t);var u,v,w=2147483647,x=36,y=1,z=26,A=38,B=700,C=72,D=128,E="-",F=/^xn--/,G=/[^\x20-\x7E]/,H=/[\x2E\u3002\uFF0E\uFF61]/g,I={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},J=x-y,K=Math.floor,L=String.fromCharCode;if(u={version:"1.4.1",ucs2:{decode:i,encode:j},decode:n,encode:o,toASCII:q,toUnicode:p},"function"==typeof a&&"object"==typeof a.amd&&a.amd)a("punycode",function(){return u});else if(r&&s)if(c.exports==r)s.exports=u;else for(v in u)u.hasOwnProperty(v)&&(r[v]=u[v]);else e.punycode=u}(this)}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],2:[function(a,b,c){function d(a,b,c){!a.defaultView||b===a.defaultView.pageXOffset&&c===a.defaultView.pageYOffset||a.defaultView.scrollTo(b,c)}function e(a,b){try{b&&(b.width=a.width,b.height=a.height,b.getContext("2d").putImageData(a.getContext("2d").getImageData(0,0,a.width,a.height),0,0))}catch(c){h("Unable to copy canvas content from",a,c)}}function f(a,b){for(var c=3===a.nodeType?document.createTextNode(a.nodeValue):a.cloneNode(!1),d=a.firstChild;d;)b!==!0&&1===d.nodeType&&"SCRIPT"===d.nodeName||c.appendChild(f(d,b)),d=d.nextSibling;return 1===a.nodeType&&(c._scrollTop=a.scrollTop,c._scrollLeft=a.scrollLeft,"CANVAS"===a.nodeName?e(a,c):"TEXTAREA"!==a.nodeName&&"SELECT"!==a.nodeName||(c.value=a.value)),c}function g(a){if(1===a.nodeType){a.scrollTop=a._scrollTop,a.scrollLeft=a._scrollLeft;for(var b=a.firstChild;b;)g(b),b=b.nextSibling}}var h=a("./log");b.exports=function(a,b,c,e,h,i,j){var k=f(a.documentElement,h.javascriptEnabled),l=b.createElement("iframe");return l.className="html2canvas-container",l.style.visibility="hidden",l.style.position="fixed",l.style.left="-10000px",l.style.top="0px",l.style.border="0",l.width=c,l.height=e,l.scrolling="no",b.body.appendChild(l),new Promise(function(b){var c=l.contentWindow.document;l.contentWindow.onload=l.onload=function(){var a=setInterval(function(){c.body.childNodes.length>0&&(g(c.documentElement),clearInterval(a),"view"===h.type&&(l.contentWindow.scrollTo(i,j),!/(iPad|iPhone|iPod)/g.test(navigator.userAgent)||l.contentWindow.scrollY===j&&l.contentWindow.scrollX===i||(c.documentElement.style.top=-j+"px",c.documentElement.style.left=-i+"px",c.documentElement.style.position="absolute")),b(l))},50)},c.open(),c.write("<!DOCTYPE html><html></html>"),d(a,i,j),c.replaceChild(c.adoptNode(k),c.documentElement),c.close()})}},{"./log":13}],3:[function(a,b,c){function d(a){this.r=0,this.g=0,this.b=0,this.a=null;this.fromArray(a)||this.namedColor(a)||this.rgb(a)||this.rgba(a)||this.hex6(a)||this.hex3(a)}d.prototype.darken=function(a){var b=1-a;return new d([Math.round(this.r*b),Math.round(this.g*b),Math.round(this.b*b),this.a])},d.prototype.isTransparent=function(){return 0===this.a},d.prototype.isBlack=function(){return 0===this.r&&0===this.g&&0===this.b},d.prototype.fromArray=function(a){return Array.isArray(a)&&(this.r=Math.min(a[0],255),this.g=Math.min(a[1],255),this.b=Math.min(a[2],255),a.length>3&&(this.a=a[3])),Array.isArray(a)};var e=/^#([a-f0-9]{3})$/i;d.prototype.hex3=function(a){var b=null;return null!==(b=a.match(e))&&(this.r=parseInt(b[1][0]+b[1][0],16),this.g=parseInt(b[1][1]+b[1][1],16),this.b=parseInt(b[1][2]+b[1][2],16)),null!==b};var f=/^#([a-f0-9]{6})$/i;d.prototype.hex6=function(a){var b=null;return null!==(b=a.match(f))&&(this.r=parseInt(b[1].substring(0,2),16),this.g=parseInt(b[1].substring(2,4),16),this.b=parseInt(b[1].substring(4,6),16)),null!==b};var g=/^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/;d.prototype.rgb=function(a){var b=null;return null!==(b=a.match(g))&&(this.r=Number(b[1]),this.g=Number(b[2]),this.b=Number(b[3])),null!==b};var h=/^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d?\.?\d+)\s*\)$/;d.prototype.rgba=function(a){var b=null;return null!==(b=a.match(h))&&(this.r=Number(b[1]),this.g=Number(b[2]),this.b=Number(b[3]),this.a=Number(b[4])),null!==b},d.prototype.toString=function(){return null!==this.a&&1!==this.a?"rgba("+[this.r,this.g,this.b,this.a].join(",")+")":"rgb("+[this.r,this.g,this.b].join(",")+")"},d.prototype.namedColor=function(a){a=a.toLowerCase();var b=i[a];if(b)this.r=b[0],this.g=b[1],this.b=b[2];else if("transparent"===a)return this.r=this.g=this.b=this.a=0,!0;return!!b},d.prototype.isColor=!0;var i={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};b.exports=d},{}],4:[function(b,c,d){function e(a,b){var c=v++;if(b=b||{},b.logging&&(p.options.logging=!0,p.options.start=Date.now()),b.async="undefined"==typeof b.async||b.async,b.allowTaint="undefined"!=typeof b.allowTaint&&b.allowTaint,b.removeContainer="undefined"==typeof b.removeContainer||b.removeContainer,b.javascriptEnabled="undefined"!=typeof b.javascriptEnabled&&b.javascriptEnabled,b.imageTimeout="undefined"==typeof b.imageTimeout?1e4:b.imageTimeout,b.renderer="function"==typeof b.renderer?b.renderer:l,b.strict=!!b.strict,"string"==typeof a){if("string"!=typeof b.proxy)return Promise.reject("Proxy must be used when rendering url");var d=null!=b.width?b.width:window.innerWidth,e=null!=b.height?b.height:window.innerHeight;return s(j(a),b.proxy,document,d,e,b).then(function(a){return g(a.contentWindow.document.documentElement,a,b,d,e)})}var h=(void 0===a?[document.documentElement]:a.length?a:[a])[0];return h.setAttribute(u+c,c),f(h.ownerDocument,b,h.ownerDocument.defaultView.innerWidth,h.ownerDocument.defaultView.innerHeight,c).then(function(a){return"function"==typeof b.onrendered&&(p("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas"),b.onrendered(a)),a})}function f(a,b,c,d,e){return r(a,a,c,d,b,a.defaultView.pageXOffset,a.defaultView.pageYOffset).then(function(f){p("Document cloned");var h=u+e,i="["+h+"='"+e+"']";a.querySelector(i).removeAttribute(h);var j=f.contentWindow,k=j.document.querySelector(i),l="function"==typeof b.onclone?Promise.resolve(b.onclone(j.document)):Promise.resolve(!0);return l.then(function(){return g(k,f,b,c,d)})})}function g(a,b,c,d,e){var f=b.contentWindow,g=new k(f.document),j=new m(c,g),l=t(a),o="view"===c.type?d:l.right+1,q="view"===c.type?e:l.bottom+1,r=new c.renderer(o,q,j,c,document),s=new n(a,r,g,j,c);return s.ready.then(function(){p("Finished rendering");var d;if("view"===c.type)d=i(r.canvas,{width:r.canvas.width,height:r.canvas.height,top:0,left:0,x:0,y:0});else if(a===f.document.body||a===f.document.documentElement||null!=c.canvas)d=r.canvas;else if(c.scale){var e={width:null!=c.width?c.width:l.width,height:null!=c.height?c.height:l.height,top:l.top,left:l.left,x:0,y:0},g={};for(var j in e)e.hasOwnProperty(j)&&(g[j]=e[j]*c.scale);d=i(r.canvas,g),d.style.width=e.width+"px",d.style.height=e.height+"px"}else d=i(r.canvas,{width:null!=c.width?c.width:l.width,height:null!=c.height?c.height:l.height,top:l.top,left:l.left,x:0,y:0});return h(b,c),d})}function h(a,b){b.removeContainer&&(a.parentNode.removeChild(a),p("Cleaned up container"))}function i(a,b){var c=document.createElement("canvas"),d=Math.min(a.width-1,Math.max(0,b.left)),e=Math.min(a.width,Math.max(1,b.left+b.width)),f=Math.min(a.height-1,Math.max(0,b.top)),g=Math.min(a.height,Math.max(1,b.top+b.height));c.width=b.width,c.height=b.height;var h=e-d,i=g-f;return p("Cropping canvas at:","left:",b.left,"top:",b.top,"width:",h,"height:",i),p("Resulting crop with width",b.width,"and height",b.height,"with x",d,"and y",f),c.getContext("2d").drawImage(a,d,f,h,i,b.x,b.y,h,i),c}function j(a){var b=document.createElement("a");return b.href=a,b.href=b.href,b}var k=b("./support"),l=b("./renderers/canvas"),m=b("./imageloader"),n=b("./nodeparser"),o=b("./nodecontainer"),p=b("./log"),q=b("./utils"),r=b("./clone"),s=b("./proxy").loadUrlDocument,t=q.getBounds,u="data-html2canvas-node",v=0;e.CanvasRenderer=l,e.NodeContainer=o,e.log=p,e.utils=q;var w="undefined"==typeof document||"function"!=typeof Object.create||"function"!=typeof document.createElement("canvas").getContext?function(){return Promise.reject("No canvas support")}:e;c.exports=w,"function"==typeof a&&a.amd&&a("html2canvas",[],function(){return w})},{"./clone":2,"./imageloader":11,"./log":13,"./nodecontainer":14,"./nodeparser":15,"./proxy":16,"./renderers/canvas":20,"./support":22,"./utils":26}],5:[function(a,b,c){function d(a){if(this.src=a,e("DummyImageContainer for",a),!this.promise||!this.image){e("Initiating DummyImageContainer"),d.prototype.image=new Image;var b=this.image;d.prototype.promise=new Promise(function(a,c){b.onload=a,b.onerror=c,b.src=f(),b.complete===!0&&a(b)})}}var e=a("./log"),f=a("./utils").smallImage;b.exports=d},{"./log":13,"./utils":26}],6:[function(a,b,c){function d(a,b){var c,d,f=document.createElement("div"),g=document.createElement("img"),h=document.createElement("span"),i="Hidden Text";f.style.visibility="hidden",f.style.fontFamily=a,f.style.fontSize=b,f.style.margin=0,f.style.padding=0,document.body.appendChild(f),g.src=e(),g.width=1,g.height=1,g.style.margin=0,g.style.padding=0,g.style.verticalAlign="baseline",h.style.fontFamily=a,h.style.fontSize=b,h.style.margin=0,h.style.padding=0,h.appendChild(document.createTextNode(i)),f.appendChild(h),f.appendChild(g),c=g.offsetTop-h.offsetTop+1,f.removeChild(h),f.appendChild(document.createTextNode(i)),f.style.lineHeight="normal",g.style.verticalAlign="super",d=g.offsetTop-f.offsetTop+1,document.body.removeChild(f),this.baseline=c,this.lineWidth=1,this.middle=d}var e=a("./utils").smallImage;b.exports=d},{"./utils":26}],7:[function(a,b,c){function d(){this.data={}}var e=a("./font");d.prototype.getMetrics=function(a,b){return void 0===this.data[a+"-"+b]&&(this.data[a+"-"+b]=new e(a,b)),this.data[a+"-"+b]},b.exports=d},{"./font":6}],8:[function(a,b,c){function d(b,c,d){this.image=null,this.src=b;var e=this,g=f(b);this.promise=(c?new Promise(function(a){"about:blank"===b.contentWindow.document.URL||null==b.contentWindow.document.documentElement?b.contentWindow.onload=b.onload=function(){a(b)}:a(b)}):this.proxyLoad(d.proxy,g,d)).then(function(b){var c=a("./core");return c(b.contentWindow.document.documentElement,{type:"view",width:b.width,height:b.height,proxy:d.proxy,javascriptEnabled:d.javascriptEnabled,removeContainer:d.removeContainer,allowTaint:d.allowTaint,imageTimeout:d.imageTimeout/2})}).then(function(a){return e.image=a})}var e=a("./utils"),f=e.getBounds,g=a("./proxy").loadUrlDocument;d.prototype.proxyLoad=function(a,b,c){var d=this.src;return g(d.src,a,d.ownerDocument,b.width,b.height,c)},b.exports=d},{"./core":4,"./proxy":16,"./utils":26}],9:[function(a,b,c){function d(a){this.src=a.value,this.colorStops=[],this.type=null,this.x0=.5,this.y0=.5,this.x1=.5,this.y1=.5,this.promise=Promise.resolve(!0)}d.TYPES={LINEAR:1,RADIAL:2},d.REGEXP_COLORSTOP=/^\s*(rgba?\(\s*\d{1,3},\s*\d{1,3},\s*\d{1,3}(?:,\s*[0-9\.]+)?\s*\)|[a-z]{3,20}|#[a-f0-9]{3,6})(?:\s+(\d{1,3}(?:\.\d+)?)(%|px)?)?(?:\s|$)/i,b.exports=d},{}],10:[function(a,b,c){function d(a,b){this.src=a,this.image=new Image;var c=this;this.tainted=null,this.promise=new Promise(function(d,e){c.image.onload=d,c.image.onerror=e,b&&(c.image.crossOrigin="anonymous"),c.image.src=a,c.image.complete===!0&&d(c.image)})}b.exports=d},{}],11:[function(a,b,c){function d(a,b){this.link=null,this.options=a,this.support=b,this.origin=this.getOrigin(window.location.href)}var e=a("./log"),f=a("./imagecontainer"),g=a("./dummyimagecontainer"),h=a("./proxyimagecontainer"),i=a("./framecontainer"),j=a("./svgcontainer"),k=a("./svgnodecontainer"),l=a("./lineargradientcontainer"),m=a("./webkitgradientcontainer"),n=a("./utils").bind;d.prototype.findImages=function(a){var b=[];return a.reduce(function(a,b){switch(b.node.nodeName){case"IMG":return a.concat([{args:[b.node.src],method:"url"}]);case"svg":case"IFRAME":return a.concat([{args:[b.node],method:b.node.nodeName}])}return a},[]).forEach(this.addImage(b,this.loadImage),this),b},d.prototype.findBackgroundImage=function(a,b){return b.parseBackgroundImages().filter(this.hasImageBackground).forEach(this.addImage(a,this.loadImage),this),a},d.prototype.addImage=function(a,b){return function(c){c.args.forEach(function(d){this.imageExists(a,d)||(a.splice(0,0,b.call(this,c)),e("Added image #"+a.length,"string"==typeof d?d.substring(0,100):d))},this)}},d.prototype.hasImageBackground=function(a){return"none"!==a.method},d.prototype.loadImage=function(a){if("url"===a.method){var b=a.args[0];return!this.isSVG(b)||this.support.svg||this.options.allowTaint?b.match(/data:image\/.*;base64,/i)?new f(b.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),(!1)):this.isSameOrigin(b)||this.options.allowTaint===!0||this.isSVG(b)?new f(b,(!1)):this.support.cors&&!this.options.allowTaint&&this.options.useCORS?new f(b,(!0)):this.options.proxy?new h(b,this.options.proxy):new g(b):new j(b)}return"linear-gradient"===a.method?new l(a):"gradient"===a.method?new m(a):"svg"===a.method?new k(a.args[0],this.support.svg):"IFRAME"===a.method?new i(a.args[0],this.isSameOrigin(a.args[0].src),this.options):new g(a)},d.prototype.isSVG=function(a){return"svg"===a.substring(a.length-3).toLowerCase()||j.prototype.isInline(a)},d.prototype.imageExists=function(a,b){return a.some(function(a){return a.src===b})},d.prototype.isSameOrigin=function(a){return this.getOrigin(a)===this.origin},d.prototype.getOrigin=function(a){var b=this.link||(this.link=document.createElement("a"));return b.href=a,b.href=b.href,b.protocol+b.hostname+b.port},d.prototype.getPromise=function(a){return this.timeout(a,this.options.imageTimeout)["catch"](function(){var b=new g(a.src);return b.promise.then(function(b){a.image=b})})},d.prototype.get=function(a){var b=null;return this.images.some(function(c){return(b=c).src===a})?b:null},d.prototype.fetch=function(a){return this.images=a.reduce(n(this.findBackgroundImage,this),this.findImages(a)),this.images.forEach(function(a,b){a.promise.then(function(){e("Succesfully loaded image #"+(b+1),a)},function(c){e("Failed loading image #"+(b+1),a,c)})}),this.ready=Promise.all(this.images.map(this.getPromise,this)),e("Finished searching images"),this},d.prototype.timeout=function(a,b){var c,d=Promise.race([a.promise,new Promise(function(d,f){c=setTimeout(function(){e("Timed out loading image",a),f(a)},b)})]).then(function(a){return clearTimeout(c),a});return d["catch"](function(){clearTimeout(c)}),d},b.exports=d},{"./dummyimagecontainer":5,"./framecontainer":8,"./imagecontainer":10,"./lineargradientcontainer":12,"./log":13,"./proxyimagecontainer":17,"./svgcontainer":23,"./svgnodecontainer":24,"./utils":26,"./webkitgradientcontainer":27}],12:[function(a,b,c){function d(a){e.apply(this,arguments),this.type=e.TYPES.LINEAR;var b=d.REGEXP_DIRECTION.test(a.args[0])||!e.REGEXP_COLORSTOP.test(a.args[0]);b?a.args[0].split(/\s+/).reverse().forEach(function(a,b){switch(a){case"left":this.x0=0,this.x1=1;break;case"top":this.y0=0,this.y1=1;break;case"right":this.x0=1,this.x1=0;break;case"bottom":this.y0=1,this.y1=0;break;case"to":var c=this.y0,d=this.x0;this.y0=this.y1,this.x0=this.x1,this.x1=d,this.y1=c;break;case"center":break;default:var e=.01*parseFloat(a,10);if(isNaN(e))break;0===b?(this.y0=e,this.y1=1-this.y0):(this.x0=e,this.x1=1-this.x0)}},this):(this.y0=0,this.y1=1),this.colorStops=a.args.slice(b?1:0).map(function(a){var b=a.match(e.REGEXP_COLORSTOP),c=+b[2],d=0===c?"%":b[3];return{color:new f(b[1]),stop:"%"===d?c/100:null}}),null===this.colorStops[0].stop&&(this.colorStops[0].stop=0),null===this.colorStops[this.colorStops.length-1].stop&&(this.colorStops[this.colorStops.length-1].stop=1),this.colorStops.forEach(function(a,b){null===a.stop&&this.colorStops.slice(b).some(function(c,d){return null!==c.stop&&(a.stop=(c.stop-this.colorStops[b-1].stop)/(d+1)+this.colorStops[b-1].stop,!0)},this)},this)}var e=a("./gradientcontainer"),f=a("./color");d.prototype=Object.create(e.prototype),d.REGEXP_DIRECTION=/^\s*(?:to|left|right|top|bottom|center|\d{1,3}(?:\.\d+)?%?)(?:\s|$)/i,b.exports=d},{"./color":3,"./gradientcontainer":9}],13:[function(a,b,c){var d=function(){d.options.logging&&window.console&&window.console.log&&Function.prototype.bind.call(window.console.log,window.console).apply(window.console,[Date.now()-d.options.start+"ms","html2canvas:"].concat([].slice.call(arguments,0)))};d.options={logging:!1},b.exports=d},{}],14:[function(a,b,c){function d(a,b){this.node=a,this.parent=b,this.stack=null,this.bounds=null,this.borders=null,this.clip=[],this.backgroundClip=[],this.offsetBounds=null,this.visible=null,this.computedStyles=null,this.colors={},this.styles={},this.backgroundImages=null,this.transformData=null,this.transformMatrix=null,this.isPseudoElement=!1,this.opacity=null}function e(a){var b=a.options[a.selectedIndex||0];return b?b.text||"":""}function f(a){if(a&&"matrix"===a[1])return a[2].split(",").map(function(a){return parseFloat(a.trim())});if(a&&"matrix3d"===a[1]){var b=a[2].split(",").map(function(a){return parseFloat(a.trim())});return[b[0],b[1],b[4],b[5],b[12],b[13]]}}function g(a){var b=a[0],c=a[2],d=a[4],e=a[1],f=a[3],g=a[5],h=b*f-c*e,i=[f,-e,-c,b,c*g-d*f,d*e-b*g].map(function(a){return a/h});return i}function h(a){return a.toString().indexOf("%")!==-1}function i(a){return a.replace("px","")}function j(a){return parseFloat(a)}var k=a("./color"),l=a("./utils"),m=l.getBounds,n=l.parseBackgrounds,o=l.offsetBounds;d.prototype.cloneTo=function(a){a.visible=this.visible,a.borders=this.borders,a.bounds=this.bounds,a.clip=this.clip,a.backgroundClip=this.backgroundClip,a.computedStyles=this.computedStyles,a.styles=this.styles,a.backgroundImages=this.backgroundImages,a.opacity=this.opacity},d.prototype.getOpacity=function(){return null===this.opacity?this.opacity=this.cssFloat("opacity"):this.opacity},d.prototype.assignStack=function(a){this.stack=a,a.children.push(this)},d.prototype.isElementVisible=function(){return this.node.nodeType===Node.TEXT_NODE?this.parent.visible:"none"!==this.css("display")&&"hidden"!==this.css("visibility")&&!this.node.hasAttribute("data-html2canvas-ignore")&&("INPUT"!==this.node.nodeName||"hidden"!==this.node.getAttribute("type"))},d.prototype.css=function(a){return this.computedStyles||(this.computedStyles=this.isPseudoElement?this.parent.computedStyle(this.before?":before":":after"):this.computedStyle(null)),this.styles[a]||(this.styles[a]=this.computedStyles[a])},d.prototype.prefixedCss=function(a){var b=["webkit","moz","ms","o"],c=this.css(a);return void 0===c&&b.some(function(b){return c=this.css(b+a.substr(0,1).toUpperCase()+a.substr(1)),void 0!==c},this),void 0===c?null:c},d.prototype.computedStyle=function(a){return this.node.ownerDocument.defaultView.getComputedStyle(this.node,a)},d.prototype.cssInt=function(a){var b=parseInt(this.css(a),10);return isNaN(b)?0:b},d.prototype.color=function(a){return this.colors[a]||(this.colors[a]=new k(this.css(a)))},d.prototype.cssFloat=function(a){var b=parseFloat(this.css(a));return isNaN(b)?0:b},d.prototype.fontWeight=function(){var a=this.css("fontWeight");switch(parseInt(a,10)){case 401:a="bold";break;case 400:a="normal"}return a},d.prototype.parseClip=function(){var a=this.css("clip").match(this.CLIP);return a?{top:parseInt(a[1],10),right:parseInt(a[2],10),bottom:parseInt(a[3],10),left:parseInt(a[4],10)}:null},d.prototype.parseBackgroundImages=function(){return this.backgroundImages||(this.backgroundImages=n(this.css("backgroundImage")))},d.prototype.cssList=function(a,b){var c=(this.css(a)||"").split(",");return c=c[b||0]||c[0]||"auto",c=c.trim().split(" "),1===c.length&&(c=[c[0],h(c[0])?"auto":c[0]]),c},d.prototype.parseBackgroundSize=function(a,b,c){var d,e,f=this.cssList("backgroundSize",c);if(h(f[0]))d=a.width*parseFloat(f[0])/100;else{if(/contain|cover/.test(f[0])){var g=a.width/a.height,i=b.width/b.height;return g<i^"contain"===f[0]?{width:a.height*i,height:a.height}:{width:a.width,height:a.width/i}}d=parseInt(f[0],10)}return e="auto"===f[0]&&"auto"===f[1]?b.height:"auto"===f[1]?d/b.width*b.height:h(f[1])?a.height*parseFloat(f[1])/100:parseInt(f[1],10),"auto"===f[0]&&(d=e/b.height*b.width),{width:d,height:e}},d.prototype.parseBackgroundPosition=function(a,b,c,d){var e,f,g=this.cssList("backgroundPosition",c);return e=h(g[0])?(a.width-(d||b).width)*(parseFloat(g[0])/100):parseInt(g[0],10),f="auto"===g[1]?e/b.width*b.height:h(g[1])?(a.height-(d||b).height)*parseFloat(g[1])/100:parseInt(g[1],10),"auto"===g[0]&&(e=f/b.height*b.width),{left:e,top:f}},d.prototype.parseBackgroundRepeat=function(a){return this.cssList("backgroundRepeat",a)[0]},d.prototype.parseTextShadows=function(){var a=this.css("textShadow"),b=[];if(a&&"none"!==a)for(var c=a.match(this.TEXT_SHADOW_PROPERTY),d=0;c&&d<c.length;d++){var e=c[d].match(this.TEXT_SHADOW_VALUES);b.push({color:new k(e[0]),offsetX:e[1]?parseFloat(e[1].replace("px","")):0,offsetY:e[2]?parseFloat(e[2].replace("px","")):0,blur:e[3]?e[3].replace("px",""):0})}return b},d.prototype.parseTransform=function(){if(!this.transformData)if(this.hasTransform()){var a=this.parseBounds(),b=this.prefixedCss("transformOrigin").split(" ").map(i).map(j);b[0]+=a.left,b[1]+=a.top,this.transformData={origin:b,matrix:this.parseTransformMatrix()}}else this.transformData={origin:[0,0],matrix:[1,0,0,1,0,0]};return this.transformData},d.prototype.parseTransformMatrix=function(){if(!this.transformMatrix){var a=this.prefixedCss("transform"),b=a?f(a.match(this.MATRIX_PROPERTY)):null;this.transformMatrix=b?b:[1,0,0,1,0,0]}return this.transformMatrix},d.prototype.inverseTransform=function(){var a=this.parseTransform();return{origin:a.origin,matrix:g(a.matrix)}},d.prototype.parseBounds=function(){return this.bounds||(this.bounds=this.hasTransform()?o(this.node):m(this.node))},d.prototype.hasTransform=function(){return"1,0,0,1,0,0"!==this.parseTransformMatrix().join(",")||this.parent&&this.parent.hasTransform()},d.prototype.getValue=function(){var a=this.node.value||"";return"SELECT"===this.node.tagName?a=e(this.node):"password"===this.node.type&&(a=Array(a.length+1).join("•")),0===a.length?this.node.placeholder||"":a},d.prototype.MATRIX_PROPERTY=/(matrix|matrix3d)\((.+)\)/,d.prototype.TEXT_SHADOW_PROPERTY=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,d.prototype.TEXT_SHADOW_VALUES=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g,d.prototype.CLIP=/^rect\((\d+)px,? (\d+)px,? (\d+)px,? (\d+)px\)$/,b.exports=d},{"./color":3,"./utils":26}],15:[function(a,b,c){function d(a,b,c,d,e){P("Starting NodeParser"),this.renderer=b,this.options=e,this.range=null,this.support=c,this.renderQueue=[],this.stack=new W((!0),1,a.ownerDocument,null);var f=new R(a,null);if(e.background&&b.rectangle(0,0,b.width,b.height,new V(e.background)),a===a.ownerDocument.documentElement){var g=new R(f.color("backgroundColor").isTransparent()?a.ownerDocument.body:a.ownerDocument.documentElement,null);b.rectangle(0,0,b.width,b.height,g.color("backgroundColor"))}f.visibile=f.isElementVisible(),this.createPseudoHideStyles(a.ownerDocument),this.disableAnimations(a.ownerDocument),this.nodes=K([f].concat(this.getChildren(f)).filter(function(a){return a.visible=a.isElementVisible()}).map(this.getPseudoElements,this)),this.fontMetrics=new U,P("Fetched nodes, total:",this.nodes.length),P("Calculate overflow clips"),this.calculateOverflowClips(),P("Start fetching images"),this.images=d.fetch(this.nodes.filter(C)),this.ready=this.images.ready.then(Y(function(){return P("Images loaded, starting parsing"),P("Creating stacking contexts"),this.createStackingContexts(),P("Sorting stacking contexts"),this.sortStackingContexts(this.stack),this.parse(this.stack),P("Render queue created with "+this.renderQueue.length+" items"),new Promise(Y(function(a){e.async?"function"==typeof e.async?e.async.call(this,this.renderQueue,a):this.renderQueue.length>0?(this.renderIndex=0,this.asyncRenderer(this.renderQueue,a)):a():(this.renderQueue.forEach(this.paint,this),a())},this))},this))}function e(a){return a.parent&&a.parent.clip.length}function f(a){return a.replace(/(\-[a-z])/g,function(a){return a.toUpperCase().replace("-","")})}function g(){}function h(a,b,c,d){var e={top:b.top+a[0].width/2,right:b.right-a[1].width/2,bottom:b.bottom-a[2].width/2,left:b.left+a[3].width/2};return a.map(function(f,g){if(f.width>0){var h=b.left,i=b.top,j=b.width,k=b.height-a[2].width;switch(g){case 0:k=a[0].width,f.args=l({c1:[h,i],c2:[h+j,i],c3:[h+j-a[1].width,i+k],c4:[h+a[3].width,i+k]},d[0],d[1],c.topLeftOuter,c.topLeftInner,c.topRightOuter,c.topRightInner),f.pathArgs=m({c1:[e.left,e.top],c2:[e.right,e.top]},d[0],d[1],c.topLeft,c.topRight);break;case 1:h=b.left+b.width-a[1].width,j=a[1].width,f.args=l({c1:[h+j,i],c2:[h+j,i+k+a[2].width],c3:[h,i+k],c4:[h,i+a[0].width]},d[1],d[2],c.topRightOuter,c.topRightInner,c.bottomRightOuter,c.bottomRightInner),f.pathArgs=m({c1:[e.right,e.top],c2:[e.right,e.bottom]},d[1],d[2],c.topRight,c.bottomRight);break;case 2:i=i+b.height-a[2].width,k=a[2].width,f.args=l({c1:[h+j,i+k],c2:[h,i+k],c3:[h+a[3].width,i],c4:[h+j-a[3].width,i]},d[2],d[3],c.bottomRightOuter,c.bottomRightInner,c.bottomLeftOuter,c.bottomLeftInner),f.pathArgs=m({c1:[e.right,e.bottom],c2:[e.left,e.bottom]},d[2],d[3],c.bottomRight,c.bottomLeft);break;case 3:j=a[3].width,f.args=l({c1:[h,i+k+a[2].width],c2:[h,i],c3:[h+j,i+a[0].width],c4:[h+j,i+k]},d[3],d[0],c.bottomLeftOuter,c.bottomLeftInner,c.topLeftOuter,c.topLeftInner),f.pathArgs=m({c1:[e.left,e.bottom],c2:[e.left,e.top]},d[3],d[0],c.bottomLeft,c.topLeft)}}return f})}function i(a,b,c,d){var e=4*((Math.sqrt(2)-1)/3),f=c*e,g=d*e,h=a+c,i=b+d;return{topLeft:k({x:a,y:i},{x:a,y:i-g},{x:h-f,y:b},{x:h,y:b}),topRight:k({x:a,y:b},{x:a+f,y:b},{x:h,y:i-g},{x:h,y:i}),bottomRight:k({x:h,y:b},{x:h,y:b+g},{x:a+f,y:i},{x:a,y:i}),bottomLeft:k({x:h,y:i},{x:h-f,y:i},{x:a,y:b+g},{x:a,y:b})}}function j(a,b,c){var d=a.left,e=a.top,f=a.width,g=a.height,h=b[0][0]<f/2?b[0][0]:f/2,j=b[0][1]<g/2?b[0][1]:g/2,k=b[1][0]<f/2?b[1][0]:f/2,l=b[1][1]<g/2?b[1][1]:g/2,m=b[2][0]<f/2?b[2][0]:f/2,n=b[2][1]<g/2?b[2][1]:g/2,o=b[3][0]<f/2?b[3][0]:f/2,p=b[3][1]<g/2?b[3][1]:g/2,q=f-k,r=g-n,s=f-m,t=g-p;
return{topLeft:i(d+c[3].width/2,e+c[0].width/2,Math.max(0,h-c[3].width/2),Math.max(0,j-c[0].width/2)).topLeft.subdivide(.5),topRight:i(d+Math.min(q,f+c[3].width/2),e+c[0].width/2,q>f+c[3].width/2?0:k-c[3].width/2,l-c[0].width/2).topRight.subdivide(.5),bottomRight:i(d+Math.min(s,f-c[3].width/2),e+Math.min(r,g+c[0].width/2),Math.max(0,m-c[1].width/2),n-c[2].width/2).bottomRight.subdivide(.5),bottomLeft:i(d+c[3].width/2,e+t,Math.max(0,o-c[3].width/2),p-c[2].width/2).bottomLeft.subdivide(.5),topLeftOuter:i(d,e,h,j).topLeft.subdivide(.5),topLeftInner:i(d+c[3].width,e+c[0].width,Math.max(0,h-c[3].width),Math.max(0,j-c[0].width)).topLeft.subdivide(.5),topRightOuter:i(d+q,e,k,l).topRight.subdivide(.5),topRightInner:i(d+Math.min(q,f+c[3].width),e+c[0].width,q>f+c[3].width?0:k-c[3].width,l-c[0].width).topRight.subdivide(.5),bottomRightOuter:i(d+s,e+r,m,n).bottomRight.subdivide(.5),bottomRightInner:i(d+Math.min(s,f-c[3].width),e+Math.min(r,g+c[0].width),Math.max(0,m-c[1].width),n-c[2].width).bottomRight.subdivide(.5),bottomLeftOuter:i(d,e+t,o,p).bottomLeft.subdivide(.5),bottomLeftInner:i(d+c[3].width,e+t,Math.max(0,o-c[3].width),p-c[2].width).bottomLeft.subdivide(.5)}}function k(a,b,c,d){var e=function(a,b,c){return{x:a.x+(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}};return{start:a,startControl:b,endControl:c,end:d,subdivide:function(f){var g=e(a,b,f),h=e(b,c,f),i=e(c,d,f),j=e(g,h,f),l=e(h,i,f),m=e(j,l,f);return[k(a,g,j,m),k(m,l,i,d)]},curveTo:function(a){a.push(["bezierCurve",b.x,b.y,c.x,c.y,d.x,d.y])},curveToReversed:function(d){d.push(["bezierCurve",c.x,c.y,b.x,b.y,a.x,a.y])}}}function l(a,b,c,d,e,f,g){var h=[];return b[0]>0||b[1]>0?(h.push(["line",d[1].start.x,d[1].start.y]),d[1].curveTo(h)):h.push(["line",a.c1[0],a.c1[1]]),c[0]>0||c[1]>0?(h.push(["line",f[0].start.x,f[0].start.y]),f[0].curveTo(h),h.push(["line",g[0].end.x,g[0].end.y]),g[0].curveToReversed(h)):(h.push(["line",a.c2[0],a.c2[1]]),h.push(["line",a.c3[0],a.c3[1]])),b[0]>0||b[1]>0?(h.push(["line",e[1].end.x,e[1].end.y]),e[1].curveToReversed(h)):h.push(["line",a.c4[0],a.c4[1]]),h}function m(a,b,c,d,e){var f=[];return b[0]>0||b[1]>0?(f.push(["line",d[1].start.x,d[1].start.y]),d[1].curveTo(f)):f.push(["line",a.c1[0],a.c1[1]]),c[0]>0||c[1]>0?(f.push(["line",e[0].start.x,e[0].start.y]),e[0].curveTo(f)):f.push(["line",a.c2[0],a.c2[1]]),f}function n(a,b,c,d,e,f,g){b[0]>0||b[1]>0?(a.push(["line",d[0].start.x,d[0].start.y]),d[0].curveTo(a),d[1].curveTo(a)):a.push(["line",f,g]),(c[0]>0||c[1]>0)&&a.push(["line",e[0].start.x,e[0].start.y])}function o(a){return a.cssInt("zIndex")<0}function p(a){return a.cssInt("zIndex")>0}function q(a){return 0===a.cssInt("zIndex")}function r(a){return["inline","inline-block","inline-table"].indexOf(a.css("display"))!==-1}function s(a){return a instanceof W}function t(a){return a.node.data.trim().length>0}function u(a){return/^(normal|none|0px)$/.test(a.parent.css("letterSpacing"))}function v(a){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(b){var c=a.css("border"+b+"Radius"),d=c.split(" ");return d.length<=1&&(d[1]=d[0]),d.map(H)})}function w(a){return a.nodeType===Node.TEXT_NODE||a.nodeType===Node.ELEMENT_NODE}function x(a){var b=a.css("position"),c=["absolute","relative","fixed"].indexOf(b)!==-1?a.css("zIndex"):"auto";return"auto"!==c}function y(a){return"static"!==a.css("position")}function z(a){return"none"!==a.css("float")}function A(a){return["inline-block","inline-table"].indexOf(a.css("display"))!==-1}function B(a){var b=this;return function(){return!a.apply(b,arguments)}}function C(a){return a.node.nodeType===Node.ELEMENT_NODE}function D(a){return a.isPseudoElement===!0}function E(a){return a.node.nodeType===Node.TEXT_NODE}function F(a){return function(b,c){return b.cssInt("zIndex")+a.indexOf(b)/a.length-(c.cssInt("zIndex")+a.indexOf(c)/a.length)}}function G(a){return a.getOpacity()<1}function H(a){return parseInt(a,10)}function I(a){return a.width}function J(a){return a.node.nodeType!==Node.ELEMENT_NODE||["SCRIPT","HEAD","TITLE","OBJECT","BR","OPTION"].indexOf(a.node.nodeName)===-1}function K(a){return[].concat.apply([],a)}function L(a){var b=a.substr(0,1);return b===a.substr(a.length-1)&&b.match(/'|"/)?a.substr(1,a.length-2):a}function M(a){for(var b,c=[],d=0,e=!1;a.length;)N(a[d])===e?(b=a.splice(0,d),b.length&&c.push(Q.ucs2.encode(b)),e=!e,d=0):d++,d>=a.length&&(b=a.splice(0,d),b.length&&c.push(Q.ucs2.encode(b)));return c}function N(a){return[32,13,10,9,45].indexOf(a)!==-1}function O(a){return/[^\u0000-\u00ff]/.test(a)}var P=a("./log"),Q=a("punycode"),R=a("./nodecontainer"),S=a("./textcontainer"),T=a("./pseudoelementcontainer"),U=a("./fontmetrics"),V=a("./color"),W=a("./stackingcontext"),X=a("./utils"),Y=X.bind,Z=X.getBounds,$=X.parseBackgrounds,_=X.offsetBounds;d.prototype.calculateOverflowClips=function(){this.nodes.forEach(function(a){if(C(a)){D(a)&&a.appendToDOM(),a.borders=this.parseBorders(a);var b="hidden"===a.css("overflow")?[a.borders.clip]:[],c=a.parseClip();c&&["absolute","fixed"].indexOf(a.css("position"))!==-1&&b.push([["rect",a.bounds.left+c.left,a.bounds.top+c.top,c.right-c.left,c.bottom-c.top]]),a.clip=e(a)?a.parent.clip.concat(b):b,a.backgroundClip="hidden"!==a.css("overflow")?a.clip.concat([a.borders.clip]):a.clip,D(a)&&a.cleanDOM()}else E(a)&&(a.clip=e(a)?a.parent.clip:[]);D(a)||(a.bounds=null)},this)},d.prototype.asyncRenderer=function(a,b,c){c=c||Date.now(),this.paint(a[this.renderIndex++]),a.length===this.renderIndex?b():c+20>Date.now()?this.asyncRenderer(a,b,c):setTimeout(Y(function(){this.asyncRenderer(a,b)},this),0)},d.prototype.createPseudoHideStyles=function(a){this.createStyles(a,"."+T.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+':before { content: "" !important; display: none !important; }.'+T.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER+':after { content: "" !important; display: none !important; }')},d.prototype.disableAnimations=function(a){this.createStyles(a,"* { -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; animation: none !important; -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; transition: none !important;}")},d.prototype.createStyles=function(a,b){var c=a.createElement("style");c.innerHTML=b,a.body.appendChild(c)},d.prototype.getPseudoElements=function(a){var b=[[a]];if(a.node.nodeType===Node.ELEMENT_NODE){var c=this.getPseudoElement(a,":before"),d=this.getPseudoElement(a,":after");c&&b.push(c),d&&b.push(d)}return K(b)},d.prototype.getPseudoElement=function(a,b){var c=a.computedStyle(b);if(!c||!c.content||"none"===c.content||"-moz-alt-content"===c.content||"none"===c.display)return null;for(var d=L(c.content),e="url"===d.substr(0,3),g=document.createElement(e?"img":"html2canvaspseudoelement"),h=new T(g,a,b),i=c.length-1;i>=0;i--){var j=f(c.item(i));g.style[j]=c[j]}if(g.className=T.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE+" "+T.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER,e)return g.src=$(d)[0].args[0],[h];var k=document.createTextNode(d);return g.appendChild(k),[h,new S(k,h)]},d.prototype.getChildren=function(a){return K([].filter.call(a.node.childNodes,w).map(function(b){var c=[b.nodeType===Node.TEXT_NODE?new S(b,a):new R(b,a)].filter(J);return b.nodeType===Node.ELEMENT_NODE&&c.length&&"TEXTAREA"!==b.tagName?c[0].isElementVisible()?c.concat(this.getChildren(c[0])):[]:c},this))},d.prototype.newStackingContext=function(a,b){var c=new W(b,a.getOpacity(),a.node,a.parent);a.cloneTo(c);var d=b?c.getParentStack(this):c.parent.stack;d.contexts.push(c),a.stack=c},d.prototype.createStackingContexts=function(){this.nodes.forEach(function(a){C(a)&&(this.isRootElement(a)||G(a)||x(a)||this.isBodyWithTransparentRoot(a)||a.hasTransform())?this.newStackingContext(a,!0):C(a)&&(y(a)&&q(a)||A(a)||z(a))?this.newStackingContext(a,!1):a.assignStack(a.parent.stack)},this)},d.prototype.isBodyWithTransparentRoot=function(a){return"BODY"===a.node.nodeName&&a.parent.color("backgroundColor").isTransparent()},d.prototype.isRootElement=function(a){return null===a.parent},d.prototype.sortStackingContexts=function(a){a.contexts.sort(F(a.contexts.slice(0))),a.contexts.forEach(this.sortStackingContexts,this)},d.prototype.parseTextBounds=function(a){return function(b,c,d){if("none"!==a.parent.css("textDecoration").substr(0,4)||0!==b.trim().length){if(this.support.rangeBounds&&!a.parent.hasTransform()){var e=d.slice(0,c).join("").length;return this.getRangeBounds(a.node,e,b.length)}if(a.node&&"string"==typeof a.node.data){var f=a.node.splitText(b.length),g=this.getWrapperBounds(a.node,a.parent.hasTransform());return a.node=f,g}}else this.support.rangeBounds&&!a.parent.hasTransform()||(a.node=a.node.splitText(b.length));return{}}},d.prototype.getWrapperBounds=function(a,b){var c=a.ownerDocument.createElement("html2canvaswrapper"),d=a.parentNode,e=a.cloneNode(!0);c.appendChild(a.cloneNode(!0)),d.replaceChild(c,a);var f=b?_(c):Z(c);return d.replaceChild(e,c),f},d.prototype.getRangeBounds=function(a,b,c){var d=this.range||(this.range=a.ownerDocument.createRange());return d.setStart(a,b),d.setEnd(a,b+c),d.getBoundingClientRect()},d.prototype.parse=function(a){var b=a.contexts.filter(o),c=a.children.filter(C),d=c.filter(B(z)),e=d.filter(B(y)).filter(B(r)),f=c.filter(B(y)).filter(z),h=d.filter(B(y)).filter(r),i=a.contexts.concat(d.filter(y)).filter(q),j=a.children.filter(E).filter(t),k=a.contexts.filter(p);b.concat(e).concat(f).concat(h).concat(i).concat(j).concat(k).forEach(function(a){this.renderQueue.push(a),s(a)&&(this.parse(a),this.renderQueue.push(new g))},this)},d.prototype.paint=function(a){try{a instanceof g?this.renderer.ctx.restore():E(a)?(D(a.parent)&&a.parent.appendToDOM(),this.paintText(a),D(a.parent)&&a.parent.cleanDOM()):this.paintNode(a)}catch(b){if(P(b),this.options.strict)throw b}},d.prototype.paintNode=function(a){s(a)&&(this.renderer.setOpacity(a.opacity),this.renderer.ctx.save(),a.hasTransform()&&this.renderer.setTransform(a.parseTransform())),"INPUT"===a.node.nodeName&&"checkbox"===a.node.type?this.paintCheckbox(a):"INPUT"===a.node.nodeName&&"radio"===a.node.type?this.paintRadio(a):this.paintElement(a)},d.prototype.paintElement=function(a){var b=a.parseBounds();this.renderer.clip(a.backgroundClip,function(){this.renderer.renderBackground(a,b,a.borders.borders.map(I))},this,a),this.renderer.mask(a.backgroundClip,function(){this.renderer.renderShadows(a,a.borders.clip)},this,a),this.renderer.clip(a.clip,function(){this.renderer.renderBorders(a.borders.borders)},this,a),this.renderer.clip(a.backgroundClip,function(){switch(a.node.nodeName){case"svg":case"IFRAME":var c=this.images.get(a.node);c?this.renderer.renderImage(a,b,a.borders,c):P("Error loading <"+a.node.nodeName+">",a.node);break;case"IMG":var d=this.images.get(a.node.src);d?this.renderer.renderImage(a,b,a.borders,d):P("Error loading <img>",a.node.src);break;case"CANVAS":this.renderer.renderImage(a,b,a.borders,{image:a.node});break;case"SELECT":case"INPUT":case"TEXTAREA":this.paintFormValue(a)}},this,a)},d.prototype.paintCheckbox=function(a){var b=a.parseBounds(),c=Math.min(b.width,b.height),d={width:c-1,height:c-1,top:b.top,left:b.left},e=[3,3],f=[e,e,e,e],g=[1,1,1,1].map(function(a){return{color:new V("#A5A5A5"),width:a}}),i=j(d,f,g);this.renderer.clip(a.backgroundClip,function(){this.renderer.rectangle(d.left+1,d.top+1,d.width-2,d.height-2,new V("#DEDEDE")),this.renderer.renderBorders(h(g,d,i,f)),a.node.checked&&(this.renderer.font(new V("#424242"),"normal","normal","bold",c-3+"px","arial"),this.renderer.text("✔",d.left+c/6,d.top+c-1))},this,a)},d.prototype.paintRadio=function(a){var b=a.parseBounds(),c=Math.min(b.width,b.height)-2;this.renderer.clip(a.backgroundClip,function(){this.renderer.circleStroke(b.left+1,b.top+1,c,new V("#DEDEDE"),1,new V("#A5A5A5")),a.node.checked&&this.renderer.circle(Math.ceil(b.left+c/4)+1,Math.ceil(b.top+c/4)+1,Math.floor(c/2),new V("#424242"))},this,a)},d.prototype.paintFormValue=function(a){var b=a.getValue();if(b.length>0){var c=a.node.ownerDocument,d=c.createElement("html2canvaswrapper"),e=["lineHeight","textAlign","fontFamily","fontWeight","fontSize","color","paddingLeft","paddingTop","paddingRight","paddingBottom","width","height","borderLeftStyle","borderTopStyle","borderLeftWidth","borderTopWidth","boxSizing","whiteSpace","wordWrap"];e.forEach(function(b){try{d.style[b]=a.css(b)}catch(c){P("html2canvas: Parse: Exception caught in renderFormValue: "+c.message)}});var f=a.parseBounds();d.style.position="fixed",d.style.left=f.left+"px",d.style.top=f.top+"px",d.textContent=b,c.body.appendChild(d),this.paintText(new S(d.firstChild,a)),c.body.removeChild(d)}},d.prototype.paintText=function(a){a.applyTextTransform();var b=Q.ucs2.decode(a.node.data),c=(!this.options.letterRendering||u(a))&&!O(a.node.data),d=c?M(b):b.map(function(a){return Q.ucs2.encode([a])});c||(a.parent.node.style.fontVariantLigatures="none");var e=a.parent.fontWeight(),f=a.parent.css("fontSize"),g=a.parent.css("fontFamily"),h=a.parent.parseTextShadows();this.renderer.font(a.parent.color("color"),a.parent.css("fontStyle"),a.parent.css("fontVariant"),e,f,g),h.length?this.renderer.fontShadow(h[0].color,h[0].offsetX,h[0].offsetY,h[0].blur):this.renderer.clearShadow(),this.renderer.clip(a.parent.clip,function(){d.map(this.parseTextBounds(a),this).forEach(function(b,c){b&&(this.renderer.text(d[c],b.left,b.bottom),this.renderTextDecoration(a.parent,b,this.fontMetrics.getMetrics(g,f)))},this)},this,a.parent)},d.prototype.renderTextDecoration=function(a,b,c){switch(a.css("textDecoration").split(" ")[0]){case"underline":this.renderer.rectangle(b.left,Math.round(b.top+c.baseline+c.lineWidth),b.width,1,a.color("color"));break;case"overline":this.renderer.rectangle(b.left,Math.round(b.top),b.width,1,a.color("color"));break;case"line-through":this.renderer.rectangle(b.left,Math.ceil(b.top+c.middle+c.lineWidth),b.width,1,a.color("color"))}};var aa={inset:[["darken",.6],["darken",.1],["darken",.1],["darken",.6]]};d.prototype.parseBorders=function(a){var b=a.parseBounds(),c=v(a),d=["Top","Right","Bottom","Left"].map(function(b,c){var d=a.css("border"+b+"Style"),e=a.color("border"+b+"Color");"inset"===d&&e.isBlack()&&(e=new V([255,255,255,e.a]));var f=aa[d]?aa[d][c]:null;return{width:a.cssInt("border"+b+"Width"),color:f?e[f[0]](f[1]):e,style:d,pathArgs:null,args:null}}),e=j(b,c,d);return{clip:this.parseBackgroundClip(a,e,d,c,b),borders:h(d,b,e,c)}},d.prototype.parseBackgroundClip=function(a,b,c,d,e){var f=a.css("backgroundClip"),g=[];switch(f){case"content-box":case"padding-box":n(g,d[0],d[1],b.topLeftInner,b.topRightInner,e.left+c[3].width,e.top+c[0].width),n(g,d[1],d[2],b.topRightInner,b.bottomRightInner,e.left+e.width-c[1].width,e.top+c[0].width),n(g,d[2],d[3],b.bottomRightInner,b.bottomLeftInner,e.left+e.width-c[1].width,e.top+e.height-c[2].width),n(g,d[3],d[0],b.bottomLeftInner,b.topLeftInner,e.left+c[3].width,e.top+e.height-c[2].width);break;default:n(g,d[0],d[1],b.topLeftOuter,b.topRightOuter,e.left,e.top),n(g,d[1],d[2],b.topRightOuter,b.bottomRightOuter,e.left+e.width,e.top),n(g,d[2],d[3],b.bottomRightOuter,b.bottomLeftOuter,e.left+e.width,e.top+e.height),n(g,d[3],d[0],b.bottomLeftOuter,b.topLeftOuter,e.left,e.top+e.height)}return g},b.exports=d},{"./color":3,"./fontmetrics":7,"./log":13,"./nodecontainer":14,"./pseudoelementcontainer":18,"./stackingcontext":21,"./textcontainer":25,"./utils":26,punycode:1}],16:[function(a,b,c){function d(a,b,c){var d="withCredentials"in new XMLHttpRequest;if(!b)return Promise.reject("No proxy configured");var e=g(d),i=h(b,a,e);return d?k(i):f(c,i,e).then(function(a){return o(a.content)})}function e(a,b,c){var d="crossOrigin"in new Image,e=g(d),i=h(b,a,e);return d?Promise.resolve(i):f(c,i,e).then(function(a){return"data:"+a.type+";base64,"+a.content})}function f(a,b,c){return new Promise(function(d,e){var f=a.createElement("script"),g=function(){delete window.html2canvas.proxy[c],a.body.removeChild(f)};window.html2canvas.proxy[c]=function(a){g(),d(a)},f.src=b,f.onerror=function(a){g(),e(a)},a.body.appendChild(f)})}function g(a){return a?"":"html2canvas_"+Date.now()+"_"+ ++p+"_"+Math.round(1e5*Math.random())}function h(a,b,c){return a+"?url="+encodeURIComponent(b)+(c.length?"&callback=html2canvas.proxy."+c:"")}function i(a){return function(b){var c,d=new DOMParser;try{c=d.parseFromString(b,"text/html")}catch(e){m("DOMParser not supported, falling back to createHTMLDocument"),c=document.implementation.createHTMLDocument("");try{c.open(),c.write(b),c.close()}catch(f){m("createHTMLDocument write not supported, falling back to document.body.innerHTML"),c.body.innerHTML=b}}var g=c.querySelector("base");if(!g||!g.href.host){var h=c.createElement("base");h.href=a,c.head.insertBefore(h,c.head.firstChild)}return c}}function j(a,b,c,e,f,g){return new d(a,b,window.document).then(i(a)).then(function(a){return n(a,c,e,f,g,0,0)})}var k=a("./xhr"),l=a("./utils"),m=a("./log"),n=a("./clone"),o=l.decode64,p=0;c.Proxy=d,c.ProxyURL=e,c.loadUrlDocument=j},{"./clone":2,"./log":13,"./utils":26,"./xhr":28}],17:[function(a,b,c){function d(a,b){var c=document.createElement("a");c.href=a,a=c.href,this.src=a,this.image=new Image;var d=this;this.promise=new Promise(function(c,f){d.image.crossOrigin="Anonymous",d.image.onload=c,d.image.onerror=f,new e(a,b,document).then(function(a){d.image.src=a})["catch"](f)})}var e=a("./proxy").ProxyURL;b.exports=d},{"./proxy":16}],18:[function(a,b,c){function d(a,b,c){e.call(this,a,b),this.isPseudoElement=!0,this.before=":before"===c}var e=a("./nodecontainer");d.prototype.cloneTo=function(a){d.prototype.cloneTo.call(this,a),a.isPseudoElement=!0,a.before=this.before},d.prototype=Object.create(e.prototype),d.prototype.appendToDOM=function(){this.before?this.parent.node.insertBefore(this.node,this.parent.node.firstChild):this.parent.node.appendChild(this.node),this.parent.node.className+=" "+this.getHideClass()},d.prototype.cleanDOM=function(){this.node.parentNode.removeChild(this.node),this.parent.node.className=this.parent.node.className.replace(this.getHideClass(),"")},d.prototype.getHideClass=function(){return this["PSEUDO_HIDE_ELEMENT_CLASS_"+(this.before?"BEFORE":"AFTER")]},d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_BEFORE="___html2canvas___pseudoelement_before",d.prototype.PSEUDO_HIDE_ELEMENT_CLASS_AFTER="___html2canvas___pseudoelement_after",b.exports=d},{"./nodecontainer":14}],19:[function(a,b,c){function d(a,b,c,d,e){this.width=a,this.height=b,this.images=c,this.options=d,this.document=e}var e=a("./log");d.prototype.renderImage=function(a,b,c,d){var e=a.cssInt("paddingLeft"),f=a.cssInt("paddingTop"),g=a.cssInt("paddingRight"),h=a.cssInt("paddingBottom"),i=c.borders,j=b.width-(i[1].width+i[3].width+e+g),k=b.height-(i[0].width+i[2].width+f+h);this.drawImage(d,0,0,d.image.width||j,d.image.height||k,b.left+e+i[3].width,b.top+f+i[0].width,j,k)},d.prototype.renderBackground=function(a,b,c){b.height>0&&b.width>0&&(this.renderBackgroundColor(a,b),this.renderBackgroundImage(a,b,c))},d.prototype.renderBackgroundColor=function(a,b){var c=a.color("backgroundColor");c.isTransparent()||this.rectangle(b.left,b.top,b.width,b.height,c)},d.prototype.renderShadows=function(a,b){var c=a.css("boxShadow");if("none"!==c){var d=c.split(/,(?![^(]*\))/);this.shadow(b,d)}},d.prototype.renderBorders=function(a){a.forEach(this.renderBorder,this)},d.prototype.renderBorder=function(a){if(!a.color.isTransparent()&&null!==a.args)if("dashed"===a.style||"dotted"===a.style){var b="dashed"===a.style?3:a.width;this.ctx.setLineDash([b]),this.path(a.pathArgs),this.ctx.strokeStyle=a.color,this.ctx.lineWidth=a.width,this.ctx.stroke()}else this.drawShape(a.args,a.color)},d.prototype.renderBackgroundImage=function(a,b,c){var d=a.parseBackgroundImages();d.reverse().forEach(function(d,f,g){switch(d.method){case"url":var h=this.images.get(d.args[0]);h?this.renderBackgroundRepeating(a,b,h,g.length-(f+1),c):e("Error loading background-image",d.args[0]);break;case"linear-gradient":case"gradient":var i=this.images.get(d.value);i?this.renderBackgroundGradient(i,b,c):e("Error loading background-image",d.args[0]);break;case"none":break;default:e("Unknown background-image type",d.args[0])}},this)},d.prototype.renderBackgroundRepeating=function(a,b,c,d,e){var f=a.parseBackgroundSize(b,c.image,d),g=a.parseBackgroundPosition(b,c.image,d,f),h=a.parseBackgroundRepeat(d);switch(h){case"repeat-x":case"repeat no-repeat":this.backgroundRepeatShape(c,g,f,b,b.left+e[3],b.top+g.top+e[0],99999,f.height,e);break;case"repeat-y":case"no-repeat repeat":this.backgroundRepeatShape(c,g,f,b,b.left+g.left+e[3],b.top+e[0],f.width,99999,e);break;case"no-repeat":this.backgroundRepeatShape(c,g,f,b,b.left+g.left+e[3],b.top+g.top+e[0],f.width,f.height,e);break;default:this.renderBackgroundRepeat(c,g,f,{top:b.top,left:b.left},e[3],e[0])}},b.exports=d},{"./log":13}],20:[function(a,b,c){function d(a,b){f.apply(this,arguments),this.canvas=this.options.canvas||this.document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.options.canvas||(this.options.dpi&&(this.options.scale=this.options.dpi/96),this.options.scale?(this.canvas.style.width=a+"px",this.canvas.style.height=b+"px",this.canvas.width=Math.floor(a*this.options.scale),this.canvas.height=Math.floor(b*this.options.scale),this.ctx.scale(this.options.scale,this.options.scale)):(this.canvas.width=a,this.canvas.height=b)),this.taintCtx=this.document.createElement("canvas").getContext("2d"),this.ctx.textBaseline="bottom",this.variables={},h("Initialized CanvasRenderer with size",a,"x",b)}function e(a){return a.length>0}var f=a("../renderer"),g=a("../lineargradientcontainer"),h=a("../log");d.prototype=Object.create(f.prototype),d.prototype.setFillStyle=function(a){return this.ctx.fillStyle="object"==typeof a&&a.isColor?a.toString():a,this.ctx},d.prototype.rectangle=function(a,b,c,d,e){this.setFillStyle(e).fillRect(a,b,c,d)},d.prototype.circle=function(a,b,c,d){this.setFillStyle(d),this.ctx.beginPath(),this.ctx.arc(a+c/2,b+c/2,c/2,0,2*Math.PI,!0),this.ctx.closePath(),this.ctx.fill()},d.prototype.circleStroke=function(a,b,c,d,e,f){this.circle(a,b,c,d),this.ctx.strokeStyle=f.toString(),this.ctx.stroke()},d.prototype.shadow=function(a,b){var c=function(a){var b={color:/^(#|rgb|hsl|(?!(inset|initial|inherit))\D+)/i,inset:/^inset/i,px:/px$/i},c=["x","y","blur","spread"],d=a.split(/ (?![^(]*\))/),e={};for(var f in b)e[f]=d.filter(b[f].test.bind(b[f])),e[f]=0===e[f].length?null:1===e[f].length?e[f][0]:e[f];for(var g=0;g<e.px.length;g++)e[c[g]]=parseInt(e.px[g]);return e},d=function(a){var b=c(a);b.inset||(e.shadowOffsetX=b.x,e.shadowOffsetY=b.y,e.shadowColor=b.color,e.shadowBlur=b.blur,e.fill())},e=this.setFillStyle("white");e.save(),this.shape(a),b.forEach(d,this),e.restore()},d.prototype.drawShape=function(a,b){this.shape(a),this.setFillStyle(b).fill()},d.prototype.taints=function(a){if(null===a.tainted){this.taintCtx.drawImage(a.image,0,0);try{this.taintCtx.getImageData(0,0,1,1),a.tainted=!1}catch(b){this.taintCtx=document.createElement("canvas").getContext("2d"),a.tainted=!0}}return a.tainted},d.prototype.drawImage=function(a,b,c,d,e,f,g,h,i){this.taints(a)&&!this.options.allowTaint||this.ctx.drawImage(a.image,b,c,d,e,f,g,h,i)},d.prototype.clip=function(a,b,c,d){this.ctx.save(),d&&d.hasTransform()?(this.setTransform(d.inverseTransform()),a.filter(e).forEach(function(a){this.shape(a).clip()},this),this.setTransform(d.parseTransform())):a.filter(e).forEach(function(a){this.shape(a).clip()},this),b.call(c),this.ctx.restore()},d.prototype.mask=function(a,b,c,d){var e=a[a.length-1];if(e&&e.length){var f=["rect",this.canvas.width,0,-this.canvas.width,this.canvas.height],g=[f].concat(e).concat([e[0]]);a=a.slice(0,-1).concat([g])}this.clip(a,b,c,d)},d.prototype.shape=function(a){return this.ctx.beginPath(),a.forEach(function(a,b){"rect"===a[0]?this.ctx.rect.apply(this.ctx,a.slice(1)):this.ctx[0===b?"moveTo":a[0]+"To"].apply(this.ctx,a.slice(1))},this),this.ctx.closePath(),this.ctx},d.prototype.path=function(a){return this.ctx.beginPath(),a.forEach(function(a,b){"rect"===a[0]?this.ctx.rect.apply(this.ctx,a.slice(1)):this.ctx[0===b?"moveTo":a[0]+"To"].apply(this.ctx,a.slice(1))},this),this.ctx},d.prototype.font=function(a,b,c,d,e,f){c=/^(normal|small-caps)$/i.test(c)?c:"",this.setFillStyle(a).font=[b,c,d,e,f].join(" ").split(",")[0]},d.prototype.fontShadow=function(a,b,c,d){this.setVariable("shadowColor",a.toString()).setVariable("shadowOffsetY",b).setVariable("shadowOffsetX",c).setVariable("shadowBlur",d)},d.prototype.clearShadow=function(){this.setVariable("shadowColor","rgba(0,0,0,0)")},d.prototype.setOpacity=function(a){this.ctx.globalAlpha=a},d.prototype.setTransform=function(a){this.ctx.translate(a.origin[0],a.origin[1]),this.ctx.transform.apply(this.ctx,a.matrix),this.ctx.translate(-a.origin[0],-a.origin[1])},d.prototype.setVariable=function(a,b){return this.variables[a]!==b&&(this.variables[a]=this.ctx[a]=b),this},d.prototype.text=function(a,b,c){this.ctx.fillText(a,b,c)},d.prototype.backgroundRepeatShape=function(a,b,c,d,e,f,g,h,i){var j=[["line",Math.round(e),Math.round(f)],["line",Math.round(e+g),Math.round(f)],["line",Math.round(e+g),Math.round(h+f)],["line",Math.round(e),Math.round(h+f)]];this.clip([j],function(){this.renderBackgroundRepeat(a,b,c,d,i[3],i[0])},this)},d.prototype.renderBackgroundRepeat=function(a,b,c,d,e,f){var g=Math.round(d.left+b.left+e),h=Math.round(d.top+b.top+f);this.setFillStyle(this.ctx.createPattern(this.resizeImage(a,c),"repeat")),this.ctx.translate(g,h),this.ctx.fill(),this.ctx.translate(-g,-h)},d.prototype.renderBackgroundGradient=function(a,b){if(a instanceof g){var c=this.ctx.createLinearGradient(b.left+b.width*a.x0,b.top+b.height*a.y0,b.left+b.width*a.x1,b.top+b.height*a.y1);a.colorStops.forEach(function(a){c.addColorStop(a.stop,a.color.toString())}),this.rectangle(b.left,b.top,b.width,b.height,c)}},d.prototype.resizeImage=function(a,b){var c=a.image;if(c.width===b.width&&c.height===b.height)return c;var d,e=document.createElement("canvas");return e.width=b.width,e.height=b.height,d=e.getContext("2d"),d.drawImage(c,0,0,c.width,c.height,0,0,b.width,b.height),e},b.exports=d},{"../lineargradientcontainer":12,"../log":13,"../renderer":19}],21:[function(a,b,c){function d(a,b,c,d){e.call(this,c,d),this.ownStacking=a,this.contexts=[],this.children=[],this.opacity=(this.parent?this.parent.stack.opacity:1)*b}var e=a("./nodecontainer");d.prototype=Object.create(e.prototype),d.prototype.getParentStack=function(a){var b=this.parent?this.parent.stack:null;return b?b.ownStacking?b:b.getParentStack(a):a.stack},b.exports=d},{"./nodecontainer":14}],22:[function(a,b,c){function d(a){this.rangeBounds=this.testRangeBounds(a),this.cors=this.testCORS(),this.svg=this.testSVG()}d.prototype.testRangeBounds=function(a){var b,c,d,e,f=!1;return a.createRange&&(b=a.createRange(),b.getBoundingClientRect&&(c=a.createElement("boundtest"),c.style.height="123px",c.style.display="block",a.body.appendChild(c),b.selectNode(c),d=b.getBoundingClientRect(),e=d.height,123===e&&(f=!0),a.body.removeChild(c))),f},d.prototype.testCORS=function(){return"undefined"!=typeof(new Image).crossOrigin},d.prototype.testSVG=function(){var a=new Image,b=document.createElement("canvas"),c=b.getContext("2d");a.src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";try{c.drawImage(a,0,0),b.toDataURL()}catch(d){return!1}return!0},b.exports=d},{}],23:[function(a,b,c){function d(a){this.src=a,this.image=null;var b=this;this.promise=this.hasFabric().then(function(){return b.isInline(a)?Promise.resolve(b.inlineFormatting(a)):e(a)}).then(function(a){return new Promise(function(c){window.html2canvas.svg.fabric.loadSVGFromString(a,b.createCanvas.call(b,c))})})}var e=a("./xhr"),f=a("./utils").decode64;d.prototype.hasFabric=function(){return window.html2canvas.svg&&window.html2canvas.svg.fabric?Promise.resolve():Promise.reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"))},d.prototype.inlineFormatting=function(a){return/^data:image\/svg\+xml;base64,/.test(a)?this.decode64(this.removeContentType(a)):this.removeContentType(a)},d.prototype.removeContentType=function(a){return a.replace(/^data:image\/svg\+xml(;base64)?,/,"")},d.prototype.isInline=function(a){return/^data:image\/svg\+xml/i.test(a)},d.prototype.createCanvas=function(a){var b=this;return function(c,d){var e=new window.html2canvas.svg.fabric.StaticCanvas("c");b.image=e.lowerCanvasEl,e.setWidth(d.width).setHeight(d.height).add(window.html2canvas.svg.fabric.util.groupSVGElements(c,d)).renderAll(),a(e.lowerCanvasEl)}},d.prototype.decode64=function(a){return"function"==typeof window.atob?window.atob(a):f(a)},b.exports=d},{"./utils":26,"./xhr":28}],24:[function(a,b,c){function d(a,b){this.src=a,this.image=null;var c=this;this.promise=b?new Promise(function(b,d){c.image=new Image,c.image.onload=b,c.image.onerror=d,c.image.src="data:image/svg+xml,"+(new XMLSerializer).serializeToString(a),c.image.complete===!0&&b(c.image)}):this.hasFabric().then(function(){return new Promise(function(b){window.html2canvas.svg.fabric.parseSVGDocument(a,c.createCanvas.call(c,b))})})}var e=a("./svgcontainer");d.prototype=Object.create(e.prototype),b.exports=d},{"./svgcontainer":23}],25:[function(a,b,c){function d(a,b){f.call(this,a,b)}function e(a,b,c){if(a.length>0)return b+c.toUpperCase()}var f=a("./nodecontainer");d.prototype=Object.create(f.prototype),d.prototype.applyTextTransform=function(){this.node.data=this.transform(this.parent.css("textTransform"))},d.prototype.transform=function(a){var b=this.node.data;switch(a){case"lowercase":return b.toLowerCase();case"capitalize":return b.replace(/(^|\s|:|-|\(|\))([a-z])/g,e);case"uppercase":return b.toUpperCase();default:return b}},b.exports=d},{"./nodecontainer":14}],26:[function(a,b,c){c.smallImage=function(){return"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"},c.bind=function(a,b){return function(){return a.apply(b,arguments)}},c.decode64=function(a){var b,c,d,e,f,g,h,i,j="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",k=a.length,l="";for(b=0;b<k;b+=4)c=j.indexOf(a[b]),d=j.indexOf(a[b+1]),e=j.indexOf(a[b+2]),f=j.indexOf(a[b+3]),g=c<<2|d>>4,h=(15&d)<<4|e>>2,i=(3&e)<<6|f,l+=64===e?String.fromCharCode(g):64===f||f===-1?String.fromCharCode(g,h):String.fromCharCode(g,h,i);return l},c.getBounds=function(a){if(a.getBoundingClientRect){var b=a.getBoundingClientRect(),c=null==a.offsetWidth?b.width:a.offsetWidth;return{top:b.top,bottom:b.bottom||b.top+b.height,right:b.left+c,left:b.left,width:c,height:null==a.offsetHeight?b.height:a.offsetHeight}}return{}},c.offsetBounds=function(a){var b=a.offsetParent?c.offsetBounds(a.offsetParent):{top:0,left:0};return{top:a.offsetTop+b.top,bottom:a.offsetTop+a.offsetHeight+b.top,right:a.offsetLeft+b.left+a.offsetWidth,left:a.offsetLeft+b.left,width:a.offsetWidth,height:a.offsetHeight}},c.parseBackgrounds=function(a){var b,c,d,e,f,g,h,i=" \r\n\t",j=[],k=0,l=0,m=function(){b&&('"'===c.substr(0,1)&&(c=c.substr(1,c.length-2)),c&&h.push(c),"-"===b.substr(0,1)&&(e=b.indexOf("-",1)+1)>0&&(d=b.substr(0,e),b=b.substr(e)),j.push({prefix:d,method:b.toLowerCase(),value:f,args:h,image:null})),h=[],b=d=c=f=""};return h=[],b=d=c=f="",a.split("").forEach(function(a){if(!(0===k&&i.indexOf(a)>-1)){switch(a){case'"':g?g===a&&(g=null):g=a;break;case"(":if(g)break;if(0===k)return k=1,void(f+=a);l++;break;case")":if(g)break;if(1===k){if(0===l)return k=0,f+=a,void m();l--}break;case",":if(g)break;if(0===k)return void m();if(1===k&&0===l&&!b.match(/^url$/i))return h.push(c),c="",void(f+=a)}f+=a,0===k?b+=a:c+=a}}),m(),j}},{}],27:[function(a,b,c){function d(a){e.apply(this,arguments),this.type="linear"===a.args[0]?e.TYPES.LINEAR:e.TYPES.RADIAL}var e=a("./gradientcontainer");d.prototype=Object.create(e.prototype),b.exports=d},{"./gradientcontainer":9}],28:[function(a,b,c){function d(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.open("GET",a),d.onload=function(){200===d.status?b(d.responseText):c(new Error(d.statusText))},d.onerror=function(){
c(new Error("Network Error"))},d.send()})}b.exports=d},{}]},{},[4])(4)});
force-app/main/default/staticresources/html2canvas.resource-meta.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Public</cacheControl>
    <contentType>text/javascript</contentType>
    <description>html2canvas</description>
</StaticResource>
force-app/main/default/staticresources/jspdf.js
New file
@@ -0,0 +1,171 @@
/**
 * jsPDF - PDF Document creation from JavaScript
 * Version 1.0.272-git Built on 2014-09-29T15:09
 *                           CommitID d4770725ca
 *
 * Copyright (c) 2010-2014 James Hall, https://github.com/MrRio/jsPDF
 *               2010 Aaron Spike, https://github.com/acspike
 *               2012 Willow Systems Corporation, willow-systems.com
 *               2012 Pablo Hess, https://github.com/pablohess
 *               2012 Florian Jenett, https://github.com/fjenett
 *               2013 Warren Weckesser, https://github.com/warrenweckesser
 *               2013 Youssef Beddad, https://github.com/lifof
 *               2013 Lee Driscoll, https://github.com/lsdriscoll
 *               2013 Stefan Slonevskiy, https://github.com/stefslon
 *               2013 Jeremy Morel, https://github.com/jmorel
 *               2013 Christoph Hartmann, https://github.com/chris-rock
 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
 *               2014 James Makes, https://github.com/dollaruw
 *               2014 Diego Casorran, https://github.com/diegocr
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * Contributor(s):
 *    siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
 *    kim3er, mfo, alnorth,
 */
/**
 * jsPDF addHTML PlugIn
 * Copyright (c) 2014 Diego Casorran
 * Licensed under the MIT License.
 * http://opensource.org/licenses/mit-license
 */
/**
 * jsPDF addImage plugin
 * Copyright (c) 2012 Jason Siefken, https://github.com/siefkenj/
 *               2013 Chris Dowling, https://github.com/gingerchris
 *               2013 Trinh Ho, https://github.com/ineedfat
 *               2013 Edwin Alejandro Perez, https://github.com/eaparango
 *               2013 Norah Smith, https://github.com/burnburnrocket
 *               2014 Diego Casorran, https://github.com/diegocr
 *               2014 James Robb, https://github.com/jamesbrobb
 */
/**
 * jsPDF Cell plugin
 * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
 *               2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
 *               2013 Lee Driscoll, https://github.com/lsdriscoll
 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
 *               2014 James Hall, james@parall.ax
 *               2014 Diego Casorran, https://github.com/diegocr
 */
/**
 * jsPDF fromHTML plugin. BETA stage. API subject to change. Needs browser
 * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
 *               2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
 *               2014 Diego Casorran, https://github.com/diegocr
 *               2014 Daniel Husar, https://github.com/danielhusar
 *               2014 Wolfgang Gassler, https://github.com/woolfg
 */
/**
 * jsPDF JavaScript plugin
 * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
 */
/**
 * jsPDF PNG PlugIn
 * Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
 */
/**
jsPDF Silly SVG plugin
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
*/
/**
 * jsPDF split_text_to_size plugin - MIT license.
 * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
 *               2014 Diego Casorran, https://github.com/diegocr
 */
/**
jsPDF standard_fonts_metrics plugin
Copyright (c) 2012 Willow Systems Corporation, willow-systems.com
MIT license.
*/
/**
 * jsPDF total_pages plugin
 * Copyright (c) 2013 Eduardo Menezes de Morais, eduardo.morais@usp.br
 */
/* Blob.js
 * A Blob implementation.
 * 2014-07-24
 * By Eli Grey, http://eligrey.com
 * By Devin Samarin, https://github.com/dsamarin
 * License: X11/MIT
 *   See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
 */
/* FileSaver.js
 * A saveAs() FileSaver implementation.
 * 2014-08-29
 * By Eli Grey, http://eligrey.com
 * License: X11/MIT
 *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
 */
/*
 * Copyright (c) 2012 chick307 <chick307@gmail.com>
 * Licensed under the MIT License.
 * http://opensource.org/licenses/mit-license
 */
/*
 Deflate.js - https://github.com/gildas-lormeau/zip.js
 Copyright (c) 2013 Gildas Lormeau. All rights reserved.
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
 1. Redistributions of source code must retain the above copyright notice,
 this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in
 the documentation and/or other materials provided with the distribution.
 3. The names of the authors may not be used to endorse or promote products
 derived from this software without specific prior written permission.
 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
/*
# PNG.js
# Copyright (c) 2011 Devon Govett
# MIT LICENSE
#
*/
/*
 * Extracted from pdf.js
 * https://github.com/andreasgal/pdf.js
 * Copyright (c) 2011 Mozilla Foundation
 * Contributors: Andreas Gal <gal@mozilla.com>
 *               Chris G Jones <cjones@mozilla.com>
 *               Shaon Barman <shaon.barman@gmail.com>
 *               Vivien Nicolas <21@vingtetun.org>
 *               Justin D'Arcangelo <justindarc@gmail.com>
 *               Yury Delendik
 */
/**
 * JavaScript Polyfill functions for jsPDF
 * Collected from public resources by
 * https://github.com/diegocr
 */
!function(t,e){e["true"]=t;var n=function(t){"use strict";function e(e){var n={};this.subscribe=function(t,e,r){if("function"!=typeof e)return!1;n.hasOwnProperty(t)||(n[t]={});var s=Math.random().toString(35);return n[t][s]=[e,!!r],s},this.unsubscribe=function(t){for(var e in n)if(n[e][t])return delete n[e][t],!0;return!1},this.publish=function(r){if(n.hasOwnProperty(r)){var s=Array.prototype.slice.call(arguments,1),i=[];for(var o in n[r]){var a=n[r][o];try{a[0].apply(e,s)}catch(u){t.console&&console.error("jsPDF PubSub Error",u.message,u)}a[1]&&i.push(o)}i.length&&i.forEach(this.unsubscribe)}}}function n(a,u,c,l){var f={};"object"==typeof a&&(f=a,a=f.orientation,u=f.unit||u,c=f.format||c,l=f.compress||f.compressPdf||l),u=u||"mm",c=c||"a4",a=(""+(a||"P")).toLowerCase();var d,h,p,m,w,g,y,v,b,q=((""+c).toLowerCase(),!!l&&"function"==typeof Uint8Array),x=f.textColor||"0 g",k=f.drawColor||"0 G",_=f.fontSize||16,A=f.lineHeight||1.15,C=f.lineWidth||.200025,S=2,E=!1,z=[],T={},I={},B=0,O=[],P={},R=[],F=0,D=0,U=0,N={title:"",subject:"",author:"",keywords:"",creator:""},L={},j=new e(L),M=function(t){return t.toFixed(2)},H=function(t){return t.toFixed(3)},G=function(t){return("0"+parseInt(t)).slice(-2)},W=function(t){E?O[m].push(t):(U+=t.length+1,R.push(t))},V=function(){return S++,z[S]=U,W(S+" 0 obj"),S},J=function(t){W("stream"),W(t),W("endstream")},X=function(){var e,r,i,o,a,u,c,l,f;for(c=t.adler32cs||n.adler32cs,q&&"undefined"==typeof c&&(q=!1),e=1;B>=e;e++){if(V(),l=(w=P[e].width)*h,f=(g=P[e].height)*h,W("<</Type /Page"),W("/Parent 1 0 R"),W("/Resources 2 0 R"),W("/MediaBox [0 0 "+M(l)+" "+M(f)+"]"),W("/Contents "+(S+1)+" 0 R>>"),W("endobj"),r=O[e].join("\n"),V(),q){for(i=[],o=r.length;o--;)i[o]=r.charCodeAt(o);u=c.from(r),a=new s(6),a.append(new Uint8Array(i)),r=a.flush(),i=new Uint8Array(r.length+6),i.set(new Uint8Array([120,156])),i.set(r,2),i.set(new Uint8Array([255&u,u>>8&255,u>>16&255,u>>24&255]),r.length+2),r=String.fromCharCode.apply(null,i),W("<</Length "+r.length+" /Filter [/FlateDecode]>>")}else W("<</Length "+r.length+">>");J(r),W("endobj")}z[1]=U,W("1 0 obj"),W("<</Type /Pages");var d="/Kids [";for(o=0;B>o;o++)d+=3+2*o+" 0 R ";W(d+"]"),W("/Count "+B),W(">>"),W("endobj")},Y=function(t){t.objectNumber=V(),W("<</BaseFont/"+t.PostScriptName+"/Type/Font"),"string"==typeof t.encoding&&W("/Encoding/"+t.encoding),W("/Subtype/Type1>>"),W("endobj")},K=function(){for(var t in T)T.hasOwnProperty(t)&&Y(T[t])},Q=function(){j.publish("putXobjectDict")},$=function(){W("/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"),W("/Font <<");for(var t in T)T.hasOwnProperty(t)&&W("/"+t+" "+T[t].objectNumber+" 0 R");W(">>"),W("/XObject <<"),Q(),W(">>")},Z=function(){K(),j.publish("putResources"),z[2]=U,W("2 0 obj"),W("<<"),$(),W(">>"),W("endobj"),j.publish("postPutResources")},te=function(t,e,n){I.hasOwnProperty(e)||(I[e]={}),I[e][n]=t},ee=function(t,e,n,r){var s="F"+(Object.keys(T).length+1).toString(10),i=T[s]={id:s,PostScriptName:t,fontName:e,fontStyle:n,encoding:r,metadata:{}};return te(s,e,n),j.publish("addFont",i),s},ne=function(){for(var t="helvetica",e="times",n="courier",r="normal",s="bold",i="italic",o="bolditalic",a="StandardEncoding",u=[["Helvetica",t,r],["Helvetica-Bold",t,s],["Helvetica-Oblique",t,i],["Helvetica-BoldOblique",t,o],["Courier",n,r],["Courier-Bold",n,s],["Courier-Oblique",n,i],["Courier-BoldOblique",n,o],["Times-Roman",e,r],["Times-Bold",e,s],["Times-Italic",e,i],["Times-BoldItalic",e,o]],c=0,l=u.length;l>c;c++){var f=ee(u[c][0],u[c][1],u[c][2],a),d=u[c][0].split("-");te(f,d[0],d[1]||"")}j.publish("addFonts",{fonts:T,dictionary:I})},re=function(e){return e.foo=function(){try{return e.apply(this,arguments)}catch(n){var r=n.stack||"";~r.indexOf(" at ")&&(r=r.split(" at ")[1]);var s="Error in function "+r.split("\n")[0].split("<")[0]+": "+n.message;if(!t.console)throw new Error(s);t.console.error(s,n),t.alert&&alert(s)}},e.foo.bar=e,e.foo},se=function(t,e){var n,r,s,i,o,a,u,c,l;if(e=e||{},s=e.sourceEncoding||"Unicode",o=e.outputEncoding,(e.autoencode||o)&&T[d].metadata&&T[d].metadata[s]&&T[d].metadata[s].encoding&&(i=T[d].metadata[s].encoding,!o&&T[d].encoding&&(o=T[d].encoding),!o&&i.codePages&&(o=i.codePages[0]),"string"==typeof o&&(o=i[o]),o)){for(u=!1,a=[],n=0,r=t.length;r>n;n++)c=o[t.charCodeAt(n)],a.push(c?String.fromCharCode(c):t[n]),a[n].charCodeAt(0)>>8&&(u=!0);t=a.join("")}for(n=t.length;void 0===u&&0!==n;)t.charCodeAt(n-1)>>8&&(u=!0),n--;if(!u)return t;for(a=e.noBOM?[]:[254,255],n=0,r=t.length;r>n;n++){if(c=t.charCodeAt(n),l=c>>8,l>>8)throw new Error("Character at position "+n+" of string '"+t+"' exceeds 16bits. Cannot be encoded into UCS-2 BE");a.push(l),a.push(c-(l<<8))}return String.fromCharCode.apply(void 0,a)},ie=function(t,e){return se(t,e).replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")},oe=function(){W("/Producer (jsPDF "+n.version+")");for(var t in N)N.hasOwnProperty(t)&&N[t]&&W("/"+t.substr(0,1).toUpperCase()+t.substr(1)+" ("+ie(N[t])+")");var e=new Date,r=e.getTimezoneOffset(),s=0>r?"+":"-",i=Math.floor(Math.abs(r/60)),o=Math.abs(r%60),a=[s,G(i),"'",G(o),"'"].join("");W(["/CreationDate (D:",e.getFullYear(),G(e.getMonth()+1),G(e.getDate()),G(e.getHours()),G(e.getMinutes()),G(e.getSeconds()),a,")"].join(""))},ae=function(){switch(W("/Type /Catalog"),W("/Pages 1 0 R"),v||(v="fullwidth"),v){case"fullwidth":W("/OpenAction [3 0 R /FitH null]");break;case"fullheight":W("/OpenAction [3 0 R /FitV null]");break;case"fullpage":W("/OpenAction [3 0 R /Fit]");break;case"original":W("/OpenAction [3 0 R /XYZ null null 1]");break;default:var t=""+v;"%"===t.substr(t.length-1)&&(v=parseInt(v)/100),"number"==typeof v&&W("/OpenAction [3 0 R /XYZ null null "+M(v)+"]")}switch(b||(b="continuous"),b){case"continuous":W("/PageLayout /OneColumn");break;case"single":W("/PageLayout /SinglePage");break;case"two":case"twoleft":W("/PageLayout /TwoColumnLeft");break;case"tworight":W("/PageLayout /TwoColumnRight")}y&&W("/PageMode /"+y),j.publish("putCatalog")},ue=function(){W("/Size "+(S+1)),W("/Root "+S+" 0 R"),W("/Info "+(S-1)+" 0 R")},ce=function(t,e){var n="string"==typeof e&&e.toLowerCase();if("string"==typeof t){var r=t.toLowerCase();o.hasOwnProperty(r)&&(t=o[r][0]/h,e=o[r][1]/h)}if(Array.isArray(t)&&(e=t[1],t=t[0]),n){switch(n.substr(0,1)){case"l":e>t&&(n="s");break;case"p":t>e&&(n="s")}"s"===n&&(p=t,t=e,e=p)}E=!0,O[++B]=[],P[B]={width:Number(t)||w,height:Number(e)||g},fe(B)},le=function(){ce.apply(this,arguments),W(M(C*h)+" w"),W(k),0!==F&&W(F+" J"),0!==D&&W(D+" j"),j.publish("addPage",{pageNumber:B})},fe=function(t){t>0&&B>=t&&(m=t,w=P[t].width,g=P[t].height)},de=function(t,e){var n;t=void 0!==t?t:T[d].fontName,e=void 0!==e?e:T[d].fontStyle;try{n=I[t][e]}catch(r){}if(!n)throw new Error("Unable to look up font label for font '"+t+"', '"+e+"'. Refer to getFontList() for available fonts.");return n},he=function(){E=!1,S=2,R=[],z=[],W("%PDF-"+i),X(),Z(),V(),W("<<"),oe(),W(">>"),W("endobj"),V(),W("<<"),ae(),W(">>"),W("endobj");var t,e=U,n="0000000000";for(W("xref"),W("0 "+(S+1)),W(n+" 65535 f "),t=1;S>=t;t++)W((n+z[t]).slice(-10)+" 00000 n ");return W("trailer"),W("<<"),ue(),W(">>"),W("startxref"),W(e),W("%%EOF"),E=!0,R.join("\n")},pe=function(t){var e="S";return"F"===t?e="f":"FD"===t||"DF"===t?e="B":("f"===t||"f*"===t||"B"===t||"B*"===t)&&(e=t),e},me=function(){for(var t=he(),e=t.length,n=new ArrayBuffer(e),r=new Uint8Array(n);e--;)r[e]=t.charCodeAt(e);return n},we=function(){return new Blob([me()],{type:"application/pdf"})},ge=re(function(e,n){var s="dataur"===(""+e).substr(0,6)?"data:application/pdf;base64,"+btoa(he()):0;switch(e){case void 0:return he();case"save":if(navigator.getUserMedia&&(void 0===t.URL||void 0===t.URL.createObjectURL))return L.output("dataurlnewwindow");r(we(),n),"function"==typeof r.unload&&t.setTimeout&&setTimeout(r.unload,911);break;case"arraybuffer":return me();case"blob":return we();case"bloburi":case"bloburl":return t.URL&&t.URL.createObjectURL(we())||void 0;case"datauristring":case"dataurlstring":return s;case"dataurlnewwindow":var i=t.open(s);if(i||"undefined"==typeof safari)return i;case"datauri":case"dataurl":return t.document.location.href=s;default:throw new Error('Output type "'+e+'" is not supported.')}});switch(u){case"pt":h=1;break;case"mm":h=72/25.4;break;case"cm":h=72/2.54;break;case"in":h=72;break;case"px":h=96/72;break;case"pc":h=12;break;case"em":h=12;break;case"ex":h=6;break;default:throw"Invalid unit: "+u}L.internal={pdfEscape:ie,getStyle:pe,getFont:function(){return T[de.apply(L,arguments)]},getFontSize:function(){return _},getLineHeight:function(){return _*A},write:function(t){W(1===arguments.length?t:Array.prototype.join.call(arguments," "))},getCoordinateString:function(t){return M(t*h)},getVerticalCoordinateString:function(t){return M((g-t)*h)},collections:{},newObject:V,putStream:J,events:j,scaleFactor:h,pageSize:{get width(){return w},get height(){return g}},output:function(t,e){return ge(t,e)},getNumberOfPages:function(){return O.length-1},pages:O},L.addPage=function(){return le.apply(this,arguments),this},L.setPage=function(){return fe.apply(this,arguments),this},L.setDisplayMode=function(t,e,n){return v=t,b=e,y=n,this},L.text=function(t,e,n,r,s){function i(t){return t=t.split("    ").join(Array(f.TabLen||9).join(" ")),ie(t,r)}"number"==typeof t&&(p=n,n=e,e=t,t=p),"string"==typeof t&&t.match(/[\n\r]/)&&(t=t.split(/\r\n|\r|\n/g)),"number"==typeof r&&(s=r,r=null);var o,a="",u="Td";if(s){s*=Math.PI/180;var c=Math.cos(s),l=Math.sin(s);a=[M(c),M(l),M(-1*l),M(c),""].join(" "),u="Tm"}if(r=r||{},"noBOM"in r||(r.noBOM=!0),"autoencode"in r||(r.autoencode=!0),"string"==typeof t)t=i(t);else{if(!(t instanceof Array))throw new Error('Type of text must be string or Array. "'+t+'" is not recognized.');for(var m=t.concat(),w=[],y=m.length;y--;)w.push(i(m.shift()));var v=Math.ceil((g-n)*h/(_*A));v>=0&&v<w.length+1&&(o=w.splice(v-1)),t=w.join(") Tj\nT* (")}return W("BT\n/"+d+" "+_+" Tf\n"+_*A+" TL\n"+x+"\n"+a+M(e*h)+" "+M((g-n)*h)+" "+u+"\n("+t+") Tj\nET"),o&&(this.addPage(),this.text(o,e,1.7*_/h)),this},L.lstext=function(t,e,n,r){for(var s=0,i=t.length;i>s;s++,e+=r)this.text(t[s],e,n)},L.line=function(t,e,n,r){return this.lines([[n-t,r-e]],t,e)},L.clip=function(){W("W"),W("S")},L.lines=function(t,e,n,r,s,i){var o,a,u,c,l,f,d,m,w,y,v;for("number"==typeof t&&(p=n,n=e,e=t,t=p),r=r||[1,1],W(H(e*h)+" "+H((g-n)*h)+" m "),o=r[0],a=r[1],c=t.length,y=e,v=n,u=0;c>u;u++)l=t[u],2===l.length?(y=l[0]*o+y,v=l[1]*a+v,W(H(y*h)+" "+H((g-v)*h)+" l")):(f=l[0]*o+y,d=l[1]*a+v,m=l[2]*o+y,w=l[3]*a+v,y=l[4]*o+y,v=l[5]*a+v,W(H(f*h)+" "+H((g-d)*h)+" "+H(m*h)+" "+H((g-w)*h)+" "+H(y*h)+" "+H((g-v)*h)+" c"));return i&&W(" h"),null!==s&&W(pe(s)),this},L.rect=function(t,e,n,r,s){pe(s);return W([M(t*h),M((g-e)*h),M(n*h),M(-r*h),"re"].join(" ")),null!==s&&W(pe(s)),this},L.triangle=function(t,e,n,r,s,i,o){return this.lines([[n-t,r-e],[s-n,i-r],[t-s,e-i]],t,e,[1,1],o,!0),this},L.roundedRect=function(t,e,n,r,s,i,o){var a=4/3*(Math.SQRT2-1);return this.lines([[n-2*s,0],[s*a,0,s,i-i*a,s,i],[0,r-2*i],[0,i*a,-(s*a),i,-s,i],[-n+2*s,0],[-(s*a),0,-s,-(i*a),-s,-i],[0,-r+2*i],[0,-(i*a),s*a,-i,s,-i]],t+s,e,[1,1],o),this},L.ellipse=function(t,e,n,r,s){var i=4/3*(Math.SQRT2-1)*n,o=4/3*(Math.SQRT2-1)*r;return W([M((t+n)*h),M((g-e)*h),"m",M((t+n)*h),M((g-(e-o))*h),M((t+i)*h),M((g-(e-r))*h),M(t*h),M((g-(e-r))*h),"c"].join(" ")),W([M((t-i)*h),M((g-(e-r))*h),M((t-n)*h),M((g-(e-o))*h),M((t-n)*h),M((g-e)*h),"c"].join(" ")),W([M((t-n)*h),M((g-(e+o))*h),M((t-i)*h),M((g-(e+r))*h),M(t*h),M((g-(e+r))*h),"c"].join(" ")),W([M((t+i)*h),M((g-(e+r))*h),M((t+n)*h),M((g-(e+o))*h),M((t+n)*h),M((g-e)*h),"c"].join(" ")),null!==s&&W(pe(s)),this},L.circle=function(t,e,n,r){return this.ellipse(t,e,n,n,r)},L.setProperties=function(t){for(var e in N)N.hasOwnProperty(e)&&t[e]&&(N[e]=t[e]);return this},L.setFontSize=function(t){return _=t,this},L.setFont=function(t,e){return d=de(t,e),this},L.setFontStyle=L.setFontType=function(t){return d=de(void 0,t),this},L.getFontList=function(){var t,e,n,r={};for(t in I)if(I.hasOwnProperty(t)){r[t]=n=[];for(e in I[t])I[t].hasOwnProperty(e)&&n.push(e)}return r},L.setLineWidth=function(t){return W((t*h).toFixed(2)+" w"),this},L.setDrawColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" G":M(t/255)+" G":void 0===r?"string"==typeof t?[t,e,n,"RG"].join(" "):[M(t/255),M(e/255),M(n/255),"RG"].join(" "):"string"==typeof t?[t,e,n,r,"K"].join(" "):[M(t),M(e),M(n),M(r),"K"].join(" "),W(s),this},L.setFillColor=function(t,e,n,r){var s;return s=void 0===e||void 0===r&&t===e===n?"string"==typeof t?t+" g":M(t/255)+" g":void 0===r?"string"==typeof t?[t,e,n,"rg"].join(" "):[M(t/255),M(e/255),M(n/255),"rg"].join(" "):"string"==typeof t?[t,e,n,r,"k"].join(" "):[M(t),M(e),M(n),M(r),"k"].join(" "),W(s),this},L.setTextColor=function(t,e,n){if("string"==typeof t&&/^#[0-9A-Fa-f]{6}$/.test(t)){var r=parseInt(t.substr(1),16);t=r>>16&255,e=r>>8&255,n=255&r}return x=0===t&&0===e&&0===n||"undefined"==typeof e?H(t/255)+" g":[H(t/255),H(e/255),H(n/255),"rg"].join(" "),this},L.CapJoinStyles={0:0,butt:0,but:0,miter:0,1:1,round:1,rounded:1,circle:1,2:2,projecting:2,project:2,square:2,bevel:2},L.setLineCap=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line cap style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return F=e,W(e+" J"),this},L.setLineJoin=function(t){var e=this.CapJoinStyles[t];if(void 0===e)throw new Error("Line join style of '"+t+"' is not recognized. See or extend .CapJoinStyles property for valid styles");return D=e,W(e+" j"),this},L.output=ge,L.save=function(t){L.output("save",t)};for(var ye in n.API)n.API.hasOwnProperty(ye)&&("events"===ye&&n.API.events.length?!function(t,e){var n,r,s;for(s=e.length-1;-1!==s;s--)n=e[s][0],r=e[s][1],t.subscribe.apply(t,[n].concat("function"==typeof r?[r]:r))}(j,n.API.events):L[ye]=n.API[ye]);return ne(),d="F1",le(c,a),j.publish("initialized"),L}var i="1.3",o={a0:[2383.94,3370.39],a1:[1683.78,2383.94],a2:[1190.55,1683.78],a3:[841.89,1190.55],a4:[595.28,841.89],a5:[419.53,595.28],a6:[297.64,419.53],a7:[209.76,297.64],a8:[147.4,209.76],a9:[104.88,147.4],a10:[73.7,104.88],b0:[2834.65,4008.19],b1:[2004.09,2834.65],b2:[1417.32,2004.09],b3:[1000.63,1417.32],b4:[708.66,1000.63],b5:[498.9,708.66],b6:[354.33,498.9],b7:[249.45,354.33],b8:[175.75,249.45],b9:[124.72,175.75],b10:[87.87,124.72],c0:[2599.37,3676.54],c1:[1836.85,2599.37],c2:[1298.27,1836.85],c3:[918.43,1298.27],c4:[649.13,918.43],c5:[459.21,649.13],c6:[323.15,459.21],c7:[229.61,323.15],c8:[161.57,229.61],c9:[113.39,161.57],c10:[79.37,113.39],dl:[311.81,623.62],letter:[612,792],"government-letter":[576,756],legal:[612,1008],"junior-legal":[576,360],ledger:[1224,792],tabloid:[792,1224],"credit-card":[153,243]};return n.API={events:[]},n.version="1.0.272-git 2014-09-29T15:09:diegocr","function"==typeof define&&define.amd?define("jsPDF",function(){return n}):t.jsPDF=n,n}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this);!function(t){"use strict";t.addHTML=function(t,e,n,r,s){if("undefined"==typeof html2canvas&&"undefined"==typeof rasterizeHTML)throw new Error("You need either https://github.com/niklasvh/html2canvas or https://github.com/cburgmer/rasterizeHTML.js");"number"!=typeof e&&(r=e,s=n),"function"==typeof r&&(s=r,r=null);var i=this.internal,o=i.scaleFactor,a=i.pageSize.width,u=i.pageSize.height;if(r=r||{},r.onrendered=function(t){e=parseInt(e)||0,n=parseInt(n)||0;var i=r.dim||{},c=i.h||0,l=i.w||Math.min(a,t.width/o)-e,f="JPEG";if(r.format&&(f=r.format),t.height>u&&r.pagesplit){var d=function(){for(var r=0;;){var i=document.createElement("canvas");i.width=Math.min(a*o,t.width),i.height=Math.min(u*o,t.height-r);var c=i.getContext("2d");c.drawImage(t,0,r,t.width,i.height,0,0,i.width,i.height);var d=[i,e,r?0:n,i.width/o,i.height/o,f,null,"SLOW"];if(this.addImage.apply(this,d),r+=i.height,r>=t.height)break;this.addPage()}s(l,r,null,d)}.bind(this);if("CANVAS"===t.nodeName){var h=new Image;h.onload=d,h.src=t.toDataURL("image/png"),t=h}else d()}else{var p=Math.random().toString(35),m=[t,e,n,l,c,f,p,"SLOW"];this.addImage.apply(this,m),s(l,c,p,m)}}.bind(this),"undefined"!=typeof html2canvas&&!r.rstz)return html2canvas(t,r);if("undefined"!=typeof rasterizeHTML){var c="drawDocument";return"string"==typeof t&&(c=/^http/.test(t)?"drawURL":"drawHTML"),r.width=r.width||a*o,rasterizeHTML[c](t,void 0,r).then(function(t){r.onrendered(t.image)},function(t){s(null,t)})}return null}}(n.API),function(t){"use strict";var e="addImage_",n=["jpeg","jpg","png"],r=function(t){var e=this.internal.newObject(),n=this.internal.write,s=this.internal.putStream;if(t.n=e,n("<</Type /XObject"),n("/Subtype /Image"),n("/Width "+t.w),n("/Height "+t.h),t.cs===this.color_spaces.INDEXED?n("/ColorSpace [/Indexed /DeviceRGB "+(t.pal.length/3-1)+" "+("smask"in t?e+2:e+1)+" 0 R]"):(n("/ColorSpace /"+t.cs),t.cs===this.color_spaces.DEVICE_CMYK&&n("/Decode [1 0 1 0 1 0 1 0]")),n("/BitsPerComponent "+t.bpc),"f"in t&&n("/Filter /"+t.f),"dp"in t&&n("/DecodeParms <<"+t.dp+">>"),"trns"in t&&t.trns.constructor==Array){for(var i="",o=0,a=t.trns.length;a>o;o++)i+=t.trns[o]+" "+t.trns[o]+" ";n("/Mask ["+i+"]")}if("smask"in t&&n("/SMask "+(e+1)+" 0 R"),n("/Length "+t.data.length+">>"),s(t.data),n("endobj"),"smask"in t){var u="/Predictor 15 /Colors 1 /BitsPerComponent "+t.bpc+" /Columns "+t.w,c={w:t.w,h:t.h,cs:"DeviceGray",bpc:t.bpc,dp:u,data:t.smask};"f"in t&&(c.f=t.f),r.call(this,c)}t.cs===this.color_spaces.INDEXED&&(this.internal.newObject(),n("<< /Length "+t.pal.length+">>"),s(this.arrayBufferToBinaryString(new Uint8Array(t.pal))),n("endobj"))},s=function(){var t=this.internal.collections[e+"images"];for(var n in t)r.call(this,t[n])},i=function(){var t,n=this.internal.collections[e+"images"],r=this.internal.write;for(var s in n)t=n[s],r("/I"+t.i,t.n,"0","R")},o=function(e){return e&&"string"==typeof e&&(e=e.toUpperCase()),e in t.image_compression?e:t.image_compression.NONE},a=function(){var t=this.internal.collections[e+"images"];return t||(this.internal.collections[e+"images"]=t={},this.internal.events.subscribe("putResources",s),this.internal.events.subscribe("putXobjectDict",i)),t},u=function(t){var e=0;return t&&(e=Object.keys?Object.keys(t).length:function(t){var e=0;for(var n in t)t.hasOwnProperty(n)&&e++;return e}(t)),e},c=function(t){return"undefined"==typeof t||null===t},l=function(e){return"string"==typeof e&&t.sHashCode(e)},f=function(t){return-1===n.indexOf(t)},d=function(e){return"function"!=typeof t["process"+e.toUpperCase()]},h=function(t){return"object"==typeof t&&1===t.nodeType},p=function(t,e,n){if("IMG"===t.nodeName&&t.hasAttribute("src")){var r=""+t.getAttribute("src");if(!n&&0===r.indexOf("data:image/"))return r;!e&&/\.png(?:[?#].*)?$/i.test(r)&&(e="png")}if("CANVAS"===t.nodeName)var s=t;else{var s=document.createElement("canvas");s.width=t.clientWidth||t.width,s.height=t.clientHeight||t.height;var i=s.getContext("2d");if(!i)throw"addImage requires canvas to be supported by browser.";if(n){var o,a,u,c,l,f,d,h,p=Math.PI/180;"object"==typeof n&&(o=n.x,a=n.y,u=n.bg,n=n.angle),h=n*p,c=Math.abs(Math.cos(h)),l=Math.abs(Math.sin(h)),f=s.width,d=s.height,s.width=d*l+f*c,s.height=d*c+f*l,isNaN(o)&&(o=s.width/2),isNaN(a)&&(a=s.height/2),i.clearRect(0,0,s.width,s.height),i.fillStyle=u||"white",i.fillRect(0,0,s.width,s.height),i.save(),i.translate(o,a),i.rotate(h),i.drawImage(t,-(f/2),-(d/2)),i.rotate(-h),i.translate(-o,-a),i.restore()}else i.drawImage(t,0,0,s.width,s.height)}return s.toDataURL("png"==(""+e).toLowerCase()?"image/png":"image/jpeg")},m=function(t,e){var n;if(e)for(var r in e)if(t===e[r].alias){n=e[r];break}return n},w=function(t,e,n){return t||e||(t=-96,e=-96),0>t&&(t=-1*n.w*72/t/this.internal.scaleFactor),0>e&&(e=-1*n.h*72/e/this.internal.scaleFactor),0===t&&(t=e*n.w/n.h),0===e&&(e=t*n.h/n.w),[t,e]},g=function(t,e,n,r,s,i,o){var a=w.call(this,n,r,s),u=this.internal.getCoordinateString,c=this.internal.getVerticalCoordinateString;n=a[0],r=a[1],o[i]=s,this.internal.write("q",u(n),"0 0",u(r),u(t),c(e+r),"cm /I"+s.i,"Do Q")};t.color_spaces={DEVICE_RGB:"DeviceRGB",DEVICE_GRAY:"DeviceGray",DEVICE_CMYK:"DeviceCMYK",CAL_GREY:"CalGray",CAL_RGB:"CalRGB",LAB:"Lab",ICC_BASED:"ICCBased",INDEXED:"Indexed",PATTERN:"Pattern",SEPERATION:"Seperation",DEVICE_N:"DeviceN"},t.decode={DCT_DECODE:"DCTDecode",FLATE_DECODE:"FlateDecode",LZW_DECODE:"LZWDecode",JPX_DECODE:"JPXDecode",JBIG2_DECODE:"JBIG2Decode",ASCII85_DECODE:"ASCII85Decode",ASCII_HEX_DECODE:"ASCIIHexDecode",RUN_LENGTH_DECODE:"RunLengthDecode",CCITT_FAX_DECODE:"CCITTFaxDecode"},t.image_compression={NONE:"NONE",FAST:"FAST",MEDIUM:"MEDIUM",SLOW:"SLOW"},t.sHashCode=function(t){return Array.prototype.reduce&&t.split("").reduce(function(t,e){return t=(t<<5)-t+e.charCodeAt(0),t&t},0)},t.isString=function(t){return"string"==typeof t},t.extractInfoFromBase64DataURI=function(t){return/^data:([\w]+?\/([\w]+?));base64,(.+?)$/g.exec(t)},t.supportsArrayBuffer=function(){return"undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array},t.isArrayBuffer=function(t){return this.supportsArrayBuffer()?t instanceof ArrayBuffer:!1},t.isArrayBufferView=function(t){return this.supportsArrayBuffer()?"undefined"==typeof Uint32Array?!1:t instanceof Int8Array||t instanceof Uint8Array||"undefined"!=typeof Uint8ClampedArray&&t instanceof Uint8ClampedArray||t instanceof Int16Array||t instanceof Uint16Array||t instanceof Int32Array||t instanceof Uint32Array||t instanceof Float32Array||t instanceof Float64Array:!1},t.binaryStringToUint8Array=function(t){for(var e=t.length,n=new Uint8Array(e),r=0;e>r;r++)n[r]=t.charCodeAt(r);return n},t.arrayBufferToBinaryString=function(t){this.isArrayBuffer(t)&&(t=new Uint8Array(t));for(var e="",n=t.byteLength,r=0;n>r;r++)e+=String.fromCharCode(t[r]);return e},t.arrayBufferToBase64=function(t){for(var e,n,r,s,i,o="",a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=new Uint8Array(t),c=u.byteLength,l=c%3,f=c-l,d=0;f>d;d+=3)i=u[d]<<16|u[d+1]<<8|u[d+2],e=(16515072&i)>>18,n=(258048&i)>>12,r=(4032&i)>>6,s=63&i,o+=a[e]+a[n]+a[r]+a[s];return 1==l?(i=u[f],e=(252&i)>>2,n=(3&i)<<4,o+=a[e]+a[n]+"=="):2==l&&(i=u[f]<<8|u[f+1],e=(64512&i)>>10,n=(1008&i)>>4,r=(15&i)<<2,o+=a[e]+a[n]+a[r]+"="),o},t.createImageInfo=function(t,e,n,r,s,i,o,a,u,c,l,f){var d={alias:a,w:e,h:n,cs:r,bpc:s,i:o,data:t};return i&&(d.f=i),u&&(d.dp=u),c&&(d.trns=c),l&&(d.pal=l),f&&(d.smask=f),d},t.addImage=function(t,e,r,s,i,w,y,v,b){if("string"!=typeof e){var q=w;w=i,i=s,s=r,r=e,e=q}if("object"==typeof t&&!h(t)&&"imageData"in t){var x=t;t=x.imageData,e=x.format||e,r=x.x||r||0,s=x.y||s||0,i=x.w||i,w=x.h||w,y=x.alias||y,v=x.compression||v,b=x.rotation||x.angle||b}if(isNaN(r)||isNaN(s))throw console.error("jsPDF.addImage: Invalid coordinates",arguments),new Error("Invalid coordinates passed to jsPDF.addImage");var k,_=a.call(this);if(!(k=m(t,_))){var A;if(h(t)&&(t=p(t,e,b)),c(y)&&(y=l(t)),!(k=m(y,_))){if(this.isString(t)){var C=this.extractInfoFromBase64DataURI(t);C?(e=C[2],t=atob(C[3])):137===t.charCodeAt(0)&&80===t.charCodeAt(1)&&78===t.charCodeAt(2)&&71===t.charCodeAt(3)&&(e="png")}if(e=(e||"JPEG").toLowerCase(),f(e))throw new Error("addImage currently only supports formats "+n+", not '"+e+"'");if(d(e))throw new Error("please ensure that the plugin for '"+e+"' support is added");if(this.supportsArrayBuffer()&&(A=t,t=this.binaryStringToUint8Array(t)),k=this["process"+e.toUpperCase()](t,u(_),y,o(v),A),!k)throw new Error("An unkwown error occurred whilst processing the image")}}return g.call(this,r,s,i,w,k,k.i,_),this};var y=function(t){var e,n,r;if(255===!t.charCodeAt(0)||216===!t.charCodeAt(1)||255===!t.charCodeAt(2)||224===!t.charCodeAt(3)||!t.charCodeAt(6)==="J".charCodeAt(0)||!t.charCodeAt(7)==="F".charCodeAt(0)||!t.charCodeAt(8)==="I".charCodeAt(0)||!t.charCodeAt(9)==="F".charCodeAt(0)||0===!t.charCodeAt(10))throw new Error("getJpegSize requires a binary string jpeg file");for(var s=256*t.charCodeAt(4)+t.charCodeAt(5),i=4,o=t.length;o>i;){if(i+=s,255!==t.charCodeAt(i))throw new Error("getJpegSize could not find the size of the image");if(192===t.charCodeAt(i+1)||193===t.charCodeAt(i+1)||194===t.charCodeAt(i+1)||195===t.charCodeAt(i+1)||196===t.charCodeAt(i+1)||197===t.charCodeAt(i+1)||198===t.charCodeAt(i+1)||199===t.charCodeAt(i+1))return n=256*t.charCodeAt(i+5)+t.charCodeAt(i+6),e=256*t.charCodeAt(i+7)+t.charCodeAt(i+8),r=t.charCodeAt(i+9),[e,n,r];i+=2,s=256*t.charCodeAt(i)+t.charCodeAt(i+1)}},v=function(t){var e=t[0]<<8|t[1];if(65496!==e)throw new Error("Supplied data is not a JPEG");for(var n,r,s,i,o=t.length,a=(t[4]<<8)+t[5],u=4;o>u;){if(u+=a,n=b(t,u),a=(n[2]<<8)+n[3],(192===n[1]||194===n[1])&&255===n[0]&&a>7)return n=b(t,u+5),r=(n[2]<<8)+n[3],s=(n[0]<<8)+n[1],i=n[4],{width:r,height:s,numcomponents:i};u+=2}throw new Error("getJpegSizeFromBytes could not find the size of the image")},b=function(t,e){return t.subarray(e,e+5)};t.processJPEG=function(t,e,n,r,s){var i,o=this.color_spaces.DEVICE_RGB,a=this.decode.DCT_DECODE,u=8;return this.isString(t)?(i=y(t),this.createImageInfo(t,i[0],i[1],1==i[3]?this.color_spaces.DEVICE_GRAY:o,u,a,e,n)):(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)?(i=v(t),t=s||this.arrayBufferToBinaryString(t),this.createImageInfo(t,i.width,i.height,1==i.numcomponents?this.color_spaces.DEVICE_GRAY:o,u,a,e,n)):null)},t.processJPG=function(){return this.processJPEG.apply(this,arguments)}}(n.API),function(t){"use strict";t.autoPrint=function(){var t;return this.internal.events.subscribe("postPutResources",function(){t=this.internal.newObject(),this.internal.write("<< /S/Named /Type/Action /N/Print >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){this.internal.write("/OpenAction "+t+" 0 R")}),this}}(n.API),function(t){"use strict";var e,n,r,s,i=3,o=13,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,c=function(t,e,n,r,s){a={x:t,y:e,w:n,h:r,ln:s}},l=function(){return a},f={left:0,top:0,bottom:0};t.setHeaderFunction=function(t){s=t},t.getTextDimensions=function(t){e=this.internal.getFont().fontName,n=this.table_font_size||this.internal.getFontSize(),r=this.internal.getFont().fontStyle;var s,i,o=19.049976/25.4;return i=document.createElement("font"),i.id="jsPDFCell",i.style.fontStyle=r,i.style.fontName=e,i.style.fontSize=n+"pt",i.textContent=t,document.body.appendChild(i),s={w:(i.offsetWidth+1)*o,h:(i.offsetHeight+1)*o},document.body.removeChild(i),s},t.cellAddPage=function(){var t=this.margins||f;this.addPage(),c(t.left,t.top,void 0,void 0),u+=1},t.cellInitialize=function(){a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1},t.cell=function(t,e,n,r,s,a,u){var d=l();if(void 0!==d.ln)if(d.ln===a)t=d.x+d.w,e=d.y;else{var h=this.margins||f;d.y+d.h+r+o>=this.internal.pageSize.height-h.bottom&&(this.cellAddPage(),this.printHeaders&&this.tableHeaderRow&&this.printHeaderRow(a,!0)),e=l().y+l().h}if(void 0!==s[0])if(this.printingHeaderRow?this.rect(t,e,n,r,"FD"):this.rect(t,e,n,r),"right"===u){if(s instanceof Array)for(var p=0;p<s.length;p++){var m=s[p],w=this.getStringUnitWidth(m)*this.internal.getFontSize();this.text(m,t+n-w-i,e+this.internal.getLineHeight()*(p+1))}}else this.text(s,t+i,e+this.internal.getLineHeight());return c(t,e,n,r,a),this},t.arrayMax=function(t,e){var n,r,s,i=t[0];for(n=0,r=t.length;r>n;n+=1)s=t[n],e?-1===e(i,s)&&(i=s):s>i&&(i=s);return i},t.table=function(e,n,r,s,i){if(!r)throw"No data for PDF table";var o,c,l,d,h,p,m,w,g,y,v=[],b=[],q={},x={},k=[],_=[],A=!1,C=!0,S=12,E=f;if(E.width=this.internal.pageSize.width,i&&(i.autoSize===!0&&(A=!0),i.printHeaders===!1&&(C=!1),i.fontSize&&(S=i.fontSize),i.margins&&(E=i.margins)),this.lnMod=0,a={x:void 0,y:void 0,w:void 0,h:void 0,ln:void 0},u=1,this.printHeaders=C,this.margins=E,this.setFontSize(S),this.table_font_size=S,void 0===s||null===s)v=Object.keys(r[0]);else if(s[0]&&"string"!=typeof s[0]){var z=19.049976/25.4;for(c=0,l=s.length;l>c;c+=1)o=s[c],v.push(o.name),b.push(o.prompt),x[o.name]=o.width*z}else v=s;if(A)for(y=function(t){return t[o]},c=0,l=v.length;l>c;c+=1){for(o=v[c],q[o]=r.map(y),k.push(this.getTextDimensions(b[c]||o).w),p=q[o],m=0,d=p.length;d>m;m+=1)h=p[m],k.push(this.getTextDimensions(h).w);x[o]=t.arrayMax(k)}if(C){var T=this.calculateLineHeight(v,x,b.length?b:v);for(c=0,l=v.length;l>c;c+=1)o=v[c],_.push([e,n,x[o],T,String(b.length?b[c]:o)]);this.setTableHeaderRow(_),this.printHeaderRow(1,!1)}for(c=0,l=r.length;l>c;c+=1){var T;for(w=r[c],T=this.calculateLineHeight(v,x,w),m=0,g=v.length;g>m;m+=1)o=v[m],this.cell(e,n,x[o],T,w[o],c+2,o.align)}return this.lastCellPos=a,this.table_x=e,this.table_y=n,this},t.calculateLineHeight=function(t,e,n){for(var r,s=0,o=0;o<t.length;o++){r=t[o],n[r]=this.splitTextToSize(String(n[r]),e[r]-i);var a=this.internal.getLineHeight()*n[r].length+i;a>s&&(s=a)}return s},t.setTableHeaderRow=function(t){this.tableHeaderRow=t},t.printHeaderRow=function(t,e){if(!this.tableHeaderRow)throw"Property tableHeaderRow does not exist.";var n,r,i,o;if(this.printingHeaderRow=!0,void 0!==s){var a=s(this,u);c(a[0],a[1],a[2],a[3],-1)}this.setFontStyle("bold");var l=[];for(i=0,o=this.tableHeaderRow.length;o>i;i+=1)this.setFillColor(200,200,200),n=this.tableHeaderRow[i],e&&(n[1]=this.margins&&this.margins.top||0,l.push(n)),r=[].concat(n),this.cell.apply(this,r.concat(t));l.length>0&&this.setTableHeaderRow(l),this.setFontStyle("normal"),this.printingHeaderRow=!1}}(n.API),function(t){var e,n,r,s,i,o,a,u,c,l,f,d,h,p,m,w,g,y,v;e=function(){function t(){}return function(e){return t.prototype=e,new t}}(),c=function(t){var e,n,r,s,i,o,a;for(n=0,r=t.length,e=void 0,s=!1,o=!1;!s&&n!==r;)e=t[n]=t[n].trimLeft(),e&&(s=!0),n++;for(n=r-1;r&&!o&&-1!==n;)e=t[n]=t[n].trimRight(),e&&(o=!0),n--;for(i=/\s+$/g,a=!0,n=0;n!==r;)e=t[n].replace(/\s+/g," "),a&&(e=e.trimLeft()),e&&(a=i.test(e)),t[n]=e,n++;return t},l=function(t,e,n,r){return this.pdf=t,this.x=e,this.y=n,this.settings=r,this.watchFunctions=[],this.init(),this},f=function(t){var e,n,s;for(e=void 0,s=t.split(","),n=s.shift();!e&&n;)e=r[n.trim().toLowerCase()],n=s.shift();return e},d=function(t){t="auto"===t?"0px":t,t.indexOf("em")>-1&&!isNaN(Number(t.replace("em","")))&&(t=18.719*Number(t.replace("em",""))+"px"),t.indexOf("pt")>-1&&!isNaN(Number(t.replace("pt","")))&&(t=1.333*Number(t.replace("pt",""))+"px");var e,n,r;return n=void 0,e=16,(r=h[t])?r:(r={"xx-small":9,"x-small":11,small:13,medium:16,large:19,"x-large":23,"xx-large":28,auto:0}[{css_line_height_string:t}],r!==n?h[t]=r/e:(r=parseFloat(t))?h[t]=r/e:(r=t.match(/([\d\.]+)(px)/),h[t]=3===r.length?parseFloat(r[1])/e:1))},u=function(t){var e,n,r;return r=function(t){var e;return e=function(t){return document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(t,null):t.currentStyle?t.currentStyle:t.style}(t),function(t){return t=t.replace(/-\D/g,function(t){return t.charAt(1).toUpperCase()}),e[t]}}(t),e={},n=void 0,e["font-family"]=f(r("font-family"))||"times",e["font-style"]=s[r("font-style")]||"normal",e["text-align"]=TextAlignMap[r("text-align")]||"left",n=i[r("font-weight")]||"normal","bold"===n&&(e["font-style"]="normal"===e["font-style"]?n:n+e["font-style"]),e["font-size"]=d(r("font-size"))||1,e["line-height"]=d(r("line-height"))||1,e.display="inline"===r("display")?"inline":"block",n="block"===e.display,e["margin-top"]=n&&d(r("margin-top"))||0,e["margin-bottom"]=n&&d(r("margin-bottom"))||0,e["padding-top"]=n&&d(r("padding-top"))||0,e["padding-bottom"]=n&&d(r("padding-bottom"))||0,e["margin-left"]=n&&d(r("margin-left"))||0,e["margin-right"]=n&&d(r("margin-right"))||0,e["padding-left"]=n&&d(r("padding-left"))||0,e["padding-right"]=n&&d(r("padding-right"))||0,e["float"]=o[r("cssFloat")]||"none",e.clear=a[r("clear")]||"none",e},p=function(t,e,n){var r,s,i,o,a;if(i=!1,s=void 0,o=void 0,a=void 0,r=n["#"+t.id])if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;if(r=n[t.nodeName],!i&&r)if("function"==typeof r)i=r(t,e);else for(s=0,o=r.length;!i&&s!==o;)i=r[s](t,e),s++;return i},v=function(t,e){var n,r,s,i,o,a,u,c,l,f;
for(n=[],r=[],s=0,f=t.rows[0].cells.length,c=t.clientWidth;f>s;)l=t.rows[0].cells[s],r[s]={name:l.textContent.toLowerCase().replace(/\s+/g,""),prompt:l.textContent.replace(/\r?\n/g,""),width:l.clientWidth/c*e.pdf.internal.pageSize.width},s++;for(s=1;s<t.rows.length;){for(a=t.rows[s],o={},i=0;i<a.cells.length;)o[r[i].name]=a.cells[i].textContent.replace(/\r?\n/g,""),i++;n.push(o),s++}return u={rows:n,headers:r}};var b={SCRIPT:1,STYLE:1,NOSCRIPT:1,OBJECT:1,EMBED:1,SELECT:1},q=1;n=function(t,e,r){var s,i,o,a,c,l,f,d,h;for(i=t.childNodes,s=void 0,o=u(t),c="block"===o.display,c&&(e.setBlockBoundary(),e.setBlockStyle(o)),f=19.049976/25.4,a=0,l=i.length;l>a;){if(s=i[a],"object"==typeof s){if(e.executeWatchFunctions(s),1===s.nodeType&&"HEADER"===s.nodeName){var w=s,g=e.pdf.margins_doc.top;e.pdf.internal.events.subscribe("addPage",function(){e.y=g,n(w,e,r),e.pdf.margins_doc.top=e.y+10,e.y+=10},!1)}if(8===s.nodeType&&"#comment"===s.nodeName)~s.textContent.indexOf("ADD_PAGE")&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top);else if(1!==s.nodeType||b[s.nodeName])if(3===s.nodeType){var y=s.nodeValue;if(s.nodeValue&&"LI"===s.parentNode.nodeName)if("OL"===s.parentNode.parentNode.nodeName)y=q++ +". "+y;else{var x=16*o["font-size"],k=2;x>20&&(k=3),h=function(t,e){this.pdf.circle(t,e,k,"FD")}}e.addText(y,o)}else"string"==typeof s&&e.addText(s,o);else{var _;if("IMG"===s.nodeName){var A=s.getAttribute("src");_=m[e.pdf.sHashCode(A)||A]}if(_){e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottom<e.y+s.height&&e.y>e.pdf.margins_doc.top&&(e.pdf.addPage(),e.y=e.pdf.margins_doc.top,e.executeWatchFunctions(s));var C=u(s),S=e.x,E=12/e.pdf.internal.scaleFactor,z=(C["margin-left"]+C["padding-left"])*E,T=(C["margin-right"]+C["padding-right"])*E,I=(C["margin-top"]+C["padding-top"])*E,B=(C["margin-bottom"]+C["padding-bottom"])*E;S+=void 0!==C["float"]&&"right"===C["float"]?e.settings.width-s.width-T:z,e.pdf.addImage(_,S,e.y+I,s.width,s.height),_=void 0,"right"===C["float"]||"left"===C["float"]?(e.watchFunctions.push(function(t,n,r,s){return e.y>=n?(e.x+=t,e.settings.width+=r,!0):s&&1===s.nodeType&&!b[s.nodeName]&&e.x+s.width>e.pdf.margins_doc.left+e.pdf.margins_doc.width?(e.x+=t,e.y=n,e.settings.width+=r,!0):!1}.bind(this,"left"===C["float"]?-s.width-z-T:0,e.y+s.height+I+B,s.width)),e.watchFunctions.push(function(t,n,r){return e.y<t&&n===e.pdf.internal.getNumberOfPages()?1===r.nodeType&&"both"===u(r).clear?(e.y=t,!0):!1:!0}.bind(this,e.y+s.height,e.pdf.internal.getNumberOfPages())),e.settings.width-=s.width+z+T,"left"===C["float"]&&(e.x+=s.width+z+T)):e.y+=s.height+B}else if("TABLE"===s.nodeName)d=v(s,e),e.y+=10,e.pdf.table(e.x,e.y,d.rows,d.headers,{autoSize:!1,printHeaders:!0,margins:e.pdf.margins_doc}),e.y=e.pdf.lastCellPos.y+e.pdf.lastCellPos.h+20;else if("OL"===s.nodeName||"UL"===s.nodeName)q=1,p(s,e,r)||n(s,e,r),e.y+=10;else if("LI"===s.nodeName){var O=e.x;e.x+="UL"===s.parentNode.nodeName?22:10,e.y+=3,p(s,e,r)||n(s,e,r),e.x=O}else"BR"===s.nodeName?e.y+=o["font-size"]*e.pdf.internal.scaleFactor:p(s,e,r)||n(s,e,r)}}a++}return c?e.setBlockBoundary(h):void 0},m={},w=function(t,e,n,r){function s(){e.pdf.internal.events.publish("imagesLoaded"),r(o)}function i(t,n,r){if(t){var i=new Image;o=++c,i.crossOrigin="",i.onerror=i.onload=function(){if(i.complete&&(0===i.src.indexOf("data:image/")&&(i.width=n||i.width||0,i.height=r||i.height||0),i.width+i.height)){var o=e.pdf.sHashCode(t)||t;m[o]=m[o]||i}--c||s()},i.src=t}}for(var o,a=t.getElementsByTagName("img"),u=a.length,c=0;u--;)i(a[u].getAttribute("src"),a[u].width,a[u].height);return c||s()},g=function(t,e,r){var s=t.getElementsByTagName("footer");if(s.length>0){s=s[0];var i=e.pdf.internal.write,o=e.y;e.pdf.internal.write=function(){},n(s,e,r);var a=Math.ceil(e.y-o)+5;e.y=o,e.pdf.internal.write=i,e.pdf.margins_doc.bottom+=a;for(var u=function(t){var i=void 0!==t?t.pageNumber:1,o=e.y;e.y=e.pdf.internal.pageSize.height-e.pdf.margins_doc.bottom,e.pdf.margins_doc.bottom-=a;for(var u=s.getElementsByTagName("span"),c=0;c<u.length;++c)(" "+u[c].className+" ").replace(/[\n\t]/g," ").indexOf(" pageCounter ")>-1&&(u[c].innerHTML=i),(" "+u[c].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&(u[c].innerHTML="###jsPDFVarTotalPages###");n(s,e,r),e.pdf.margins_doc.bottom+=a,e.y=o},c=s.getElementsByTagName("span"),l=0;l<c.length;++l)(" "+c[l].className+" ").replace(/[\n\t]/g," ").indexOf(" totalPages ")>-1&&e.pdf.internal.events.subscribe("htmlRenderingFinished",e.pdf.putTotalPages.bind(e.pdf,"###jsPDFVarTotalPages###"),!0);e.pdf.internal.events.subscribe("addPage",u,!1),u(),b.FOOTER=1}},y=function(t,e,r,s,i,o){if(!e)return!1;"string"==typeof e||e.parentNode||(e=""+e.innerHTML),"string"==typeof e&&(e=function(t){var e,n,r,s;return r="jsPDFhtmlText"+Date.now().toString()+(1e3*Math.random()).toFixed(0),s="position: absolute !important;clip: rect(1px 1px 1px 1px); /* IE6, IE7 */clip: rect(1px, 1px, 1px, 1px);padding:0 !important;border:0 !important;height: 1px !important;width: 1px !important; top:auto;left:-100px;overflow: hidden;",n=document.createElement("div"),n.style.cssText=s,n.innerHTML='<iframe style="height:1px;width:1px" name="'+r+'" />',document.body.appendChild(n),e=window.frames[r],e.document.body.innerHTML=t,e.document.body}(e.replace(/<\/?script[^>]*?>/gi,"")));var a,u=new l(t,r,s,i);return w.call(this,e,u,i.elementHandlers,function(t){g(e,u,i.elementHandlers),n(e,u,i.elementHandlers),u.pdf.internal.events.publish("htmlRenderingFinished"),a=u.dispose(),"function"==typeof o?o(a):t&&console.error("jsPDF Warning: rendering issues? provide a callback to fromHTML!")}),a||{x:u.x,y:u.y}},l.prototype.init=function(){return this.paragraph={text:[],style:[]},this.pdf.internal.write("q")},l.prototype.dispose=function(){return this.pdf.internal.write("Q"),{x:this.x,y:this.y,ready:!0}},l.prototype.executeWatchFunctions=function(t){var e=!1,n=[];if(this.watchFunctions.length>0){for(var r=0;r<this.watchFunctions.length;++r)this.watchFunctions[r](t)===!0?e=!0:n.push(this.watchFunctions[r]);this.watchFunctions=n}return e},l.prototype.splitFragmentsIntoLines=function(t,n){var r,s,i,o,a,u,c,l,f,d,h,p,m,w,g;for(s=12,h=this.pdf.internal.scaleFactor,a={},i=void 0,d=void 0,o=void 0,u=void 0,g=void 0,f=void 0,l=void 0,c=void 0,p=[],m=[p],r=0,w=this.settings.width;t.length;)if(u=t.shift(),g=n.shift(),u)if(i=g["font-family"],d=g["font-style"],o=a[i+d],o||(o=this.pdf.internal.getFont(i,d).metadata.Unicode,a[i+d]=o),f={widths:o.widths,kerning:o.kerning,fontSize:g["font-size"]*s,textIndent:r},l=this.pdf.getStringUnitWidth(u,f)*f.fontSize/h,r+l>w){for(c=this.pdf.splitTextToSize(u,w,f),p.push([c.shift(),g]);c.length;)p=[[c.shift(),g]],m.push(p);r=this.pdf.getStringUnitWidth(p[0][0],f)*f.fontSize/h}else p.push([u,g]),r+=l;if(void 0!==g["text-align"]&&("center"===g["text-align"]||"right"===g["text-align"]||"justify"===g["text-align"]))for(var y=0;y<m.length;++y){var v=this.pdf.getStringUnitWidth(m[y][0][0],f)*f.fontSize/h;y>0&&(m[y][0][1]=e(m[y][0][1]));var b=w-v;if("right"===g["text-align"])m[y][0][1]["margin-left"]=b;else if("center"===g["text-align"])m[y][0][1]["margin-left"]=b/2;else if("justify"===g["text-align"]){var q=m[y][0][0].split(" ").length-1;m[y][0][1]["word-spacing"]=b/q,y===m.length-1&&(m[y][0][1]["word-spacing"]=0)}}return m},l.prototype.RenderTextFragment=function(t,e){var n,r,s;s=0,n=12,this.pdf.internal.pageSize.height-this.pdf.margins_doc.bottom<this.y+this.pdf.internal.getFontSize()&&(this.pdf.internal.write("ET","Q"),this.pdf.addPage(),this.y=this.pdf.margins_doc.top,this.pdf.internal.write("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td"),s=Math.max(s,e["line-height"],e["font-size"]),this.pdf.internal.write(0,(-1*n*s).toFixed(2),"Td")),r=this.pdf.internal.getFont(e["font-family"],e["font-style"]),void 0!==e["word-spacing"]&&e["word-spacing"]>0&&this.pdf.internal.write(e["word-spacing"].toFixed(2),"Tw"),this.pdf.internal.write("/"+r.id,(n*e["font-size"]).toFixed(2),"Tf","("+this.pdf.internal.pdfEscape(t)+") Tj"),void 0!==e["word-spacing"]&&this.pdf.internal.write(0,"Tw")},l.prototype.renderParagraph=function(t){var e,n,r,s,i,o,a,u,l,f,d,h,p,m,w;if(s=c(this.paragraph.text),m=this.paragraph.style,e=this.paragraph.blockstyle,p=this.paragraph.blockstyle||{},this.paragraph={text:[],style:[],blockstyle:{},priorblockstyle:e},s.join("").trim()){u=this.splitFragmentsIntoLines(s,m),a=void 0,l=void 0,n=12,r=n/this.pdf.internal.scaleFactor,h=(Math.max((e["margin-top"]||0)-(p["margin-bottom"]||0),0)+(e["padding-top"]||0))*r,d=((e["margin-bottom"]||0)+(e["padding-bottom"]||0))*r,f=this.pdf.internal.write,i=void 0,o=void 0,this.y+=h,f("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td");for(var g=0;u.length;){for(a=u.shift(),l=0,i=0,o=a.length;i!==o;)a[i][0].trim()&&(l=Math.max(l,a[i][1]["line-height"],a[i][1]["font-size"]),w=7*a[i][1]["font-size"]),i++;var y=0;for(void 0!==a[0][1]["margin-left"]&&a[0][1]["margin-left"]>0&&(wantedIndent=this.pdf.internal.getCoordinateString(a[0][1]["margin-left"]),y=wantedIndent-g,g=wantedIndent),f(y,(-1*n*l).toFixed(2),"Td"),i=0,o=a.length;i!==o;)a[i][0]&&this.RenderTextFragment(a[i][0],a[i][1]),i++;if(this.y+=l*r,this.executeWatchFunctions(a[0][1])&&u.length>0){var v=[],b=[];u.forEach(function(t){for(var e=0,n=t.length;e!==n;)t[e][0]&&(v.push(t[e][0]+" "),b.push(t[e][1])),++e}),u=this.splitFragmentsIntoLines(c(v),b),f("ET","Q"),f("q","BT 0 g",this.pdf.internal.getCoordinateString(this.x),this.pdf.internal.getVerticalCoordinateString(this.y),"Td")}}return t&&"function"==typeof t&&t.call(this,this.x-9,this.y-w/2),f("ET","Q"),this.y+=d}},l.prototype.setBlockBoundary=function(t){return this.renderParagraph(t)},l.prototype.setBlockStyle=function(t){return this.paragraph.blockstyle=t},l.prototype.addText=function(t,e){return this.paragraph.text.push(t),this.paragraph.style.push(e)},r={helvetica:"helvetica","sans-serif":"helvetica","times new roman":"times",serif:"times",times:"times",monospace:"courier",courier:"courier"},i={100:"normal",200:"normal",300:"normal",400:"normal",500:"bold",600:"bold",700:"bold",800:"bold",900:"bold",normal:"normal",bold:"bold",bolder:"bold",lighter:"normal"},s={normal:"normal",italic:"italic",oblique:"italic"},TextAlignMap={left:"left",right:"right",center:"center",justify:"justify"},o={none:"none",right:"right",left:"left"},a={none:"none",both:"both"},h={normal:1},t.fromHTML=function(t,e,n,r,s,i){"use strict";return this.margins_doc=i||{top:0,bottom:0},r||(r={}),r.elementHandlers||(r.elementHandlers={}),y(this,t,isNaN(e)?4:e,isNaN(n)?4:n,r,s)}}(n.API),function(t){"use strict";var e,n,r;t.addJS=function(t){return r=t,this.internal.events.subscribe("postPutResources",function(){e=this.internal.newObject(),this.internal.write("<< /Names [(EmbeddedJS) "+(e+1)+" 0 R] >>","endobj"),n=this.internal.newObject(),this.internal.write("<< /S /JavaScript /JS (",r,") >>","endobj")}),this.internal.events.subscribe("putCatalog",function(){void 0!==e&&void 0!==n&&this.internal.write("/Names <</JavaScript "+e+" 0 R>>")}),this}}(n.API),function(t){"use strict";var e=function(){return"function"!=typeof PNG||"function"!=typeof o},n=function(e){return e!==t.image_compression.NONE&&r()},r=function(){var t="function"==typeof s;if(!t)throw new Error("requires deflate.js for compression");return t},i=function(e,n,r,i){var o=5,l=d;switch(i){case t.image_compression.FAST:o=3,l=f;break;case t.image_compression.MEDIUM:o=6,l=h;break;case t.image_compression.SLOW:o=9,l=p}e=c(e,n,r,l);var m=new Uint8Array(a(o)),w=u(e),g=new s(o),y=g.append(e),v=g.flush(),b=m.length+y.length+v.length,q=new Uint8Array(b+4);return q.set(m),q.set(y,m.length),q.set(v,m.length+y.length),q[b++]=w>>>24&255,q[b++]=w>>>16&255,q[b++]=w>>>8&255,q[b++]=255&w,t.arrayBufferToBinaryString(q)},a=function(t,e){var n=8,r=Math.LOG2E*Math.log(32768)-8,s=r<<4|n,i=s<<8,o=Math.min(3,(e-1&255)>>1);return i|=o<<6,i|=0,i+=31-i%31,[s,255&i&255]},u=function(t,e){for(var n,r=1,s=65535&r,i=r>>>16&65535,o=t.length,a=0;o>0;){n=o>e?e:o,o-=n;do s+=t[a++],i+=s;while(--n);s%=65521,i%=65521}return(i<<16|s)>>>0},c=function(t,e,n,r){for(var s,i,o,a=t.length/e,u=new Uint8Array(t.length+a),c=w(),l=0;a>l;l++){if(o=l*e,s=t.subarray(o,o+e),r)u.set(r(s,n,i),o+l);else{for(var f=0,d=c.length,h=[];d>f;f++)h[f]=c[f](s,n,i);var p=g(h.concat());u.set(h[p],o+l)}i=s}return u},l=function(t){var e=Array.apply([],t);return e.unshift(0),e},f=function(t,e){var n,r=[],s=0,i=t.length;for(r[0]=1;i>s;s++)n=t[s-e]||0,r[s+1]=t[s]-n+256&255;return r},d=function(t,e,n){var r,s=[],i=0,o=t.length;for(s[0]=2;o>i;i++)r=n&&n[i]||0,s[i+1]=t[i]-r+256&255;return s},h=function(t,e,n){var r,s,i=[],o=0,a=t.length;for(i[0]=3;a>o;o++)r=t[o-e]||0,s=n&&n[o]||0,i[o+1]=t[o]+256-(r+s>>>1)&255;return i},p=function(t,e,n){var r,s,i,o,a=[],u=0,c=t.length;for(a[0]=4;c>u;u++)r=t[u-e]||0,s=n&&n[u]||0,i=n&&n[u-e]||0,o=m(r,s,i),a[u+1]=t[u]-o+256&255;return a},m=function(t,e,n){var r=t+e-n,s=Math.abs(r-t),i=Math.abs(r-e),o=Math.abs(r-n);return i>=s&&o>=s?t:o>=i?e:n},w=function(){return[l,f,d,h,p]},g=function(t){for(var e,n,r,s=0,i=t.length;i>s;)e=y(t[s].slice(1)),(n>e||!n)&&(n=e,r=s),s++;return r},y=function(t){for(var e=0,n=t.length,r=0;n>e;)r+=Math.abs(t[e++]);return r};t.processPNG=function(t,r,s,o){var a,u,c,l,f,d,h=this.color_spaces.DEVICE_RGB,p=this.decode.FLATE_DECODE,m=8;if(this.isArrayBuffer(t)&&(t=new Uint8Array(t)),this.isArrayBufferView(t)){if(e())throw new Error("PNG support requires png.js and zlib.js");if(a=new PNG(t),t=a.imgData,m=a.bits,h=a.colorSpace,l=a.colors,-1!==[4,6].indexOf(a.colorType)){if(8===a.bits)for(var w,g,y=window["Uint"+a.pixelBitlength+"Array"],v=new y(a.decodePixels().buffer),b=v.length,q=new Uint8Array(b*a.colors),x=new Uint8Array(b),k=a.pixelBitlength-a.bits,_=0,A=0;b>_;_++){for(w=v[_],g=0;k>g;)q[A++]=w>>>g&255,g+=a.bits;x[_]=w>>>g&255}if(16===a.bits){for(var w,v=new Uint32Array(a.decodePixels().buffer),b=v.length,q=new Uint8Array(b*(32/a.pixelBitlength)*a.colors),x=new Uint8Array(b*(32/a.pixelBitlength)),C=a.colors>1,_=0,A=0,S=0;b>_;)w=v[_++],q[A++]=w>>>0&255,C&&(q[A++]=w>>>16&255,w=v[_++],q[A++]=w>>>0&255),x[S++]=w>>>16&255;m=8}n(o)?(t=i(q,a.width*a.colors,a.colors,o),d=i(x,a.width,1,o)):(t=q,d=x,p=null)}if(3===a.colorType&&(h=this.color_spaces.INDEXED,f=a.palette,a.transparency.indexed)){for(var E=a.transparency.indexed,z=0,_=0,b=E.length;b>_;++_)z+=E[_];if(z/=255,z===b-1&&-1!==E.indexOf(0))c=[E.indexOf(0)];else if(z!==b){for(var v=a.decodePixels(),x=new Uint8Array(v.length),_=0,b=v.length;b>_;_++)x[_]=E[v[_]];d=i(x,a.width,1)}}return u=p===this.decode.FLATE_DECODE?"/Predictor 15 /Colors "+l+" /BitsPerComponent "+m+" /Columns "+a.width:"/Colors "+l+" /BitsPerComponent "+m+" /Columns "+a.width,(this.isArrayBuffer(t)||this.isArrayBufferView(t))&&(t=this.arrayBufferToBinaryString(t)),(d&&this.isArrayBuffer(d)||this.isArrayBufferView(d))&&(d=this.arrayBufferToBinaryString(d)),this.createImageInfo(t,a.width,a.height,h,m,p,r,s,u,c,f,d)}throw new Error("Unsupported PNG image data, try using JPEG instead.")}}(n.API),function(t){"use strict";t.addSVG=function(t,e,n,r,s){function i(t,e){var n=e.createElement("style");n.type="text/css",n.styleSheet?n.styleSheet.cssText=t:n.appendChild(e.createTextNode(t)),e.getElementsByTagName("head")[0].appendChild(n)}function o(t){var e="childframe",n=t.createElement("iframe");return i(".jsPDF_sillysvg_iframe {display:none;position:absolute;}",t),n.name=e,n.setAttribute("width",0),n.setAttribute("height",0),n.setAttribute("frameborder","0"),n.setAttribute("scrolling","no"),n.setAttribute("seamless","seamless"),n.setAttribute("class","jsPDF_sillysvg_iframe"),t.body.appendChild(n),n}function a(t,e){var n=(e.contentWindow||e.contentDocument).document;return n.write(t),n.close(),n.getElementsByTagName("svg")[0]}function u(t){for(var e=parseFloat(t[1]),n=parseFloat(t[2]),r=[],s=3,i=t.length;i>s;)"c"===t[s]?(r.push([parseFloat(t[s+1]),parseFloat(t[s+2]),parseFloat(t[s+3]),parseFloat(t[s+4]),parseFloat(t[s+5]),parseFloat(t[s+6])]),s+=7):"l"===t[s]?(r.push([parseFloat(t[s+1]),parseFloat(t[s+2])]),s+=3):s+=1;return[e,n,r]}var c;if(e===c||n===c)throw new Error("addSVG needs values for 'x' and 'y'");var l=o(document),f=a(t,l),d=[1,1],h=parseFloat(f.getAttribute("width")),p=parseFloat(f.getAttribute("height"));h&&p&&(r&&s?d=[r/h,s/p]:r?d=[r/h,r/h]:s&&(d=[s/p,s/p]));var m,w,g,y,v=f.childNodes;for(m=0,w=v.length;w>m;m++)g=v[m],g.tagName&&"PATH"===g.tagName.toUpperCase()&&(y=u(g.getAttribute("d").split(" ")),y[0]=y[0]*d[0]+e,y[1]=y[1]*d[1]+n,this.lines.call(this,y[2],y[0],y[1],d));return this}}(n.API),function(t){"use strict";var e=t.getCharWidthsArray=function(t,e){e||(e={});var n,r,s,i=e.widths?e.widths:this.internal.getFont().metadata.Unicode.widths,o=i.fof?i.fof:1,a=e.kerning?e.kerning:this.internal.getFont().metadata.Unicode.kerning,u=a.fof?a.fof:1,c=0,l=i[0]||o,f=[];for(n=0,r=t.length;r>n;n++)s=t.charCodeAt(n),f.push((i[s]||l)/o+(a[s]&&a[s][c]||0)/u),c=s;return f},n=function(t){for(var e=t.length,n=0;e;)e--,n+=t[e];return n},r=t.getStringUnitWidth=function(t,r){return n(e.call(this,t,r))},s=function(t,e,n,r){for(var s=[],i=0,o=t.length,a=0;i!==o&&a+e[i]<n;)a+=e[i],i++;s.push(t.slice(0,i));var u=i;for(a=0;i!==o;)a+e[i]>r&&(s.push(t.slice(u,i)),a=0,u=i),a+=e[i],i++;return u!==i&&s.push(t.slice(u,i)),s},i=function(t,i,o){o||(o={});var a,u,c,l,f,d,h=[],p=[h],m=o.textIndent||0,w=0,g=0,y=t.split(" "),v=e(" ",o)[0];if(d=-1===o.lineIndent?y[0].length+2:o.lineIndent||0){var b=Array(d).join(" "),q=[];y.map(function(t){t=t.split(/\s*\n/),t.length>1?q=q.concat(t.map(function(t,e){return(e&&t.length?"\n":"")+t})):q.push(t[0])}),y=q,d=r(b,o)}for(c=0,l=y.length;l>c;c++){var x=0;if(a=y[c],d&&"\n"==a[0]&&(a=a.substr(1),x=1),u=e(a,o),g=n(u),m+w+g>i||x){if(g>i){for(f=s(a,u,i-(m+w),i),h.push(f.shift()),h=[f.pop()];f.length;)p.push([f.shift()]);g=n(u.slice(a.length-h[0].length))}else h=[a];p.push(h),m=g+d,w=v}else h.push(a),m+=w+g,w=v}if(d)var k=function(t,e){return(e?b:"")+t.join(" ")};else var k=function(t){return t.join(" ")};return p.map(k)};t.splitTextToSize=function(t,e,n){n||(n={});var r,s=n.fontSize||this.internal.getFontSize(),o=function(t){var e={0:1},n={};if(t.widths&&t.kerning)return{widths:t.widths,kerning:t.kerning};var r=this.internal.getFont(t.fontName,t.fontStyle),s="Unicode";return r.metadata[s]?{widths:r.metadata[s].widths||e,kerning:r.metadata[s].kerning||n}:{widths:e,kerning:n}}.call(this,n);r=Array.isArray(t)?t:t.split(/\r?\n/);var a=1*this.internal.scaleFactor*e/s;o.textIndent=n.textIndent?1*n.textIndent*this.internal.scaleFactor/s:0,o.lineIndent=n.lineIndent;var u,c,l=[];for(u=0,c=r.length;c>u;u++)l=l.concat(i(r[u],a,o));return l}}(n.API),function(t){"use strict";var e=function(t){for(var e="0123456789abcdef",n="klmnopqrstuvwxyz",r={},s=0;s<n.length;s++)r[n[s]]=e[s];var i,o,a,u,c,l={},f=1,d=l,h=[],p="",m="",w=t.length-1;for(s=1;s!=w;)c=t[s],s+=1,"'"==c?o?(u=o.join(""),o=i):o=[]:o?o.push(c):"{"==c?(h.push([d,u]),d={},u=i):"}"==c?(a=h.pop(),a[0][a[1]]=d,u=i,d=a[0]):"-"==c?f=-1:u===i?r.hasOwnProperty(c)?(p+=r[c],u=parseInt(p,16)*f,f=1,p=""):p+=c:r.hasOwnProperty(c)?(m+=r[c],d[u]=parseInt(m,16)*f,f=1,u=i,m=""):m+=c;return l},n={codePages:["WinAnsiEncoding"],WinAnsiEncoding:e("{19m8n201n9q201o9r201s9l201t9m201u8m201w9n201x9o201y8o202k8q202l8r202m9p202q8p20aw8k203k8t203t8v203u9v2cq8s212m9t15m8w15n9w2dw9s16k8u16l9u17s9z17x8y17y9y}")},r={Unicode:{Courier:n,"Courier-Bold":n,"Courier-BoldOblique":n,"Courier-Oblique":n,Helvetica:n,"Helvetica-Bold":n,"Helvetica-BoldOblique":n,"Helvetica-Oblique":n,"Times-Roman":n,"Times-Bold":n,"Times-BoldItalic":n,"Times-Italic":n}},s={Unicode:{"Courier-Oblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-BoldItalic":e("{'widths'{k3o2q4ycx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2r202m2n2n3m2o3m2p5n202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5n4l4m4m4m4n4m4o4s4p4m4q4m4r4s4s4y4t2r4u3m4v4m4w3x4x5t4y4s4z4s5k3x5l4s5m4m5n3r5o3x5p4s5q4m5r5t5s4m5t3x5u3x5v2l5w1w5x2l5y3t5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q2l6r3m6s3r6t1w6u1w6v3m6w1w6x4y6y3r6z3m7k3m7l3m7m2r7n2r7o1w7p3r7q2w7r4m7s3m7t2w7u2r7v2n7w1q7x2n7y3t202l3mcl4mal2ram3man3mao3map3mar3mas2lat4uau1uav3maw3way4uaz2lbk2sbl3t'fof'6obo2lbp3tbq3mbr1tbs2lbu1ybv3mbz3mck4m202k3mcm4mcn4mco4mcp4mcq5ycr4mcs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz2w203k6o212m6o2dw2l2cq2l3t3m3u2l17s3x19m3m}'kerning'{cl{4qu5kt5qt5rs17ss5ts}201s{201ss}201t{cks4lscmscnscoscpscls2wu2yu201ts}201x{2wu2yu}2k{201ts}2w{4qx5kx5ou5qx5rs17su5tu}2x{17su5tu5ou}2y{4qx5kx5ou5qx5rs17ss5ts}'fof'-6ofn{17sw5tw5ou5qw5rs}7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qs}3v{17su5tu5os5qs}7p{17su5tu}ck{4qu5kt5qt5rs17ss5ts}4l{4qu5kt5qt5rs17ss5ts}cm{4qu5kt5qt5rs17ss5ts}cn{4qu5kt5qt5rs17ss5ts}co{4qu5kt5qt5rs17ss5ts}cp{4qu5kt5qt5rs17ss5ts}6l{4qu5ou5qw5rt17su5tu}5q{ckuclucmucnucoucpu4lu}5r{ckuclucmucnucoucpu4lu}7q{cksclscmscnscoscps4ls}6p{4qu5ou5qw5rt17sw5tw}ek{4qu5ou5qw5rt17su5tu}el{4qu5ou5qw5rt17su5tu}em{4qu5ou5qw5rt17su5tu}en{4qu5ou5qw5rt17su5tu}eo{4qu5ou5qw5rt17su5tu}ep{4qu5ou5qw5rt17su5tu}es{17ss5ts5qs4qu}et{4qu5ou5qw5rt17sw5tw}eu{4qu5ou5qw5rt17ss5ts}ev{17ss5ts5qs4qu}6z{17sw5tw5ou5qw5rs}fm{17sw5tw5ou5qw5rs}7n{201ts}fo{17sw5tw5ou5qw5rs}fp{17sw5tw5ou5qw5rs}fq{17sw5tw5ou5qw5rs}7r{cksclscmscnscoscps4ls}fs{17sw5tw5ou5qw5rs}ft{17su5tu}fu{17su5tu}fv{17su5tu}fw{17su5tu}fz{cksclscmscnscoscps4ls}}}"),"Helvetica-Bold":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),Courier:e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Courier-BoldOblique":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Bold":e("{'widths'{k3q2q5ncx2r201n3m201o6o201s2l201t2l201u2l201w3m201x3m201y3m2k1t2l2l202m2n2n3m2o3m2p6o202q6o2r1w2s2l2t2l2u3m2v3t2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w3t3x3t3y3t3z3m4k5x4l4s4m4m4n4s4o4s4p4m4q3x4r4y4s4y4t2r4u3m4v4y4w4m4x5y4y4s4z4y5k3x5l4y5m4s5n3r5o4m5p4s5q4s5r6o5s4s5t4s5u4m5v2l5w1w5x2l5y3u5z3m6k2l6l3m6m3r6n2w6o3r6p2w6q2l6r3m6s3r6t1w6u2l6v3r6w1w6x5n6y3r6z3m7k3r7l3r7m2w7n2r7o2l7p3r7q3m7r4s7s3m7t3m7u2w7v2r7w1q7x2r7y3o202l3mcl4sal2lam3man3mao3map3mar3mas2lat4uau1yav3maw3tay4uaz2lbk2sbl3t'fof'6obo2lbp3rbr1tbs2lbu2lbv3mbz3mck4s202k3mcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw2r2m3rcy2rcz2rdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3rek3mel3mem3men3meo3mep3meq4ser2wes2wet2weu2wev2wew1wex1wey1wez1wfl3rfm3mfn3mfo3mfp3mfq3mfr3tfs3mft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3m3u2l17s4s19m3m}'kerning'{cl{4qt5ks5ot5qy5rw17sv5tv}201t{cks4lscmscnscoscpscls4wv}2k{201ts}2w{4qu5ku7mu5os5qx5ru17su5tu}2x{17su5tu5ou5qs}2y{4qv5kv7mu5ot5qz5ru17su5tu}'fof'-6o7t{cksclscmscnscoscps4ls}3u{17su5tu5os5qu}3v{17su5tu5os5qu}fu{17su5tu5ou5qu}7p{17su5tu5ou5qu}ck{4qt5ks5ot5qy5rw17sv5tv}4l{4qt5ks5ot5qy5rw17sv5tv}cm{4qt5ks5ot5qy5rw17sv5tv}cn{4qt5ks5ot5qy5rw17sv5tv}co{4qt5ks5ot5qy5rw17sv5tv}cp{4qt5ks5ot5qy5rw17sv5tv}6l{17st5tt5ou5qu}17s{ckuclucmucnucoucpu4lu4wu}5o{ckuclucmucnucoucpu4lu4wu}5q{ckzclzcmzcnzcozcpz4lz4wu}5r{ckxclxcmxcnxcoxcpx4lx4wu}5t{ckuclucmucnucoucpu4lu4wu}7q{ckuclucmucnucoucpu4lu}6p{17sw5tw5ou5qu}ek{17st5tt5qu}el{17st5tt5ou5qu}em{17st5tt5qu}en{17st5tt5qu}eo{17st5tt5qu}ep{17st5tt5ou5qu}es{17ss5ts5qu}et{17sw5tw5ou5qu}eu{17sw5tw5ou5qu}ev{17ss5ts5qu}6z{17sw5tw5ou5qu5rs}fm{17sw5tw5ou5qu5rs}fn{17sw5tw5ou5qu5rs}fo{17sw5tw5ou5qu5rs}fp{17sw5tw5ou5qu5rs}fq{17sw5tw5ou5qu5rs}7r{cktcltcmtcntcotcpt4lt5os}fs{17sw5tw5ou5qu5rs}ft{17su5tu5ou5qu}7m{5os}fv{17su5tu5ou5qu}fw{17su5tu5ou5qu}fz{cksclscmscnscoscps4ls}}}"),Helvetica:e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}"),"Helvetica-BoldOblique":e("{'widths'{k3s2q4scx1w201n3r201o6o201s1w201t1w201u1w201w3m201x3m201y3m2k1w2l2l202m2n2n3r2o3r2p5t202q6o2r1s2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v2l3w3u3x3u3y3u3z3x4k6l4l4s4m4s4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3r4v4s4w3x4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v2l5w1w5x2l5y3u5z3r6k2l6l3r6m3x6n3r6o3x6p3r6q2l6r3x6s3x6t1w6u1w6v3r6w1w6x5t6y3x6z3x7k3x7l3x7m2r7n3r7o2l7p3x7q3r7r4y7s3r7t3r7u3m7v2r7w1w7x2r7y3u202l3rcl4sal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3xbq3rbr1wbs2lbu2obv3rbz3xck4s202k3rcm4scn4sco4scp4scq6ocr4scs4mct4mcu4mcv4mcw1w2m2zcy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3res3ret3reu3rev3rew1wex1wey1wez1wfl3xfm3xfn3xfo3xfp3xfq3xfr3ufs3xft3xfu3xfv3xfw3xfz3r203k6o212m6o2dw2l2cq2l3t3r3u2l17s4m19m3r}'kerning'{cl{4qs5ku5ot5qs17sv5tv}201t{2ww4wy2yw}201w{2ks}201x{2ww4wy2yw}2k{201ts201xs}2w{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}2x{5ow5qs}2y{7qs4qu5kw5os5qw5rs17su5tu7tsfzs}'fof'-6o7p{17su5tu5ot}ck{4qs5ku5ot5qs17sv5tv}4l{4qs5ku5ot5qs17sv5tv}cm{4qs5ku5ot5qs17sv5tv}cn{4qs5ku5ot5qs17sv5tv}co{4qs5ku5ot5qs17sv5tv}cp{4qs5ku5ot5qs17sv5tv}6l{17st5tt5os}17s{2kwclvcmvcnvcovcpv4lv4wwckv}5o{2kucltcmtcntcotcpt4lt4wtckt}5q{2ksclscmscnscoscps4ls4wvcks}5r{2ks4ws}5t{2kwclvcmvcnvcovcpv4lv4wwckv}eo{17st5tt5os}fu{17su5tu5ot}6p{17ss5ts}ek{17st5tt5os}el{17st5tt5os}em{17st5tt5os}en{17st5tt5os}6o{201ts}ep{17st5tt5os}es{17ss5ts}et{17ss5ts}eu{17ss5ts}ev{17ss5ts}6z{17su5tu5os5qt}fm{17su5tu5os5qt}fn{17su5tu5os5qt}fo{17su5tu5os5qt}fp{17su5tu5os5qt}fq{17su5tu5os5qt}fs{17su5tu5os5qt}ft{17su5tu5ot}7m{5os}fv{17su5tu5ot}fw{17su5tu5ot}}}"),"Courier-Bold":e("{'widths'{k3w'fof'6o}'kerning'{'fof'-6o}}"),"Times-Italic":e("{'widths'{k3n2q4ycx2l201n3m201o5t201s2l201t2l201u2l201w3r201x3r201y3r2k1t2l2l202m2n2n3m2o3m2p5n202q5t2r1p2s2l2t2l2u3m2v4n2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v2l3w4n3x4n3y4n3z3m4k5w4l3x4m3x4n4m4o4s4p3x4q3x4r4s4s4s4t2l4u2w4v4m4w3r4x5n4y4m4z4s5k3x5l4s5m3x5n3m5o3r5p4s5q3x5r5n5s3x5t3r5u3r5v2r5w1w5x2r5y2u5z3m6k2l6l3m6m3m6n2w6o3m6p2w6q1w6r3m6s3m6t1w6u1w6v2w6w1w6x4s6y3m6z3m7k3m7l3m7m2r7n2r7o1w7p3m7q2w7r4m7s2w7t2w7u2r7v2s7w1v7x2s7y3q202l3mcl3xal2ram3man3mao3map3mar3mas2lat4wau1vav3maw4nay4waz2lbk2sbl4n'fof'6obo2lbp3mbq3obr1tbs2lbu1zbv3mbz3mck3x202k3mcm3xcn3xco3xcp3xcq5tcr4mcs3xct3xcu3xcv3xcw2l2m2ucy2lcz2ldl4mdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek3mel3mem3men3meo3mep3meq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr4nfs3mft3mfu3mfv3mfw3mfz2w203k6o212m6m2dw2l2cq2l3t3m3u2l17s3r19m3m}'kerning'{cl{5kt4qw}201s{201sw}201t{201tw2wy2yy6q-t}201x{2wy2yy}2k{201tw}2w{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}2x{17ss5ts5os}2y{7qs4qy7rs5ky7mw5os5qx5ru17su5tu}'fof'-6o6t{17ss5ts5qs}7t{5os}3v{5qs}7p{17su5tu5qs}ck{5kt4qw}4l{5kt4qw}cm{5kt4qw}cn{5kt4qw}co{5kt4qw}cp{5kt4qw}6l{4qs5ks5ou5qw5ru17su5tu}17s{2ks}5q{ckvclvcmvcnvcovcpv4lv}5r{ckuclucmucnucoucpu4lu}5t{2ks}6p{4qs5ks5ou5qw5ru17su5tu}ek{4qs5ks5ou5qw5ru17su5tu}el{4qs5ks5ou5qw5ru17su5tu}em{4qs5ks5ou5qw5ru17su5tu}en{4qs5ks5ou5qw5ru17su5tu}eo{4qs5ks5ou5qw5ru17su5tu}ep{4qs5ks5ou5qw5ru17su5tu}es{5ks5qs4qs}et{4qs5ks5ou5qw5ru17su5tu}eu{4qs5ks5qw5ru17su5tu}ev{5ks5qs4qs}ex{17ss5ts5qs}6z{4qv5ks5ou5qw5ru17su5tu}fm{4qv5ks5ou5qw5ru17su5tu}fn{4qv5ks5ou5qw5ru17su5tu}fo{4qv5ks5ou5qw5ru17su5tu}fp{4qv5ks5ou5qw5ru17su5tu}fq{4qv5ks5ou5qw5ru17su5tu}7r{5os}fs{4qv5ks5ou5qw5ru17su5tu}ft{17su5tu5qs}fu{17su5tu5qs}fv{17su5tu5qs}fw{17su5tu5qs}}}"),"Times-Roman":e("{'widths'{k3n2q4ycx2l201n3m201o6o201s2l201t2l201u2l201w2w201x2w201y2w2k1t2l2l202m2n2n3m2o3m2p5n202q6o2r1m2s2l2t2l2u3m2v3s2w1t2x2l2y1t2z1w3k3m3l3m3m3m3n3m3o3m3p3m3q3m3r3m3s3m203t2l203u2l3v1w3w3s3x3s3y3s3z2w4k5w4l4s4m4m4n4m4o4s4p3x4q3r4r4s4s4s4t2l4u2r4v4s4w3x4x5t4y4s4z4s5k3r5l4s5m4m5n3r5o3x5p4s5q4s5r5y5s4s5t4s5u3x5v2l5w1w5x2l5y2z5z3m6k2l6l2w6m3m6n2w6o3m6p2w6q2l6r3m6s3m6t1w6u1w6v3m6w1w6x4y6y3m6z3m7k3m7l3m7m2l7n2r7o1w7p3m7q3m7r4s7s3m7t3m7u2w7v3k7w1o7x3k7y3q202l3mcl4sal2lam3man3mao3map3mar3mas2lat4wau1vav3maw3say4waz2lbk2sbl3s'fof'6obo2lbp3mbq2xbr1tbs2lbu1zbv3mbz2wck4s202k3mcm4scn4sco4scp4scq5tcr4mcs3xct3xcu3xcv3xcw2l2m2tcy2lcz2ldl4sdm4sdn4sdo4sdp4sdq4sds4sdt4sdu4sdv4sdw4sdz3mek2wel2wem2wen2weo2wep2weq4mer2wes2wet2weu2wev2wew1wex1wey1wez1wfl3mfm3mfn3mfo3mfp3mfq3mfr3sfs3mft3mfu3mfv3mfw3mfz3m203k6o212m6m2dw2l2cq2l3t3m3u1w17s4s19m3m}'kerning'{cl{4qs5ku17sw5ou5qy5rw201ss5tw201ws}201s{201ss}201t{ckw4lwcmwcnwcowcpwclw4wu201ts}2k{201ts}2w{4qs5kw5os5qx5ru17sx5tx}2x{17sw5tw5ou5qu}2y{4qs5kw5os5qx5ru17sx5tx}'fof'-6o7t{ckuclucmucnucoucpu4lu5os5rs}3u{17su5tu5qs}3v{17su5tu5qs}7p{17sw5tw5qs}ck{4qs5ku17sw5ou5qy5rw201ss5tw201ws}4l{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cm{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cn{4qs5ku17sw5ou5qy5rw201ss5tw201ws}co{4qs5ku17sw5ou5qy5rw201ss5tw201ws}cp{4qs5ku17sw5ou5qy5rw201ss5tw201ws}6l{17su5tu5os5qw5rs}17s{2ktclvcmvcnvcovcpv4lv4wuckv}5o{ckwclwcmwcnwcowcpw4lw4wu}5q{ckyclycmycnycoycpy4ly4wu5ms}5r{cktcltcmtcntcotcpt4lt4ws}5t{2ktclvcmvcnvcovcpv4lv4wuckv}7q{cksclscmscnscoscps4ls}6p{17su5tu5qw5rs}ek{5qs5rs}el{17su5tu5os5qw5rs}em{17su5tu5os5qs5rs}en{17su5qs5rs}eo{5qs5rs}ep{17su5tu5os5qw5rs}es{5qs}et{17su5tu5qw5rs}eu{17su5tu5qs5rs}ev{5qs}6z{17sv5tv5os5qx5rs}fm{5os5qt5rs}fn{17sv5tv5os5qx5rs}fo{17sv5tv5os5qx5rs}fp{5os5qt5rs}fq{5os5qt5rs}7r{ckuclucmucnucoucpu4lu5os}fs{17sv5tv5os5qx5rs}ft{17ss5ts5qs}fu{17sw5tw5qs}fv{17sw5tw5qs}fw{17ss5ts5qs}fz{ckuclucmucnucoucpu4lu5os5rs}}}"),"Helvetica-Oblique":e("{'widths'{k3p2q4mcx1w201n3r201o6o201s1q201t1q201u1q201w2l201x2l201y2l2k1w2l1w202m2n2n3r2o3r2p5t202q6o2r1n2s2l2t2l2u2r2v3u2w1w2x2l2y1w2z1w3k3r3l3r3m3r3n3r3o3r3p3r3q3r3r3r3s3r203t2l203u2l3v1w3w3u3x3u3y3u3z3r4k6p4l4m4m4m4n4s4o4s4p4m4q3x4r4y4s4s4t1w4u3m4v4m4w3r4x5n4y4s4z4y5k4m5l4y5m4s5n4m5o3x5p4s5q4m5r5y5s4m5t4m5u3x5v1w5w1w5x1w5y2z5z3r6k2l6l3r6m3r6n3m6o3r6p3r6q1w6r3r6s3r6t1q6u1q6v3m6w1q6x5n6y3r6z3r7k3r7l3r7m2l7n3m7o1w7p3r7q3m7r4s7s3m7t3m7u3m7v2l7w1u7x2l7y3u202l3rcl4mal2lam3ran3rao3rap3rar3ras2lat4tau2pav3raw3uay4taz2lbk2sbl3u'fof'6obo2lbp3rbr1wbs2lbu2obv3rbz3xck4m202k3rcm4mcn4mco4mcp4mcq6ocr4scs4mct4mcu4mcv4mcw1w2m2ncy1wcz1wdl4sdm4ydn4ydo4ydp4ydq4yds4ydt4sdu4sdv4sdw4sdz3xek3rel3rem3ren3reo3rep3req5ter3mes3ret3reu3rev3rew1wex1wey1wez1wfl3rfm3rfn3rfo3rfp3rfq3rfr3ufs3xft3rfu3rfv3rfw3rfz3m203k6o212m6o2dw2l2cq2l3t3r3u1w17s4m19m3r}'kerning'{5q{4wv}cl{4qs5kw5ow5qs17sv5tv}201t{2wu4w1k2yu}201x{2wu4wy2yu}17s{2ktclucmucnu4otcpu4lu4wycoucku}2w{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}2x{17sy5ty5oy5qs}2y{7qs4qz5k1m17sy5ow5qx5rsfsu5ty7tufzu}'fof'-6o7p{17sv5tv5ow}ck{4qs5kw5ow5qs17sv5tv}4l{4qs5kw5ow5qs17sv5tv}cm{4qs5kw5ow5qs17sv5tv}cn{4qs5kw5ow5qs17sv5tv}co{4qs5kw5ow5qs17sv5tv}cp{4qs5kw5ow5qs17sv5tv}6l{17sy5ty5ow}do{17st5tt}4z{17st5tt}7s{fst}dm{17st5tt}dn{17st5tt}5o{ckwclwcmwcnwcowcpw4lw4wv}dp{17st5tt}dq{17st5tt}7t{5ow}ds{17st5tt}5t{2ktclucmucnu4otcpu4lu4wycoucku}fu{17sv5tv5ow}6p{17sy5ty5ow5qs}ek{17sy5ty5ow}el{17sy5ty5ow}em{17sy5ty5ow}en{5ty}eo{17sy5ty5ow}ep{17sy5ty5ow}es{17sy5ty5qs}et{17sy5ty5ow5qs}eu{17sy5ty5ow5qs}ev{17sy5ty5ow5qs}6z{17sy5ty5ow5qs}fm{17sy5ty5ow5qs}fn{17sy5ty5ow5qs}fo{17sy5ty5ow5qs}fp{17sy5ty5qs}fq{17sy5ty5ow5qs}7r{5ow}fs{17sy5ty5ow5qs}ft{17sv5tv5ow}7m{5ow}fv{17sv5tv5ow}fw{17sv5tv5ow}}}")}};
t.events.push(["addFonts",function(t){var e,n,i,o,a,u="Unicode";for(n in t.fonts)t.fonts.hasOwnProperty(n)&&(e=t.fonts[n],i=s[u][e.PostScriptName],i&&(o=e.metadata[u]?e.metadata[u]:e.metadata[u]={},o.widths=i.widths,o.kerning=i.kerning),a=r[u][e.PostScriptName],a&&(o=e.metadata[u]?e.metadata[u]:e.metadata[u]={},o.encoding=a,a.codePages&&a.codePages.length&&(e.encoding=a.codePages[0])))}])}(n.API),function(t){"use strict";t.putTotalPages=function(t){for(var e=new RegExp(t,"g"),n=1;n<=this.internal.getNumberOfPages();n++)for(var r=0;r<this.internal.pages[n].length;r++)this.internal.pages[n][r]=this.internal.pages[n][r].replace(e,this.internal.getNumberOfPages());return this}}(n.API),function(t){"use strict";if(t.URL=t.URL||t.webkitURL,t.Blob&&t.URL)try{return void new Blob}catch(e){}var n=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||function(t){var e=function(t){return Object.prototype.toString.call(t).match(/^\[object\s(.*)\]$/)[1]},n=function(){this.data=[]},r=function(t,e,n){this.data=t,this.size=t.length,this.type=e,this.encoding=n},s=n.prototype,i=r.prototype,o=t.FileReaderSync,a=function(t){this.code=this[this.name=t]},u="NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR".split(" "),c=u.length,l=t.URL||t.webkitURL||t,f=l.createObjectURL,d=l.revokeObjectURL,h=l,p=t.btoa,m=t.atob,w=t.ArrayBuffer,g=t.Uint8Array,y=/^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/;for(r.fake=i.fake=!0;c--;)a.prototype[u[c]]=c+1;return l.createObjectURL||(h=t.URL=function(t){var e,n=document.createElementNS("http://www.w3.org/1999/xhtml","a");return n.href=t,"origin"in n||("data:"===n.protocol.toLowerCase()?n.origin=null:(e=t.match(y),n.origin=e&&e[1])),n}),h.createObjectURL=function(t){var e,n=t.type;return null===n&&(n="application/octet-stream"),t instanceof r?(e="data:"+n,"base64"===t.encoding?e+";base64,"+t.data:"URI"===t.encoding?e+","+decodeURIComponent(t.data):p?e+";base64,"+p(t.data):e+","+encodeURIComponent(t.data)):f?f.call(l,t):void 0},h.revokeObjectURL=function(t){"data:"!==t.substring(0,5)&&d&&d.call(l,t)},s.append=function(t){var n=this.data;if(g&&(t instanceof w||t instanceof g)){for(var s="",i=new g(t),u=0,c=i.length;c>u;u++)s+=String.fromCharCode(i[u]);n.push(s)}else if("Blob"===e(t)||"File"===e(t)){if(!o)throw new a("NOT_READABLE_ERR");var l=new o;n.push(l.readAsBinaryString(t))}else t instanceof r?"base64"===t.encoding&&m?n.push(m(t.data)):"URI"===t.encoding?n.push(decodeURIComponent(t.data)):"raw"===t.encoding&&n.push(t.data):("string"!=typeof t&&(t+=""),n.push(unescape(encodeURIComponent(t))))},s.getBlob=function(t){return arguments.length||(t=null),new r(this.data.join(""),t,"raw")},s.toString=function(){return"[object BlobBuilder]"},i.slice=function(t,e,n){var s=arguments.length;return 3>s&&(n=null),new r(this.data.slice(t,s>1?e:this.data.length),n,this.encoding)},i.toString=function(){return"[object Blob]"},i.close=function(){this.size=0,delete this.data},n}(t);t.Blob=function(t,e){var r=e?e.type||"":"",s=new n;if(t)for(var i=0,o=t.length;o>i;i++)s.append(t[i]);return s.getBlob(r)}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content||this);var r=r||"undefined"!=typeof navigator&&navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator)||function(t){"use strict";if("undefined"==typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var e=t.document,n=function(){return t.URL||t.webkitURL||t},r=e.createElementNS("http://www.w3.org/1999/xhtml","a"),s="download"in r,i=function(n){var r=e.createEvent("MouseEvents");r.initMouseEvent("click",!0,!1,t,0,0,0,0,0,!1,!1,!1,!1,0,null),n.dispatchEvent(r)},o=t.webkitRequestFileSystem,a=t.requestFileSystem||o||t.mozRequestFileSystem,u=function(e){(t.setImmediate||t.setTimeout)(function(){throw e},0)},c="application/octet-stream",l=0,f=10,d=function(e){var r=function(){"string"==typeof e?n().revokeObjectURL(e):e.remove()};t.chrome?r():setTimeout(r,f)},h=function(t,e,n){e=[].concat(e);for(var r=e.length;r--;){var s=t["on"+e[r]];if("function"==typeof s)try{s.call(t,n||t)}catch(i){u(i)}}},p=function(e,u){var f,p,m,w=this,g=e.type,y=!1,v=function(){h(w,"writestart progress write writeend".split(" "))},b=function(){if((y||!f)&&(f=n().createObjectURL(e)),p)p.location.href=f;else{var r=t.open(f,"_blank");void 0==r&&"undefined"!=typeof safari&&(t.location.href=f)}w.readyState=w.DONE,v(),d(f)},q=function(t){return function(){return w.readyState!==w.DONE?t.apply(this,arguments):void 0}},x={create:!0,exclusive:!1};return w.readyState=w.INIT,u||(u="download"),s?(f=n().createObjectURL(e),r.href=f,r.download=u,i(r),w.readyState=w.DONE,v(),void d(f)):(t.chrome&&g&&g!==c&&(m=e.slice||e.webkitSlice,e=m.call(e,0,e.size,c),y=!0),o&&"download"!==u&&(u+=".download"),(g===c||o)&&(p=t),a?(l+=e.size,void a(t.TEMPORARY,l,q(function(t){t.root.getDirectory("saved",x,q(function(t){var n=function(){t.getFile(u,x,q(function(t){t.createWriter(q(function(n){n.onwriteend=function(e){p.location.href=t.toURL(),w.readyState=w.DONE,h(w,"writeend",e),d(t)},n.onerror=function(){var t=n.error;t.code!==t.ABORT_ERR&&b()},"writestart progress write abort".split(" ").forEach(function(t){n["on"+t]=w["on"+t]}),n.write(e),w.abort=function(){n.abort(),w.readyState=w.DONE},w.readyState=w.WRITING}),b)}),b)};t.getFile(u,{create:!1},q(function(t){t.remove(),n()}),q(function(t){t.code===t.NOT_FOUND_ERR?n():b()}))}),b)}),b)):void b())},m=p.prototype,w=function(t,e){return new p(t,e)};return m.abort=function(){var t=this;t.readyState=t.DONE,h(t,"abort")},m.readyState=m.INIT=0,m.WRITING=1,m.DONE=2,m.error=m.onwritestart=m.onprogress=m.onwrite=m.onabort=m.onerror=m.onwriteend=null,w}}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this.content);"undefined"!=typeof module&&null!==module&&(module.exports=r),void function(t,e){"object"==typeof module?module.exports=e():t.adler32cs=e()}(n,function(){var t="function"==typeof ArrayBuffer&&"function"==typeof Uint8Array,e=null,n=function(){if(!t)return function(){return!1};try{var n=require("buffer");"function"==typeof n.Buffer&&(e=n.Buffer)}catch(r){}return function(t){return t instanceof ArrayBuffer||null!==e&&t instanceof e}}(),r=function(){return null!==e?function(t){return new e(t,"utf8").toString("binary")}:function(t){return unescape(encodeURIComponent(t))}}(),s=65521,i=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;o>i;i++)n=(n+(255&e.charCodeAt(i)))%s,r=(r+n)%s;return(r<<16|n)>>>0},o=function(t,e){for(var n=65535&t,r=t>>>16,i=0,o=e.length;o>i;i++)n=(n+e[i])%s,r=(r+n)%s;return(r<<16|n)>>>0},a={},u=a.Adler32=function(){var e=function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!isFinite(t=null==t?1:+t))throw new Error("First arguments needs to be a finite number.");this.checksum=t>>>0},s=e.prototype={};return s.constructor=e,e.from=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");this.checksum=i(1,t.toString())}),e.fromUtf8=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(null==t)throw new Error("First argument needs to be a string.");var n=r(t.toString());this.checksum=i(1,n)}),t&&(e.fromBuffer=function(t){return t.prototype=s,t}(function(t){if(!(this instanceof e))throw new TypeError("Constructor cannot called be as a function.");if(!n(t))throw new Error("First argument needs to be ArrayBuffer.");var r=new Uint8Array(t);return this.checksum=o(1,r)})),s.update=function(t){if(null==t)throw new Error("First argument needs to be a string.");return t=t.toString(),this.checksum=i(this.checksum,t)},s.updateUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=r(t.toString());return this.checksum=i(this.checksum,e)},t&&(s.updateBuffer=function(t){if(!n(t))throw new Error("First argument needs to be ArrayBuffer.");var e=new Uint8Array(t);return this.checksum=o(this.checksum,e)}),s.clone=function(){return new u(this.checksum)},e}();return a.from=function(t){if(null==t)throw new Error("First argument needs to be a string.");return i(1,t.toString())},a.fromUtf8=function(t){if(null==t)throw new Error("First argument needs to be a string.");var e=r(t.toString());return i(1,e)},t&&(a.fromBuffer=function(t){if(!n(t))throw new Error("First argument need to be ArrayBuffer.");var e=new Uint8Array(t);return o(1,e)}),a});var s=function(){function t(){function t(t){var e,n,s,i,a,u,c=r.dyn_tree,l=r.stat_desc.static_tree,f=r.stat_desc.extra_bits,h=r.stat_desc.extra_base,p=r.stat_desc.max_length,m=0;for(i=0;o>=i;i++)t.bl_count[i]=0;for(c[2*t.heap[t.heap_max]+1]=0,e=t.heap_max+1;d>e;e++)n=t.heap[e],i=c[2*c[2*n+1]+1]+1,i>p&&(i=p,m++),c[2*n+1]=i,n>r.max_code||(t.bl_count[i]++,a=0,n>=h&&(a=f[n-h]),u=c[2*n],t.opt_len+=u*(i+a),l&&(t.static_len+=u*(l[2*n+1]+a)));if(0!==m){do{for(i=p-1;0===t.bl_count[i];)i--;t.bl_count[i]--,t.bl_count[i+1]+=2,t.bl_count[p]--,m-=2}while(m>0);for(i=p;0!==i;i--)for(n=t.bl_count[i];0!==n;)s=t.heap[--e],s>r.max_code||(c[2*s+1]!=i&&(t.opt_len+=(i-c[2*s+1])*c[2*s],c[2*s+1]=i),n--)}}function e(t,e){var n=0;do n|=1&t,t>>>=1,n<<=1;while(--e>0);return n>>>1}function n(t,n,r){var s,i,a,u=[],c=0;for(s=1;o>=s;s++)u[s]=c=c+r[s-1]<<1;for(i=0;n>=i;i++)a=t[2*i+1],0!==a&&(t[2*i]=e(u[a]++,a))}var r=this;r.build_tree=function(e){var s,i,o,a=r.dyn_tree,u=r.stat_desc.static_tree,c=r.stat_desc.elems,l=-1;for(e.heap_len=0,e.heap_max=d,s=0;c>s;s++)0!==a[2*s]?(e.heap[++e.heap_len]=l=s,e.depth[s]=0):a[2*s+1]=0;for(;e.heap_len<2;)o=e.heap[++e.heap_len]=2>l?++l:0,a[2*o]=1,e.depth[o]=0,e.opt_len--,u&&(e.static_len-=u[2*o+1]);for(r.max_code=l,s=Math.floor(e.heap_len/2);s>=1;s--)e.pqdownheap(a,s);o=c;do s=e.heap[1],e.heap[1]=e.heap[e.heap_len--],e.pqdownheap(a,1),i=e.heap[1],e.heap[--e.heap_max]=s,e.heap[--e.heap_max]=i,a[2*o]=a[2*s]+a[2*i],e.depth[o]=Math.max(e.depth[s],e.depth[i])+1,a[2*s+1]=a[2*i+1]=o,e.heap[1]=o++,e.pqdownheap(a,1);while(e.heap_len>=2);e.heap[--e.heap_max]=e.heap[1],t(e),n(a,r.max_code,e.bl_count)}}function e(t,e,n,r,s){var i=this;i.static_tree=t,i.extra_bits=e,i.extra_base=n,i.elems=r,i.max_length=s}function n(t,e,n,r,s){var i=this;i.good_length=t,i.max_lazy=e,i.nice_length=n,i.max_chain=r,i.func=s}function r(t,e,n,r){var s=t[2*e],i=t[2*n];return i>s||s==i&&r[e]<=r[n]}function s(){function n(){var t;for(Te=2*Ce,Be[Pe-1]=0,t=0;Pe-1>t;t++)Be[t]=0;Je=N[Xe].max_lazy,Ke=N[Xe].good_length,Qe=N[Xe].nice_length,Ve=N[Xe].max_chain,Me=0,Ue=0,Ge=0,Ne=We=Z-1,je=0,Oe=0}function s(){var t;for(t=0;f>t;t++)$e[2*t]=0;for(t=0;a>t;t++)Ze[2*t]=0;for(t=0;u>t;t++)tn[2*t]=0;$e[2*h]=1,en.opt_len=en.static_len=0,un=ln=0}function i(){nn.dyn_tree=$e,nn.stat_desc=e.static_l_desc,rn.dyn_tree=Ze,rn.stat_desc=e.static_d_desc,sn.dyn_tree=tn,sn.stat_desc=e.static_bl_desc,dn=0,hn=0,fn=8,s()}function o(t,e){var n,r,s=-1,i=t[1],o=0,a=7,u=4;for(0===i&&(a=138,u=3),t[2*(e+1)+1]=65535,n=0;e>=n;n++)r=i,i=t[2*(n+1)+1],++o<a&&r==i||(u>o?tn[2*r]+=o:0!==r?(r!=s&&tn[2*r]++,tn[2*m]++):10>=o?tn[2*w]++:tn[2*g]++,o=0,s=r,0===i?(a=138,u=3):r==i?(a=6,u=3):(a=7,u=4))}function c(){var e;for(o($e,nn.max_code),o(Ze,rn.max_code),sn.build_tree(en),e=u-1;e>=3&&0===tn[2*t.bl_order[e]+1];e--);return en.opt_len+=3*(e+1)+5+5+4,e}function d(t){en.pending_buf[en.pending++]=t}function p(t){d(255&t),d(t>>>8&255)}function O(t){d(t>>8&255),d(255&t&255)}function ne(t,e){var n,r=e;hn>y-r?(n=t,dn|=n<<hn&65535,p(dn),dn=n>>>y-hn,hn+=r-y):(dn|=t<<hn&65535,hn+=r)}function re(t,e){var n=2*t;ne(65535&e[n],65535&e[n+1])}function se(t,e){var n,r,s=-1,i=t[1],o=0,a=7,u=4;for(0===i&&(a=138,u=3),n=0;e>=n;n++)if(r=i,i=t[2*(n+1)+1],!(++o<a&&r==i)){if(u>o){do re(r,tn);while(0!==--o)}else 0!==r?(r!=s&&(re(r,tn),o--),re(m,tn),ne(o-3,2)):10>=o?(re(w,tn),ne(o-3,3)):(re(g,tn),ne(o-11,7));o=0,s=r,0===i?(a=138,u=3):r==i?(a=6,u=3):(a=7,u=4)}}function ie(e,n,r){var s;for(ne(e-257,5),ne(n-1,5),ne(r-4,4),s=0;r>s;s++)ne(tn[2*t.bl_order[s]+1],3);se($e,e-1),se(Ze,n-1)}function oe(){16==hn?(p(dn),dn=0,hn=0):hn>=8&&(d(255&dn),dn>>>=8,hn-=8)}function ae(){ne(Q<<1,3),re(h,e.static_ltree),oe(),9>1+fn+10-hn&&(ne(Q<<1,3),re(h,e.static_ltree),oe()),fn=7}function ue(e,n){var r,s,i;if(en.pending_buf[cn+2*un]=e>>>8&255,en.pending_buf[cn+2*un+1]=255&e,en.pending_buf[on+un]=255&n,un++,0===e?$e[2*n]++:(ln++,e--,$e[2*(t._length_code[n]+l+1)]++,Ze[2*t.d_code(e)]++),0===(8191&un)&&Xe>2){for(r=8*un,s=Me-Ue,i=0;a>i;i++)r+=Ze[2*i]*(5+t.extra_dbits[i]);if(r>>>=3,ln<Math.floor(un/2)&&r<Math.floor(s/2))return!0}return un==an-1}function ce(e,n){var r,s,i,o,a=0;if(0!==un)do r=en.pending_buf[cn+2*a]<<8&65280|255&en.pending_buf[cn+2*a+1],s=255&en.pending_buf[on+a],a++,0===r?re(s,e):(i=t._length_code[s],re(i+l+1,e),o=t.extra_lbits[i],0!==o&&(s-=t.base_length[i],ne(s,o)),r--,i=t.d_code(r),re(i,n),o=t.extra_dbits[i],0!==o&&(r-=t.base_dist[i],ne(r,o)));while(un>a);re(h,e),fn=e[2*h+1]}function le(){hn>8?p(dn):hn>0&&d(255&dn),dn=0,hn=0}function fe(t,e,n){le(),fn=8,n&&(p(e),p(~e)),en.pending_buf.set(ze.subarray(t,t+e),en.pending),en.pending+=e}function de(t,e,n){ne((K<<1)+(n?1:0),3),fe(t,e,!0)}function he(t,n,r){var i,o,a=0;Xe>0?(nn.build_tree(en),rn.build_tree(en),a=c(),i=en.opt_len+3+7>>>3,o=en.static_len+3+7>>>3,i>=o&&(i=o)):i=o=n+5,i>=n+4&&-1!=t?de(t,n,r):o==i?(ne((Q<<1)+(r?1:0),3),ce(e.static_ltree,e.static_dtree)):(ne(($<<1)+(r?1:0),3),ie(nn.max_code+1,rn.max_code+1,a+1),ce($e,Ze)),s(),r&&le()}function pe(t){he(Ue>=0?Ue:-1,Me-Ue,t),Ue=Me,qe.flush_pending()}function me(){var t,e,n,r;do{if(r=Te-Ge-Me,0===r&&0===Me&&0===Ge)r=Ce;else if(-1==r)r--;else if(Me>=Ce+Ce-ee){ze.set(ze.subarray(Ce,Ce+Ce),0),He-=Ce,Me-=Ce,Ue-=Ce,t=Pe,n=t;do e=65535&Be[--n],Be[n]=e>=Ce?e-Ce:0;while(0!==--t);t=Ce,n=t;do e=65535&Ie[--n],Ie[n]=e>=Ce?e-Ce:0;while(0!==--t);r+=Ce}if(0===qe.avail_in)return;t=qe.read_buf(ze,Me+Ge,r),Ge+=t,Ge>=Z&&(Oe=255&ze[Me],Oe=(Oe<<De^255&ze[Me+1])&Fe)}while(ee>Ge&&0!==qe.avail_in)}function we(t){var e,n=65535;for(n>ke-5&&(n=ke-5);;){if(1>=Ge){if(me(),0===Ge&&t==k)return j;if(0===Ge)break}if(Me+=Ge,Ge=0,e=Ue+n,(0===Me||Me>=e)&&(Ge=Me-e,Me=e,pe(!1),0===qe.avail_out))return j;if(Me-Ue>=Ce-ee&&(pe(!1),0===qe.avail_out))return j}return pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function ge(t){var e,n,r=Ve,s=Me,i=We,o=Me>Ce-ee?Me-(Ce-ee):0,a=Qe,u=Ee,c=Me+te,l=ze[s+i-1],f=ze[s+i];We>=Ke&&(r>>=2),a>Ge&&(a=Ge);do if(e=t,ze[e+i]==f&&ze[e+i-1]==l&&ze[e]==ze[s]&&ze[++e]==ze[s+1]){s+=2,e++;do;while(ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&ze[++s]==ze[++e]&&c>s);if(n=te-(c-s),s=c-te,n>i){if(He=t,i=n,n>=a)break;l=ze[s+i-1],f=ze[s+i]}}while((t=65535&Ie[t&u])>o&&0!==--r);return Ge>=i?i:Ge}function ye(t){for(var e,n=0;;){if(ee>Ge){if(me(),ee>Ge&&t==k)return j;if(0===Ge)break}if(Ge>=Z&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Fe,n=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me),0!==n&&Ce-ee>=(Me-n&65535)&&Ye!=q&&(Ne=ge(n)),Ne>=Z)if(e=ue(Me-He,Ne-Z),Ge-=Ne,Je>=Ne&&Ge>=Z){Ne--;do Me++,Oe=(Oe<<De^255&ze[Me+(Z-1)])&Fe,n=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me;while(0!==--Ne);Me++}else Me+=Ne,Ne=0,Oe=255&ze[Me],Oe=(Oe<<De^255&ze[Me+1])&Fe;else e=ue(0,255&ze[Me]),Ge--,Me++;if(e&&(pe(!1),0===qe.avail_out))return j}return pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function ve(t){for(var e,n,r=0;;){if(ee>Ge){if(me(),ee>Ge&&t==k)return j;if(0===Ge)break}if(Ge>=Z&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Fe,r=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me),We=Ne,Le=He,Ne=Z-1,0!==r&&Je>We&&Ce-ee>=(Me-r&65535)&&(Ye!=q&&(Ne=ge(r)),5>=Ne&&(Ye==b||Ne==Z&&Me-He>4096)&&(Ne=Z-1)),We>=Z&&We>=Ne){n=Me+Ge-Z,e=ue(Me-1-Le,We-Z),Ge-=We-1,We-=2;do++Me<=n&&(Oe=(Oe<<De^255&ze[Me+(Z-1)])&Fe,r=65535&Be[Oe],Ie[Me&Ee]=Be[Oe],Be[Oe]=Me);while(0!==--We);if(je=0,Ne=Z-1,Me++,e&&(pe(!1),0===qe.avail_out))return j}else if(0!==je){if(e=ue(0,255&ze[Me-1]),e&&pe(!1),Me++,Ge--,0===qe.avail_out)return j}else je=1,Me++,Ge--}return 0!==je&&(e=ue(0,255&ze[Me-1]),je=0),pe(t==C),0===qe.avail_out?t==C?H:j:t==C?G:M}function be(t){return t.total_in=t.total_out=0,t.msg=null,en.pending=0,en.pending_out=0,xe=J,Ae=k,i(),n(),S}var qe,xe,ke,_e,Ae,Ce,Se,Ee,ze,Te,Ie,Be,Oe,Pe,Re,Fe,De,Ue,Ne,Le,je,Me,He,Ge,We,Ve,Je,Xe,Ye,Ke,Qe,$e,Ze,tn,en=this,nn=new t,rn=new t,sn=new t;en.depth=[];var on,an,un,cn,ln,fn,dn,hn;en.bl_count=[],en.heap=[],$e=[],Ze=[],tn=[],en.pqdownheap=function(t,e){for(var n=en.heap,s=n[e],i=e<<1;i<=en.heap_len&&(i<en.heap_len&&r(t,n[i+1],n[i],en.depth)&&i++,!r(t,s,n[i],en.depth));)n[e]=n[i],e=i,i<<=1;n[e]=s},en.deflateInit=function(t,e,n,r,s,i){return r||(r=Y),s||(s=R),i||(i=x),t.msg=null,e==v&&(e=6),1>s||s>P||r!=Y||9>n||n>15||0>e||e>9||0>i||i>q?T:(t.dstate=en,Se=n,Ce=1<<Se,Ee=Ce-1,Re=s+7,Pe=1<<Re,Fe=Pe-1,De=Math.floor((Re+Z-1)/Z),ze=new Uint8Array(2*Ce),Ie=[],Be=[],an=1<<s+6,en.pending_buf=new Uint8Array(4*an),ke=4*an,cn=Math.floor(an/2),on=3*an,Xe=e,Ye=i,_e=255&r,be(t))},en.deflateEnd=function(){return xe!=V&&xe!=J&&xe!=X?T:(en.pending_buf=null,Be=null,Ie=null,ze=null,en.dstate=null,xe==J?I:S)},en.deflateParams=function(t,e,n){var r=S;return e==v&&(e=6),0>e||e>9||0>n||n>q?T:(N[Xe].func!=N[e].func&&0!==t.total_in&&(r=t.deflate(_)),Xe!=e&&(Xe=e,Je=N[Xe].max_lazy,Ke=N[Xe].good_length,Qe=N[Xe].nice_length,Ve=N[Xe].max_chain),Ye=n,r)},en.deflateSetDictionary=function(t,e,n){var r,s=n,i=0;if(!e||xe!=V)return T;if(Z>s)return S;for(s>Ce-ee&&(s=Ce-ee,i=n-s),ze.set(e.subarray(i,i+s),0),Me=s,Ue=s,Oe=255&ze[0],Oe=(Oe<<De^255&ze[1])&Fe,r=0;s-Z>=r;r++)Oe=(Oe<<De^255&ze[r+(Z-1)])&Fe,Ie[r&Ee]=Be[Oe],Be[Oe]=r;return S},en.deflate=function(t,e){var n,r,s,i,o;if(e>C||0>e)return T;if(!t.next_out||!t.next_in&&0!==t.avail_in||xe==X&&e!=C)return t.msg=L[z-T],T;if(0===t.avail_out)return t.msg=L[z-B],B;if(qe=t,i=Ae,Ae=e,xe==V&&(r=Y+(Se-8<<4)<<8,s=(Xe-1&255)>>1,s>3&&(s=3),r|=s<<6,0!==Me&&(r|=W),r+=31-r%31,xe=J,O(r)),0!==en.pending){if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}else if(0===qe.avail_in&&i>=e&&e!=C)return qe.msg=L[z-B],B;if(xe==X&&0!==qe.avail_in)return t.msg=L[z-B],B;if(0!==qe.avail_in||0!==Ge||e!=k&&xe!=X){switch(o=-1,N[Xe].func){case F:o=we(e);break;case D:o=ye(e);break;case U:o=ve(e)}if((o==H||o==G)&&(xe=X),o==j||o==H)return 0===qe.avail_out&&(Ae=-1),S;if(o==M){if(e==_)ae();else if(de(0,0,!1),e==A)for(n=0;Pe>n;n++)Be[n]=0;if(qe.flush_pending(),0===qe.avail_out)return Ae=-1,S}}return e!=C?S:E}}function i(){var t=this;t.next_in_index=0,t.next_out_index=0,t.avail_in=0,t.total_in=0,t.avail_out=0,t.total_out=0}var o=15,a=30,u=19,c=29,l=256,f=l+1+c,d=2*f+1,h=256,p=7,m=16,w=17,g=18,y=16,v=-1,b=1,q=2,x=0,k=0,_=1,A=3,C=4,S=0,E=1,z=2,T=-2,I=-3,B=-5,O=[0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,0,0,16,17,18,18,19,19,20,20,20,20,21,21,21,21,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29];t._length_code=[0,1,2,3,4,5,6,7,8,8,9,9,10,10,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,18,18,18,18,18,18,18,18,19,19,19,19,19,19,19,19,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,22,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28],t.base_length=[0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224,0],t.base_dist=[0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576],t.d_code=function(t){return 256>t?O[t]:O[256+(t>>>7)]},t.extra_lbits=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],t.extra_dbits=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],t.extra_blbits=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],t.bl_order=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],e.static_ltree=[12,8,140,8,76,8,204,8,44,8,172,8,108,8,236,8,28,8,156,8,92,8,220,8,60,8,188,8,124,8,252,8,2,8,130,8,66,8,194,8,34,8,162,8,98,8,226,8,18,8,146,8,82,8,210,8,50,8,178,8,114,8,242,8,10,8,138,8,74,8,202,8,42,8,170,8,106,8,234,8,26,8,154,8,90,8,218,8,58,8,186,8,122,8,250,8,6,8,134,8,70,8,198,8,38,8,166,8,102,8,230,8,22,8,150,8,86,8,214,8,54,8,182,8,118,8,246,8,14,8,142,8,78,8,206,8,46,8,174,8,110,8,238,8,30,8,158,8,94,8,222,8,62,8,190,8,126,8,254,8,1,8,129,8,65,8,193,8,33,8,161,8,97,8,225,8,17,8,145,8,81,8,209,8,49,8,177,8,113,8,241,8,9,8,137,8,73,8,201,8,41,8,169,8,105,8,233,8,25,8,153,8,89,8,217,8,57,8,185,8,121,8,249,8,5,8,133,8,69,8,197,8,37,8,165,8,101,8,229,8,21,8,149,8,85,8,213,8,53,8,181,8,117,8,245,8,13,8,141,8,77,8,205,8,45,8,173,8,109,8,237,8,29,8,157,8,93,8,221,8,61,8,189,8,125,8,253,8,19,9,275,9,147,9,403,9,83,9,339,9,211,9,467,9,51,9,307,9,179,9,435,9,115,9,371,9,243,9,499,9,11,9,267,9,139,9,395,9,75,9,331,9,203,9,459,9,43,9,299,9,171,9,427,9,107,9,363,9,235,9,491,9,27,9,283,9,155,9,411,9,91,9,347,9,219,9,475,9,59,9,315,9,187,9,443,9,123,9,379,9,251,9,507,9,7,9,263,9,135,9,391,9,71,9,327,9,199,9,455,9,39,9,295,9,167,9,423,9,103,9,359,9,231,9,487,9,23,9,279,9,151,9,407,9,87,9,343,9,215,9,471,9,55,9,311,9,183,9,439,9,119,9,375,9,247,9,503,9,15,9,271,9,143,9,399,9,79,9,335,9,207,9,463,9,47,9,303,9,175,9,431,9,111,9,367,9,239,9,495,9,31,9,287,9,159,9,415,9,95,9,351,9,223,9,479,9,63,9,319,9,191,9,447,9,127,9,383,9,255,9,511,9,0,7,64,7,32,7,96,7,16,7,80,7,48,7,112,7,8,7,72,7,40,7,104,7,24,7,88,7,56,7,120,7,4,7,68,7,36,7,100,7,20,7,84,7,52,7,116,7,3,8,131,8,67,8,195,8,35,8,163,8,99,8,227,8],e.static_dtree=[0,5,16,5,8,5,24,5,4,5,20,5,12,5,28,5,2,5,18,5,10,5,26,5,6,5,22,5,14,5,30,5,1,5,17,5,9,5,25,5,5,5,21,5,13,5,29,5,3,5,19,5,11,5,27,5,7,5,23,5],e.static_l_desc=new e(e.static_ltree,t.extra_lbits,l+1,f,o),e.static_d_desc=new e(e.static_dtree,t.extra_dbits,0,a,o),e.static_bl_desc=new e(null,t.extra_blbits,0,u,p);var P=9,R=8,F=0,D=1,U=2,N=[new n(0,0,0,0,F),new n(4,4,8,4,D),new n(4,5,16,8,D),new n(4,6,32,32,D),new n(4,4,16,16,U),new n(8,16,32,32,U),new n(8,16,128,128,U),new n(8,32,128,256,U),new n(32,128,258,1024,U),new n(32,258,258,4096,U)],L=["need dictionary","stream end","","","stream error","data error","","buffer error","",""],j=0,M=1,H=2,G=3,W=32,V=42,J=113,X=666,Y=8,K=0,Q=1,$=2,Z=3,te=258,ee=te+Z+1;return i.prototype={deflateInit:function(t,e){var n=this;return n.dstate=new s,e||(e=o),n.dstate.deflateInit(n,t,e)},deflate:function(t){var e=this;return e.dstate?e.dstate.deflate(e,t):T},deflateEnd:function(){var t=this;if(!t.dstate)return T;var e=t.dstate.deflateEnd();return t.dstate=null,e},deflateParams:function(t,e){var n=this;return n.dstate?n.dstate.deflateParams(n,t,e):T},deflateSetDictionary:function(t,e){var n=this;return n.dstate?n.dstate.deflateSetDictionary(n,t,e):T},read_buf:function(t,e,n){var r=this,s=r.avail_in;return s>n&&(s=n),0===s?0:(r.avail_in-=s,t.set(r.next_in.subarray(r.next_in_index,r.next_in_index+s),e),r.next_in_index+=s,r.total_in+=s,s)},flush_pending:function(){var t=this,e=t.dstate.pending;e>t.avail_out&&(e=t.avail_out),0!==e&&(t.next_out.set(t.dstate.pending_buf.subarray(t.dstate.pending_out,t.dstate.pending_out+e),t.next_out_index),t.next_out_index+=e,t.dstate.pending_out+=e,t.total_out+=e,t.avail_out-=e,t.dstate.pending-=e,0===t.dstate.pending&&(t.dstate.pending_out=0))}},function(t){var e=this,n=new i,r=512,s=k,o=new Uint8Array(r);"undefined"==typeof t&&(t=v),n.deflateInit(t),n.next_out=o,e.append=function(t,e){var i,a,u=[],c=0,l=0,f=0;if(t.length){n.next_in_index=0,n.next_in=t,n.avail_in=t.length;do{if(n.next_out_index=0,n.avail_out=r,i=n.deflate(s),i!=S)throw"deflating: "+n.msg;n.next_out_index&&u.push(n.next_out_index==r?new Uint8Array(o):new Uint8Array(o.subarray(0,n.next_out_index))),f+=n.next_out_index,e&&n.next_in_index>0&&n.next_in_index!=c&&(e(n.next_in_index),c=n.next_in_index)}while(n.avail_in>0||0===n.avail_out);return a=new Uint8Array(f),u.forEach(function(t){a.set(t,l),l+=t.length}),a}},e.flush=function(){var t,e,s=[],i=0,a=0;do{if(n.next_out_index=0,n.avail_out=r,t=n.deflate(C),t!=E&&t!=S)throw"deflating: "+n.msg;r-n.avail_out>0&&s.push(new Uint8Array(o.subarray(0,n.next_out_index))),a+=n.next_out_index}while(n.avail_in>0||0===n.avail_out);return n.deflateEnd(),e=new Uint8Array(a),s.forEach(function(t){e.set(t,i),i+=t.length}),e}}}(this);!function(t){var e;e=function(){function e(t){var e,n,r,s,i,o,a,u,c,l,f,d,h,p,m;for(this.data=t,this.pos=8,this.palette=[],this.imgData=[],this.transparency={},this.animation=null,this.text={},o=null;;){switch(e=this.readUInt32(),l=function(){var t,e;for(e=[],a=t=0;4>t;a=++t)e.push(String.fromCharCode(this.data[this.pos++]));return e}.call(this).join("")){case"IHDR":this.width=this.readUInt32(),this.height=this.readUInt32(),this.bits=this.data[this.pos++],this.colorType=this.data[this.pos++],this.compressionMethod=this.data[this.pos++],this.filterMethod=this.data[this.pos++],this.interlaceMethod=this.data[this.pos++];break;case"acTL":this.animation={numFrames:this.readUInt32(),numPlays:this.readUInt32()||1/0,frames:[]};break;case"PLTE":this.palette=this.read(e);break;case"fcTL":o&&this.animation.frames.push(o),this.pos+=4,o={width:this.readUInt32(),height:this.readUInt32(),xOffset:this.readUInt32(),yOffset:this.readUInt32()},i=this.readUInt16(),s=this.readUInt16()||100,o.delay=1e3*i/s,o.disposeOp=this.data[this.pos++],o.blendOp=this.data[this.pos++],o.data=[];break;case"IDAT":case"fdAT":for("fdAT"===l&&(this.pos+=4,e-=4),t=(null!=o?o.data:void 0)||this.imgData,a=h=0;e>=0?e>h:h>e;a=e>=0?++h:--h)t.push(this.data[this.pos++]);break;case"tRNS":switch(this.transparency={},this.colorType){case 3:if(r=this.palette.length/3,this.transparency.indexed=this.read(e),this.transparency.indexed.length>r)throw new Error("More transparent colors than palette size");if(f=r-this.transparency.indexed.length,f>0)for(a=p=0;f>=0?f>p:p>f;a=f>=0?++p:--p)this.transparency.indexed.push(255);break;case 0:this.transparency.grayscale=this.read(e)[0];break;case 2:this.transparency.rgb=this.read(e)}break;case"tEXt":d=this.read(e),u=d.indexOf(0),c=String.fromCharCode.apply(String,d.slice(0,u)),this.text[c]=String.fromCharCode.apply(String,d.slice(u+1));break;case"IEND":return o&&this.animation.frames.push(o),this.colors=function(){switch(this.colorType){case 0:case 3:case 4:return 1;case 2:case 6:return 3}}.call(this),this.hasAlphaChannel=4===(m=this.colorType)||6===m,n=this.colors+(this.hasAlphaChannel?1:0),this.pixelBitlength=this.bits*n,this.colorSpace=function(){switch(this.colors){case 1:return"DeviceGray";case 3:return"DeviceRGB"}}.call(this),void(this.imgData=new Uint8Array(this.imgData));default:this.pos+=e}if(this.pos+=4,this.pos>this.data.length)throw new Error("Incomplete or corrupt PNG file")}}var n,r,s,i,a,u,c,l;e.load=function(t,n,r){var s;return"function"==typeof n&&(r=n),s=new XMLHttpRequest,s.open("GET",t,!0),s.responseType="arraybuffer",s.onload=function(){var t,i;return t=new Uint8Array(s.response||s.mozResponseArrayBuffer),i=new e(t),"function"==typeof(null!=n?n.getContext:void 0)&&i.render(n),"function"==typeof r?r(i):void 0},s.send(null)},i=0,s=1,a=2,r=0,n=1,e.prototype.read=function(t){var e,n,r;for(r=[],e=n=0;t>=0?t>n:n>t;e=t>=0?++n:--n)r.push(this.data[this.pos++]);return r},e.prototype.readUInt32=function(){var t,e,n,r;return t=this.data[this.pos++]<<24,e=this.data[this.pos++]<<16,n=this.data[this.pos++]<<8,r=this.data[this.pos++],t|e|n|r},e.prototype.readUInt16=function(){var t,e;return t=this.data[this.pos++]<<8,e=this.data[this.pos++],t|e},e.prototype.decodePixels=function(t){var e,n,r,s,i,a,u,c,l,f,d,h,p,m,w,g,y,v,b,q,x,k,_;if(null==t&&(t=this.imgData),0===t.length)return new Uint8Array(0);for(t=new o(t),t=t.getBytes(),h=this.pixelBitlength/8,g=h*this.width,p=new Uint8Array(g*this.height),a=t.length,w=0,m=0,n=0;a>m;){switch(t[m++]){case 0:for(s=b=0;g>b;s=b+=1)p[n++]=t[m++];break;case 1:for(s=q=0;g>q;s=q+=1)e=t[m++],i=h>s?0:p[n-h],p[n++]=(e+i)%256;break;case 2:for(s=x=0;g>x;s=x+=1)e=t[m++],r=(s-s%h)/h,y=w&&p[(w-1)*g+r*h+s%h],p[n++]=(y+e)%256;break;case 3:for(s=k=0;g>k;s=k+=1)e=t[m++],r=(s-s%h)/h,i=h>s?0:p[n-h],y=w&&p[(w-1)*g+r*h+s%h],p[n++]=(e+Math.floor((i+y)/2))%256;break;case 4:for(s=_=0;g>_;s=_+=1)e=t[m++],r=(s-s%h)/h,i=h>s?0:p[n-h],0===w?y=v=0:(y=p[(w-1)*g+r*h+s%h],v=r&&p[(w-1)*g+(r-1)*h+s%h]),u=i+y-v,c=Math.abs(u-i),f=Math.abs(u-y),d=Math.abs(u-v),l=f>=c&&d>=c?i:d>=f?y:v,p[n++]=(e+l)%256;break;default:throw new Error("Invalid filter algorithm: "+t[m-1])}w++}return p},e.prototype.decodePalette=function(){var t,e,n,r,s,i,o,a,u,c;for(r=this.palette,o=this.transparency.indexed||[],i=new Uint8Array((o.length||0)+r.length),s=0,n=r.length,t=0,e=a=0,u=r.length;u>a;e=a+=3)i[s++]=r[e],i[s++]=r[e+1],i[s++]=r[e+2],i[s++]=null!=(c=o[t++])?c:255;return i},e.prototype.copyToImageData=function(t,e){var n,r,s,i,o,a,u,c,l,f,d;if(r=this.colors,l=null,n=this.hasAlphaChannel,this.palette.length&&(l=null!=(d=this._decodedPalette)?d:this._decodedPalette=this.decodePalette(),r=4,n=!0),s=t.data||t,c=s.length,o=l||e,i=a=0,1===r)for(;c>i;)u=l?4*e[i/4]:a,f=o[u++],s[i++]=f,s[i++]=f,s[i++]=f,s[i++]=n?o[u++]:255,a=u;else for(;c>i;)u=l?4*e[i/4]:a,s[i++]=o[u++],s[i++]=o[u++],s[i++]=o[u++],s[i++]=n?o[u++]:255,a=u},e.prototype.decode=function(){var t;return t=new Uint8Array(this.width*this.height*4),this.copyToImageData(t,this.decodePixels()),t};try{c=t.document.createElement("canvas"),l=c.getContext("2d")}catch(f){return-1}return u=function(t){var e;return l.width=t.width,l.height=t.height,l.clearRect(0,0,t.width,t.height),l.putImageData(t,0,0),e=new Image,e.src=c.toDataURL(),e},e.prototype.decodeFrames=function(t){var e,n,r,s,i,o,a,c;if(this.animation){for(a=this.animation.frames,c=[],n=i=0,o=a.length;o>i;n=++i)e=a[n],r=t.createImageData(e.width,e.height),s=this.decodePixels(new Uint8Array(e.data)),this.copyToImageData(r,s),e.imageData=r,c.push(e.image=u(r));return c}},e.prototype.renderFrame=function(t,e){var n,i,o;return i=this.animation.frames,n=i[e],o=i[e-1],0===e&&t.clearRect(0,0,this.width,this.height),(null!=o?o.disposeOp:void 0)===s?t.clearRect(o.xOffset,o.yOffset,o.width,o.height):(null!=o?o.disposeOp:void 0)===a&&t.putImageData(o.imageData,o.xOffset,o.yOffset),n.blendOp===r&&t.clearRect(n.xOffset,n.yOffset,n.width,n.height),t.drawImage(n.image,n.xOffset,n.yOffset)},e.prototype.animate=function(t){var e,n,r,s,i,o,a=this;return n=0,o=this.animation,s=o.numFrames,r=o.frames,i=o.numPlays,(e=function(){var o,u;return o=n++%s,u=r[o],a.renderFrame(t,o),s>1&&i>n/s?a.animation._timeout=setTimeout(e,u.delay):void 0
})()},e.prototype.stopAnimation=function(){var t;return clearTimeout(null!=(t=this.animation)?t._timeout:void 0)},e.prototype.render=function(t){var e,n;return t._png&&t._png.stopAnimation(),t._png=this,t.width=this.width,t.height=this.height,e=t.getContext("2d"),this.animation?(this.decodeFrames(e),this.animate(e)):(n=e.createImageData(this.width,this.height),this.copyToImageData(n,this.decodePixels()),e.putImageData(n,0,0))},e}(),t.PNG=e}("undefined"!=typeof window&&window||this);var i=function(){function t(){this.pos=0,this.bufferLength=0,this.eof=!1,this.buffer=null}return t.prototype={ensureBuffer:function(t){var e=this.buffer,n=e?e.byteLength:0;if(n>t)return e;for(var r=512;t>r;)r<<=1;for(var s=new Uint8Array(r),i=0;n>i;++i)s[i]=e[i];return this.buffer=s},getByte:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return this.buffer[this.pos++]},getBytes:function(t){var e=this.pos;if(t){this.ensureBuffer(e+t);for(var n=e+t;!this.eof&&this.bufferLength<n;)this.readBlock();var r=this.bufferLength;n>r&&(n=r)}else{for(;!this.eof;)this.readBlock();var n=this.bufferLength}return this.pos=n,this.buffer.subarray(e,n)},lookChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos])},getChar:function(){for(var t=this.pos;this.bufferLength<=t;){if(this.eof)return null;this.readBlock()}return String.fromCharCode(this.buffer[this.pos++])},makeSubStream:function(t,e,n){for(var r=t+e;this.bufferLength<=r&&!this.eof;)this.readBlock();return new Stream(this.buffer,t,e,n)},skip:function(t){t||(t=1),this.pos+=t},reset:function(){this.pos=0}},t}(),o=function(){function t(t){throw new Error(t)}function e(e){var n=0,r=e[n++],s=e[n++];(-1==r||-1==s)&&t("Invalid header in flate stream"),8!=(15&r)&&t("Unknown compression method in flate stream"),((r<<8)+s)%31!=0&&t("Bad FCHECK in flate stream"),32&s&&t("FDICT bit set in flate stream"),this.bytes=e,this.bytesPos=n,this.codeSize=0,this.codeBuf=0,i.call(this)}if("undefined"==typeof Uint32Array)return void 0;var n=new Uint32Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),r=new Uint32Array([3,4,5,6,7,8,9,10,65547,65549,65551,65553,131091,131095,131099,131103,196643,196651,196659,196667,262211,262227,262243,262259,327811,327843,327875,327907,258,258,258]),s=new Uint32Array([1,2,3,4,65541,65543,131081,131085,196625,196633,262177,262193,327745,327777,393345,393409,459009,459137,524801,525057,590849,591361,657409,658433,724993,727041,794625,798721,868353,876545]),o=[new Uint32Array([459008,524368,524304,524568,459024,524400,524336,590016,459016,524384,524320,589984,524288,524416,524352,590048,459012,524376,524312,589968,459028,524408,524344,590032,459020,524392,524328,59e4,524296,524424,524360,590064,459010,524372,524308,524572,459026,524404,524340,590024,459018,524388,524324,589992,524292,524420,524356,590056,459014,524380,524316,589976,459030,524412,524348,590040,459022,524396,524332,590008,524300,524428,524364,590072,459009,524370,524306,524570,459025,524402,524338,590020,459017,524386,524322,589988,524290,524418,524354,590052,459013,524378,524314,589972,459029,524410,524346,590036,459021,524394,524330,590004,524298,524426,524362,590068,459011,524374,524310,524574,459027,524406,524342,590028,459019,524390,524326,589996,524294,524422,524358,590060,459015,524382,524318,589980,459031,524414,524350,590044,459023,524398,524334,590012,524302,524430,524366,590076,459008,524369,524305,524569,459024,524401,524337,590018,459016,524385,524321,589986,524289,524417,524353,590050,459012,524377,524313,589970,459028,524409,524345,590034,459020,524393,524329,590002,524297,524425,524361,590066,459010,524373,524309,524573,459026,524405,524341,590026,459018,524389,524325,589994,524293,524421,524357,590058,459014,524381,524317,589978,459030,524413,524349,590042,459022,524397,524333,590010,524301,524429,524365,590074,459009,524371,524307,524571,459025,524403,524339,590022,459017,524387,524323,589990,524291,524419,524355,590054,459013,524379,524315,589974,459029,524411,524347,590038,459021,524395,524331,590006,524299,524427,524363,590070,459011,524375,524311,524575,459027,524407,524343,590030,459019,524391,524327,589998,524295,524423,524359,590062,459015,524383,524319,589982,459031,524415,524351,590046,459023,524399,524335,590014,524303,524431,524367,590078,459008,524368,524304,524568,459024,524400,524336,590017,459016,524384,524320,589985,524288,524416,524352,590049,459012,524376,524312,589969,459028,524408,524344,590033,459020,524392,524328,590001,524296,524424,524360,590065,459010,524372,524308,524572,459026,524404,524340,590025,459018,524388,524324,589993,524292,524420,524356,590057,459014,524380,524316,589977,459030,524412,524348,590041,459022,524396,524332,590009,524300,524428,524364,590073,459009,524370,524306,524570,459025,524402,524338,590021,459017,524386,524322,589989,524290,524418,524354,590053,459013,524378,524314,589973,459029,524410,524346,590037,459021,524394,524330,590005,524298,524426,524362,590069,459011,524374,524310,524574,459027,524406,524342,590029,459019,524390,524326,589997,524294,524422,524358,590061,459015,524382,524318,589981,459031,524414,524350,590045,459023,524398,524334,590013,524302,524430,524366,590077,459008,524369,524305,524569,459024,524401,524337,590019,459016,524385,524321,589987,524289,524417,524353,590051,459012,524377,524313,589971,459028,524409,524345,590035,459020,524393,524329,590003,524297,524425,524361,590067,459010,524373,524309,524573,459026,524405,524341,590027,459018,524389,524325,589995,524293,524421,524357,590059,459014,524381,524317,589979,459030,524413,524349,590043,459022,524397,524333,590011,524301,524429,524365,590075,459009,524371,524307,524571,459025,524403,524339,590023,459017,524387,524323,589991,524291,524419,524355,590055,459013,524379,524315,589975,459029,524411,524347,590039,459021,524395,524331,590007,524299,524427,524363,590071,459011,524375,524311,524575,459027,524407,524343,590031,459019,524391,524327,589999,524295,524423,524359,590063,459015,524383,524319,589983,459031,524415,524351,590047,459023,524399,524335,590015,524303,524431,524367,590079]),9],a=[new Uint32Array([327680,327696,327688,327704,327684,327700,327692,327708,327682,327698,327690,327706,327686,327702,327694,0,327681,327697,327689,327705,327685,327701,327693,327709,327683,327699,327691,327707,327687,327703,327695,0]),5];return e.prototype=Object.create(i.prototype),e.prototype.getBits=function(e){for(var n,r=this.codeSize,s=this.codeBuf,i=this.bytes,o=this.bytesPos;e>r;)"undefined"==typeof(n=i[o++])&&t("Bad encoding in flate stream"),s|=n<<r,r+=8;return n=s&(1<<e)-1,this.codeBuf=s>>e,this.codeSize=r-=e,this.bytesPos=o,n},e.prototype.getCode=function(e){for(var n=e[0],r=e[1],s=this.codeSize,i=this.codeBuf,o=this.bytes,a=this.bytesPos;r>s;){var u;"undefined"==typeof(u=o[a++])&&t("Bad encoding in flate stream"),i|=u<<s,s+=8}var c=n[i&(1<<r)-1],l=c>>16,f=65535&c;return(0==s||l>s||0==l)&&t("Bad encoding in flate stream"),this.codeBuf=i>>l,this.codeSize=s-l,this.bytesPos=a,f},e.prototype.generateHuffmanTable=function(t){for(var e=t.length,n=0,r=0;e>r;++r)t[r]>n&&(n=t[r]);for(var s=1<<n,i=new Uint32Array(s),o=1,a=0,u=2;n>=o;++o,a<<=1,u<<=1)for(var c=0;e>c;++c)if(t[c]==o){for(var l=0,f=a,r=0;o>r;++r)l=l<<1|1&f,f>>=1;for(var r=l;s>r;r+=u)i[r]=o<<16|c;++a}return[i,n]},e.prototype.readBlock=function(){function e(t,e,n,r,s){for(var i=t.getBits(n)+r;i-->0;)e[k++]=s}var i=this.getBits(3);if(1&i&&(this.eof=!0),i>>=1,0==i){var u,c=this.bytes,l=this.bytesPos;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var f=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),f|=u<<8,"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream");var d=u;"undefined"==typeof(u=c[l++])&&t("Bad block header in flate stream"),d|=u<<8,d!=(65535&~f)&&t("Bad uncompressed block length in flate stream"),this.codeBuf=0,this.codeSize=0;var h=this.bufferLength,p=this.ensureBuffer(h+f),m=h+f;this.bufferLength=m;for(var w=h;m>w;++w){if("undefined"==typeof(u=c[l++])){this.eof=!0;break}p[w]=u}return void(this.bytesPos=l)}var g,y;if(1==i)g=o,y=a;else if(2==i){for(var v=this.getBits(5)+257,b=this.getBits(5)+1,q=this.getBits(4)+4,x=Array(n.length),k=0;q>k;)x[n[k++]]=this.getBits(3);for(var _=this.generateHuffmanTable(x),A=0,k=0,C=v+b,S=new Array(C);C>k;){var E=this.getCode(_);16==E?e(this,S,2,3,A):17==E?e(this,S,3,3,A=0):18==E?e(this,S,7,11,A=0):S[k++]=A=E}g=this.generateHuffmanTable(S.slice(0,v)),y=this.generateHuffmanTable(S.slice(v,C))}else t("Unknown block type in flate stream");for(var p=this.buffer,z=p?p.length:0,T=this.bufferLength;;){var I=this.getCode(g);if(256>I)T+1>=z&&(p=this.ensureBuffer(T+1),z=p.length),p[T++]=I;else{if(256==I)return void(this.bufferLength=T);I-=257,I=r[I];var B=I>>16;B>0&&(B=this.getBits(B));var A=(65535&I)+B;I=this.getCode(y),I=s[I],B=I>>16,B>0&&(B=this.getBits(B));var O=(65535&I)+B;T+A>=z&&(p=this.ensureBuffer(T+A),z=p.length);for(var P=0;A>P;++P,++T)p[T]=p[T-O]}}},e}();!function(t){var e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";"undefined"==typeof t.btoa&&(t.btoa=function(t){var n,r,s,i,o,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;do n=t.charCodeAt(l++),r=t.charCodeAt(l++),s=t.charCodeAt(l++),c=n<<16|r<<8|s,i=c>>18&63,o=c>>12&63,a=c>>6&63,u=63&c,h[f++]=e.charAt(i)+e.charAt(o)+e.charAt(a)+e.charAt(u);while(l<t.length);d=h.join("");var p=t.length%3;return(p?d.slice(0,p-3):d)+"===".slice(p||3)}),"undefined"==typeof t.atob&&(t.atob=function(t){var n,r,s,i,o,a,u,c,l=0,f=0,d="",h=[];if(!t)return t;t+="";do i=e.indexOf(t.charAt(l++)),o=e.indexOf(t.charAt(l++)),a=e.indexOf(t.charAt(l++)),u=e.indexOf(t.charAt(l++)),c=i<<18|o<<12|a<<6|u,n=c>>16&255,r=c>>8&255,s=255&c,h[f++]=64==a?String.fromCharCode(n):64==u?String.fromCharCode(n,r):String.fromCharCode(n,r,s);while(l<t.length);return d=h.join("")}),Array.prototype.map||(Array.prototype.map=function(t){if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var e=Object(this),n=e.length>>>0,r=new Array(n),s=arguments.length>1?arguments[1]:void 0,i=0;n>i;i++)i in e&&(r[i]=t.call(s,e[i],i,e));return r}),Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)}),Array.prototype.forEach||(Array.prototype.forEach=function(t,e){"use strict";if(void 0===this||null===this||"function"!=typeof t)throw new TypeError;for(var n=Object(this),r=n.length>>>0,s=0;r>s;s++)s in n&&t.call(e,n[s],s,n)}),Object.keys||(Object.keys=function(){"use strict";var t=Object.prototype.hasOwnProperty,e=!{toString:null}.propertyIsEnumerable("toString"),n=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],r=n.length;return function(s){if("object"!=typeof s&&("function"!=typeof s||null===s))throw new TypeError;var i,o,a=[];for(i in s)t.call(s,i)&&a.push(i);if(e)for(o=0;r>o;o++)t.call(s,n[o])&&a.push(n[o]);return a}}()),String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")}),String.prototype.trimLeft||(String.prototype.trimLeft=function(){return this.replace(/^\s+/g,"")}),String.prototype.trimRight||(String.prototype.trimRight=function(){return this.replace(/\s+$/g,"")})}("undefined"!=typeof self&&self||"undefined"!=typeof window&&window||this)}({},function(){return this}());
force-app/main/default/staticresources/jspdf.resource-meta.xml
New file
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<StaticResource xmlns="http://soap.sforce.com/2006/04/metadata">
    <cacheControl>Public</cacheControl>
    <contentType>text/javascript</contentType>
    <description>jspdf</description>
</StaticResource>