{"diffoscope-json-version": 1, "source1": "/input1", "source2": "/input2", "unified_diff": null, "details": [{"source1": "zipinfo {}", "source2": "zipinfo {}", "unified_diff": "@@ -1,35 +1,35 @@\n-Zip file size: 106969 bytes, number of entries: 33\n+Zip file size: 108780 bytes, number of entries: 33\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/\n -rw----     2.0 fat     2767 bX stor 70-Jan-01 00:00 META-INF/DEPENDENCIES\n -rw----     2.0 fat    11358 bX stor 70-Jan-01 00:00 META-INF/LICENSE\n -rw----     2.0 fat       25 bX stor 70-Jan-01 00:00 META-INF/MANIFEST.MF\n -rw----     2.0 fat      178 bX stor 70-Jan-01 00:00 META-INF/NOTICE\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/dubbo/internal/\n -rw----     2.0 fat      133 bX stor 70-Jan-01 00:00 META-INF/dubbo/internal/org.apache.dubbo.remoting.Transporter\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/\n -rw----     2.0 fat        0 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.properties\n--rw----     2.0 fat     2399 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml\n+-rw----     2.0 fat     2340 bX stor 70-Jan-01 00:00 META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/remoting/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/\n -rw----     2.0 fat    10214 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyBackedChannelBuffer.java\n--rw----     2.0 fat     8769 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyChannel.java\n--rw----     2.0 fat     9286 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyClient.java\n--rw----     2.0 fat     6249 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java\n--rw----     2.0 fat     3547 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java\n--rw----     2.0 fat     2654 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java\n--rw----     2.0 fat     7939 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyServer.java\n--rw----     2.0 fat     5243 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java\n--rw----     2.0 fat     1614 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java\n--rw----     2.0 fat     5550 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/SslContexts.java\n--rw----     2.0 fat     5835 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java\n+-rw----     2.0 fat     9045 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyChannel.java\n+-rw----     2.0 fat     9503 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyClient.java\n+-rw----     2.0 fat     6410 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java\n+-rw----     2.0 fat     3648 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java\n+-rw----     2.0 fat     2714 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java\n+-rw----     2.0 fat     8141 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyServer.java\n+-rw----     2.0 fat     5381 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java\n+-rw----     2.0 fat     1657 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java\n+-rw----     2.0 fat     5671 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/SslContexts.java\n+-rw----     2.0 fat     5976 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java\n -rw----     2.0 fat        0 bx stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/logging/\n -rw----     2.0 fat     2243 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/logging/FormattingTuple.java\n--rw----     2.0 fat    14622 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java\n-33 files, 100625 bytes uncompressed, 100625 bytes compressed:  0.0%\n+-rw----     2.0 fat    15032 bX stor 70-Jan-01 00:00 org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java\n+33 files, 102436 bytes uncompressed, 102436 bytes compressed:  0.0%\n"}, {"source1": "zipdetails --redact --scan --utc {}", "source2": "zipdetails --redact --scan --utc {}", "unified_diff": "@@ -312,1512 +312,1512 @@\n #\n 03C6A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n 03C6C   Length              0005 (5)\n 03C6E   Flags               01 (1) 'Modification'\n 03C6F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n 03C73 PAYLOAD\n \n-045D2 DATA DESCRIPTOR       08074B50 (134695760)\n-045D6 CRC                   2E65EAC2 (778431170)\n-045DA Compressed Size       0000095F (2399)\n-045DE Uncompressed Size     0000095F (2399)\n-\n-045E2 LOCAL HEADER #14      04034B50 (67324752)\n-045E6 Extract Zip Spec      14 (20) '2.0'\n-045E7 Extract OS            00 (0) 'MS-DOS'\n-045E8 General Purpose Flag  0000 (0)\n-045EA Compression Method    0000 (0) 'Stored'\n-045EC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-045F0 CRC                   00000000 (0)\n-045F4 Compressed Size       00000000 (0)\n-045F8 Uncompressed Size     00000000 (0)\n-045FC Filename Length       0004 (4)\n-045FE Extra Length          0009 (9)\n-04600 Filename              'XXXX'\n-#\n-# WARNING: Offset 0x4600: Filename 'XXXX'\n-#          Zero length filename\n-#\n-04604 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-04606   Length              0005 (5)\n-04608   Flags               01 (1) 'Modification'\n-04609   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-0460D LOCAL HEADER #15      04034B50 (67324752)\n-04611 Extract Zip Spec      14 (20) '2.0'\n-04612 Extract OS            00 (0) 'MS-DOS'\n-04613 General Purpose Flag  0000 (0)\n-04615 Compression Method    0000 (0) 'Stored'\n-04617 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0461B CRC                   00000000 (0)\n-0461F Compressed Size       00000000 (0)\n-04623 Uncompressed Size     00000000 (0)\n-04627 Filename Length       000B (11)\n-04629 Extra Length          0009 (9)\n-0462B Filename              'XXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x462B: Filename 'XXXXXXXXXXX'\n-#          Zero length filename\n-#\n-04636 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-04638   Length              0005 (5)\n-0463A   Flags               01 (1) 'Modification'\n-0463B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-0463F LOCAL HEADER #16      04034B50 (67324752)\n-04643 Extract Zip Spec      14 (20) '2.0'\n-04644 Extract OS            00 (0) 'MS-DOS'\n-04645 General Purpose Flag  0000 (0)\n-04647 Compression Method    0000 (0) 'Stored'\n-04649 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0464D CRC                   00000000 (0)\n-04651 Compressed Size       00000000 (0)\n-04655 Uncompressed Size     00000000 (0)\n-04659 Filename Length       0011 (17)\n-0465B Extra Length          0009 (9)\n-0465D Filename              'XXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x465D: Filename 'XXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0466E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-04670   Length              0005 (5)\n-04672   Flags               01 (1) 'Modification'\n-04673   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-04677 LOCAL HEADER #17      04034B50 (67324752)\n-0467B Extract Zip Spec      14 (20) '2.0'\n-0467C Extract OS            00 (0) 'MS-DOS'\n-0467D General Purpose Flag  0000 (0)\n-0467F Compression Method    0000 (0) 'Stored'\n-04681 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-04685 CRC                   00000000 (0)\n-04689 Compressed Size       00000000 (0)\n-0468D Uncompressed Size     00000000 (0)\n-04691 Filename Length       001A (26)\n-04693 Extra Length          0009 (9)\n-04695 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x4695: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-046AF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-046B1   Length              0005 (5)\n-046B3   Flags               01 (1) 'Modification'\n-046B4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-046B8 LOCAL HEADER #18      04034B50 (67324752)\n-046BC Extract Zip Spec      14 (20) '2.0'\n-046BD Extract OS            00 (0) 'MS-DOS'\n-046BE General Purpose Flag  0000 (0)\n-046C0 Compression Method    0000 (0) 'Stored'\n-046C2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-046C6 CRC                   00000000 (0)\n-046CA Compressed Size       00000000 (0)\n-046CE Uncompressed Size     00000000 (0)\n-046D2 Filename Length       0024 (36)\n-046D4 Extra Length          0009 (9)\n-046D6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x46D6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-046FA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-046FC   Length              0005 (5)\n-046FE   Flags               01 (1) 'Modification'\n-046FF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-04703 LOCAL HEADER #19      04034B50 (67324752)\n-04707 Extract Zip Spec      14 (20) '2.0'\n-04708 Extract OS            00 (0) 'MS-DOS'\n-04709 General Purpose Flag  0000 (0)\n-0470B Compression Method    0000 (0) 'Stored'\n-0470D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-04711 CRC                   00000000 (0)\n-04715 Compressed Size       00000000 (0)\n-04719 Uncompressed Size     00000000 (0)\n-0471D Filename Length       002B (43)\n-0471F Extra Length          0009 (9)\n-04721 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x4721: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0474C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0474E   Length              0005 (5)\n-04750   Flags               01 (1) 'Modification'\n-04751   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-04755 LOCAL HEADER #20      04034B50 (67324752)\n-04759 Extract Zip Spec      14 (20) '2.0'\n-0475A Extract OS            00 (0) 'MS-DOS'\n-0475B General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0475D Compression Method    0000 (0) 'Stored'\n-0475F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-04763 CRC                   00000000 (0)\n-04767 Compressed Size       00000000 (0)\n-0476B Uncompressed Size     00000000 (0)\n-0476F Filename Length       0048 (72)\n-04771 Extra Length          0009 (9)\n-04773 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x4773: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-047BB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-047BD   Length              0005 (5)\n-047BF   Flags               01 (1) 'Modification'\n-047C0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-047C4 PAYLOAD\n-\n-06FAA DATA DESCRIPTOR       08074B50 (134695760)\n-06FAE CRC                   73E7CE8A (1944571530)\n-06FB2 Compressed Size       000027E6 (10214)\n-06FB6 Uncompressed Size     000027E6 (10214)\n-\n-06FBA LOCAL HEADER #21      04034B50 (67324752)\n-06FBE Extract Zip Spec      14 (20) '2.0'\n-06FBF Extract OS            00 (0) 'MS-DOS'\n-06FC0 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-06FC2 Compression Method    0000 (0) 'Stored'\n-06FC4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-06FC8 CRC                   00000000 (0)\n-06FCC Compressed Size       00000000 (0)\n-06FD0 Uncompressed Size     00000000 (0)\n-06FD4 Filename Length       003C (60)\n-06FD6 Extra Length          0009 (9)\n-06FD8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x6FD8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-07014 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-07016   Length              0005 (5)\n-07018   Flags               01 (1) 'Modification'\n-07019   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0701D PAYLOAD\n-\n-0925E DATA DESCRIPTOR       08074B50 (134695760)\n-09262 CRC                   CD460ADB (3443919579)\n-09266 Compressed Size       00002241 (8769)\n-0926A Uncompressed Size     00002241 (8769)\n-\n-0926E LOCAL HEADER #22      04034B50 (67324752)\n-09272 Extract Zip Spec      14 (20) '2.0'\n-09273 Extract OS            00 (0) 'MS-DOS'\n-09274 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-09276 Compression Method    0000 (0) 'Stored'\n-09278 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0927C CRC                   00000000 (0)\n-09280 Compressed Size       00000000 (0)\n-09284 Uncompressed Size     00000000 (0)\n-09288 Filename Length       003B (59)\n-0928A Extra Length          0009 (9)\n-0928C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x928C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-092C7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-092C9   Length              0005 (5)\n-092CB   Flags               01 (1) 'Modification'\n-092CC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-092D0 PAYLOAD\n-\n-0B716 DATA DESCRIPTOR       08074B50 (134695760)\n-0B71A CRC                   17148ACF (387222223)\n-0B71E Compressed Size       00002446 (9286)\n-0B722 Uncompressed Size     00002446 (9286)\n-\n-0B726 LOCAL HEADER #23      04034B50 (67324752)\n-0B72A Extract Zip Spec      14 (20) '2.0'\n-0B72B Extract OS            00 (0) 'MS-DOS'\n-0B72C General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0B72E Compression Method    0000 (0) 'Stored'\n-0B730 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0B734 CRC                   00000000 (0)\n-0B738 Compressed Size       00000000 (0)\n-0B73C Uncompressed Size     00000000 (0)\n-0B740 Filename Length       0042 (66)\n-0B742 Extra Length          0009 (9)\n-0B744 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xB744: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0B786 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0B788   Length              0005 (5)\n-0B78A   Flags               01 (1) 'Modification'\n-0B78B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0B78F PAYLOAD\n-\n-0CFF8 DATA DESCRIPTOR       08074B50 (134695760)\n-0CFFC CRC                   15F2B7F5 (368228341)\n-0D000 Compressed Size       00001869 (6249)\n-0D004 Uncompressed Size     00001869 (6249)\n-\n-0D008 LOCAL HEADER #24      04034B50 (67324752)\n-0D00C Extract Zip Spec      14 (20) '2.0'\n-0D00D Extract OS            00 (0) 'MS-DOS'\n-0D00E General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0D010 Compression Method    0000 (0) 'Stored'\n-0D012 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0D016 CRC                   00000000 (0)\n-0D01A Compressed Size       00000000 (0)\n-0D01E Uncompressed Size     00000000 (0)\n-0D022 Filename Length       0041 (65)\n-0D024 Extra Length          0009 (9)\n-0D026 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xD026: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0D067 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0D069   Length              0005 (5)\n-0D06B   Flags               01 (1) 'Modification'\n-0D06C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0D070 PAYLOAD\n-\n-0DE4B DATA DESCRIPTOR       08074B50 (134695760)\n-0DE4F CRC                   BA9CD18D (3130839437)\n-0DE53 Compressed Size       00000DDB (3547)\n-0DE57 Uncompressed Size     00000DDB (3547)\n-\n-0DE5B LOCAL HEADER #25      04034B50 (67324752)\n-0DE5F Extract Zip Spec      14 (20) '2.0'\n-0DE60 Extract OS            00 (0) 'MS-DOS'\n-0DE61 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0DE63 Compression Method    0000 (0) 'Stored'\n-0DE65 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0DE69 CRC                   00000000 (0)\n-0DE6D Compressed Size       00000000 (0)\n-0DE71 Uncompressed Size     00000000 (0)\n-0DE75 Filename Length       0045 (69)\n-0DE77 Extra Length          0009 (9)\n-0DE79 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xDE79: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0DEBE Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0DEC0   Length              0005 (5)\n-0DEC2   Flags               01 (1) 'Modification'\n-0DEC3   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0DEC7 PAYLOAD\n-\n-0E925 DATA DESCRIPTOR       08074B50 (134695760)\n-0E929 CRC                   16F071B0 (384856496)\n-0E92D Compressed Size       00000A5E (2654)\n-0E931 Uncompressed Size     00000A5E (2654)\n-\n-0E935 LOCAL HEADER #26      04034B50 (67324752)\n-0E939 Extract Zip Spec      14 (20) '2.0'\n-0E93A Extract OS            00 (0) 'MS-DOS'\n-0E93B General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-0E93D Compression Method    0000 (0) 'Stored'\n-0E93F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-0E943 CRC                   00000000 (0)\n-0E947 Compressed Size       00000000 (0)\n-0E94B Uncompressed Size     00000000 (0)\n-0E94F Filename Length       003B (59)\n-0E951 Extra Length          0009 (9)\n-0E953 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0xE953: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-0E98E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-0E990   Length              0005 (5)\n-0E992   Flags               01 (1) 'Modification'\n-0E993   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-0E997 PAYLOAD\n-\n-1089A DATA DESCRIPTOR       08074B50 (134695760)\n-1089E CRC                   99FF093E (2583628094)\n-108A2 Compressed Size       00001F03 (7939)\n-108A6 Uncompressed Size     00001F03 (7939)\n-\n-108AA LOCAL HEADER #27      04034B50 (67324752)\n-108AE Extract Zip Spec      14 (20) '2.0'\n-108AF Extract OS            00 (0) 'MS-DOS'\n-108B0 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-108B2 Compression Method    0000 (0) 'Stored'\n-108B4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-108B8 CRC                   00000000 (0)\n-108BC Compressed Size       00000000 (0)\n-108C0 Uncompressed Size     00000000 (0)\n-108C4 Filename Length       0042 (66)\n-108C6 Extra Length          0009 (9)\n-108C8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x108C8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1090A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1090C   Length              0005 (5)\n-1090E   Flags               01 (1) 'Modification'\n-1090F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-10913 PAYLOAD\n-\n-11D8E DATA DESCRIPTOR       08074B50 (134695760)\n-11D92 CRC                   7ED127C7 (2127636423)\n-11D96 Compressed Size       0000147B (5243)\n-11D9A Uncompressed Size     0000147B (5243)\n-\n-11D9E LOCAL HEADER #28      04034B50 (67324752)\n-11DA2 Extract Zip Spec      14 (20) '2.0'\n-11DA3 Extract OS            00 (0) 'MS-DOS'\n-11DA4 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-11DA6 Compression Method    0000 (0) 'Stored'\n-11DA8 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-11DAC CRC                   00000000 (0)\n-11DB0 Compressed Size       00000000 (0)\n-11DB4 Uncompressed Size     00000000 (0)\n-11DB8 Filename Length       0040 (64)\n-11DBA Extra Length          0009 (9)\n-11DBC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x11DBC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-11DFC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-11DFE   Length              0005 (5)\n-11E00   Flags               01 (1) 'Modification'\n-11E01   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-11E05 PAYLOAD\n-\n-12453 DATA DESCRIPTOR       08074B50 (134695760)\n-12457 CRC                   4AAC1D37 (1252793655)\n-1245B Compressed Size       0000064E (1614)\n-1245F Uncompressed Size     0000064E (1614)\n-\n-12463 LOCAL HEADER #29      04034B50 (67324752)\n-12467 Extract Zip Spec      14 (20) '2.0'\n-12468 Extract OS            00 (0) 'MS-DOS'\n-12469 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1246B Compression Method    0000 (0) 'Stored'\n-1246D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-12471 CRC                   00000000 (0)\n-12475 Compressed Size       00000000 (0)\n-12479 Uncompressed Size     00000000 (0)\n-1247D Filename Length       003B (59)\n-1247F Extra Length          0009 (9)\n-12481 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x12481: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-124BC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-124BE   Length              0005 (5)\n-124C0   Flags               01 (1) 'Modification'\n-124C1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-124C5 PAYLOAD\n-\n-13A73 DATA DESCRIPTOR       08074B50 (134695760)\n-13A77 CRC                   155577E8 (357922792)\n-13A7B Compressed Size       000015AE (5550)\n-13A7F Uncompressed Size     000015AE (5550)\n-\n-13A83 LOCAL HEADER #30      04034B50 (67324752)\n-13A87 Extract Zip Spec      14 (20) '2.0'\n-13A88 Extract OS            00 (0) 'MS-DOS'\n-13A89 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-13A8B Compression Method    0000 (0) 'Stored'\n-13A8D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-13A91 CRC                   00000000 (0)\n-13A95 Compressed Size       00000000 (0)\n-13A99 Uncompressed Size     00000000 (0)\n-13A9D Filename Length       0045 (69)\n-13A9F Extra Length          0009 (9)\n-13AA1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x13AA1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-13AE6 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-13AE8   Length              0005 (5)\n-13AEA   Flags               01 (1) 'Modification'\n-13AEB   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-13AEF PAYLOAD\n-\n-151BA DATA DESCRIPTOR       08074B50 (134695760)\n-151BE CRC                   FC50D2E5 (4233155301)\n-151C2 Compressed Size       000016CB (5835)\n-151C6 Uncompressed Size     000016CB (5835)\n-\n-151CA LOCAL HEADER #31      04034B50 (67324752)\n-151CE Extract Zip Spec      14 (20) '2.0'\n-151CF Extract OS            00 (0) 'MS-DOS'\n-151D0 General Purpose Flag  0000 (0)\n-151D2 Compression Method    0000 (0) 'Stored'\n-151D4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-151D8 CRC                   00000000 (0)\n-151DC Compressed Size       00000000 (0)\n-151E0 Uncompressed Size     00000000 (0)\n-151E4 Filename Length       0033 (51)\n-151E6 Extra Length          0009 (9)\n-151E8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x151E8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1521B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1521D   Length              0005 (5)\n-1521F   Flags               01 (1) 'Modification'\n-15220   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-15224 LOCAL HEADER #32      04034B50 (67324752)\n-15228 Extract Zip Spec      14 (20) '2.0'\n-15229 Extract OS            00 (0) 'MS-DOS'\n-1522A General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1522C Compression Method    0000 (0) 'Stored'\n-1522E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-15232 CRC                   00000000 (0)\n-15236 Compressed Size       00000000 (0)\n-1523A Uncompressed Size     00000000 (0)\n-1523E Filename Length       0047 (71)\n-15240 Extra Length          0009 (9)\n-15242 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x15242: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-15289 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1528B   Length              0005 (5)\n-1528D   Flags               01 (1) 'Modification'\n-1528E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-15292 PAYLOAD\n-\n-15B55 DATA DESCRIPTOR       08074B50 (134695760)\n-15B59 CRC                   58FEAB57 (1493085015)\n-15B5D Compressed Size       000008C3 (2243)\n-15B61 Uncompressed Size     000008C3 (2243)\n-\n-15B65 LOCAL HEADER #33      04034B50 (67324752)\n-15B69 Extract Zip Spec      14 (20) '2.0'\n-15B6A Extract OS            00 (0) 'MS-DOS'\n-15B6B General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-15B6D Compression Method    0000 (0) 'Stored'\n-15B6F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-15B73 CRC                   00000000 (0)\n-15B77 Compressed Size       00000000 (0)\n-15B7B Uncompressed Size     00000000 (0)\n-15B7F Filename Length       0048 (72)\n-15B81 Extra Length          0009 (9)\n-15B83 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x15B83: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-15BCB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-15BCD   Length              0005 (5)\n-15BCF   Flags               01 (1) 'Modification'\n-15BD0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-15BD4 PAYLOAD\n-\n-194F2 DATA DESCRIPTOR       08074B50 (134695760)\n-194F6 CRC                   BC1F87C6 (3156182982)\n-194FA Compressed Size       0000391E (14622)\n-194FE Uncompressed Size     0000391E (14622)\n-\n-19502 CENTRAL HEADER #1     02014B50 (33639248)\n-19506 Created Zip Spec      14 (20) '2.0'\n-19507 Created OS            00 (0) 'MS-DOS'\n-19508 Extract Zip Spec      14 (20) '2.0'\n-19509 Extract OS            00 (0) 'MS-DOS'\n-1950A General Purpose Flag  0000 (0)\n-1950C Compression Method    0000 (0) 'Stored'\n-1950E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19512 CRC                   00000000 (0)\n-19516 Compressed Size       00000000 (0)\n-1951A Uncompressed Size     00000000 (0)\n-1951E Filename Length       0009 (9)\n-19520 Extra Length          0009 (9)\n-19522 Comment Length        0000 (0)\n-19524 Disk Start            0000 (0)\n-19526 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19528 Ext File Attributes   00000000 (0)\n-1952C Local Header Offset   00000000 (0)\n-19530 Filename              'XXXXXXXXX'\n-#\n-# WARNING: Offset 0x19530: Filename 'XXXXXXXXX'\n-#          Zero length filename\n-#\n-19539 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1953B   Length              0005 (5)\n-1953D   Flags               01 (1) 'Modification'\n-1953E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19542 CENTRAL HEADER #2     02014B50 (33639248)\n-19546 Created Zip Spec      14 (20) '2.0'\n-19547 Created OS            00 (0) 'MS-DOS'\n-19548 Extract Zip Spec      14 (20) '2.0'\n-19549 Extract OS            00 (0) 'MS-DOS'\n-1954A General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1954C Compression Method    0000 (0) 'Stored'\n-1954E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19552 CRC                   0F83987F (260282495)\n-19556 Compressed Size       00000ACF (2767)\n-1955A Uncompressed Size     00000ACF (2767)\n-1955E Filename Length       0015 (21)\n-19560 Extra Length          0009 (9)\n-19562 Comment Length        0000 (0)\n-19564 Disk Start            0000 (0)\n-19566 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19568 Ext File Attributes   00000000 (0)\n-1956C Local Header Offset   00000030 (48)\n-19570 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19570: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19585 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19587   Length              0005 (5)\n-19589   Flags               01 (1) 'Modification'\n-1958A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1958E CENTRAL HEADER #3     02014B50 (33639248)\n-19592 Created Zip Spec      14 (20) '2.0'\n-19593 Created OS            00 (0) 'MS-DOS'\n-19594 Extract Zip Spec      14 (20) '2.0'\n-19595 Extract OS            00 (0) 'MS-DOS'\n-19596 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19598 Compression Method    0000 (0) 'Stored'\n-1959A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1959E CRC                   86E2B4B4 (2263004340)\n-195A2 Compressed Size       00002C5E (11358)\n-195A6 Uncompressed Size     00002C5E (11358)\n-195AA Filename Length       0010 (16)\n-195AC Extra Length          0009 (9)\n-195AE Comment Length        0000 (0)\n-195B0 Disk Start            0000 (0)\n-195B2 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-195B4 Ext File Attributes   00000000 (0)\n-195B8 Local Header Offset   00000B4B (2891)\n-195BC Filename              'XXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x195BC: Filename 'XXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-195CC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-195CE   Length              0005 (5)\n-195D0   Flags               01 (1) 'Modification'\n-195D1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-195D5 CENTRAL HEADER #4     02014B50 (33639248)\n-195D9 Created Zip Spec      14 (20) '2.0'\n-195DA Created OS            00 (0) 'MS-DOS'\n-195DB Extract Zip Spec      14 (20) '2.0'\n-195DC Extract OS            00 (0) 'MS-DOS'\n-195DD General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-195DF Compression Method    0000 (0) 'Stored'\n-195E1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-195E5 CRC                   EE027FB2 (3993141170)\n-195E9 Compressed Size       00000019 (25)\n-195ED Uncompressed Size     00000019 (25)\n-195F1 Filename Length       0014 (20)\n-195F3 Extra Length          0009 (9)\n-195F5 Comment Length        0000 (0)\n-195F7 Disk Start            0000 (0)\n-195F9 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-195FB Ext File Attributes   00000000 (0)\n-195FF Local Header Offset   000037F0 (14320)\n-19603 Filename              'XXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19603: Filename 'XXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19617 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19619   Length              0005 (5)\n-1961B   Flags               01 (1) 'Modification'\n-1961C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19620 CENTRAL HEADER #5     02014B50 (33639248)\n-19624 Created Zip Spec      14 (20) '2.0'\n-19625 Created OS            00 (0) 'MS-DOS'\n-19626 Extract Zip Spec      14 (20) '2.0'\n-19627 Extract OS            00 (0) 'MS-DOS'\n-19628 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1962A Compression Method    0000 (0) 'Stored'\n-1962C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19630 CRC                   5A29D305 (1512690437)\n-19634 Compressed Size       000000B2 (178)\n-19638 Uncompressed Size     000000B2 (178)\n-1963C Filename Length       000F (15)\n-1963E Extra Length          0009 (9)\n-19640 Comment Length        0000 (0)\n-19642 Disk Start            0000 (0)\n-19644 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19646 Ext File Attributes   00000000 (0)\n-1964A Local Header Offset   00003854 (14420)\n-1964E Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1964E: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1965D Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1965F   Length              0005 (5)\n-19661   Flags               01 (1) 'Modification'\n-19662   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19666 CENTRAL HEADER #6     02014B50 (33639248)\n-1966A Created Zip Spec      14 (20) '2.0'\n-1966B Created OS            00 (0) 'MS-DOS'\n-1966C Extract Zip Spec      14 (20) '2.0'\n-1966D Extract OS            00 (0) 'MS-DOS'\n-1966E General Purpose Flag  0000 (0)\n-19670 Compression Method    0000 (0) 'Stored'\n-19672 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19676 CRC                   00000000 (0)\n-1967A Compressed Size       00000000 (0)\n-1967E Uncompressed Size     00000000 (0)\n-19682 Filename Length       000F (15)\n-19684 Extra Length          0009 (9)\n-19686 Comment Length        0000 (0)\n-19688 Disk Start            0000 (0)\n-1968A Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1968C Ext File Attributes   00000000 (0)\n-19690 Local Header Offset   0000394C (14668)\n-19694 Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19694: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-196A3 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-196A5   Length              0005 (5)\n-196A7   Flags               01 (1) 'Modification'\n-196A8   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-196AC CENTRAL HEADER #7     02014B50 (33639248)\n-196B0 Created Zip Spec      14 (20) '2.0'\n-196B1 Created OS            00 (0) 'MS-DOS'\n-196B2 Extract Zip Spec      14 (20) '2.0'\n-196B3 Extract OS            00 (0) 'MS-DOS'\n-196B4 General Purpose Flag  0000 (0)\n-196B6 Compression Method    0000 (0) 'Stored'\n-196B8 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-196BC CRC                   00000000 (0)\n-196C0 Compressed Size       00000000 (0)\n-196C4 Uncompressed Size     00000000 (0)\n-196C8 Filename Length       0018 (24)\n-196CA Extra Length          0009 (9)\n-196CC Comment Length        0000 (0)\n-196CE Disk Start            0000 (0)\n-196D0 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-196D2 Ext File Attributes   00000000 (0)\n-196D6 Local Header Offset   00003982 (14722)\n-196DA Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x196DA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-196F2 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-196F4   Length              0005 (5)\n-196F6   Flags               01 (1) 'Modification'\n-196F7   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-196FB CENTRAL HEADER #8     02014B50 (33639248)\n-196FF Created Zip Spec      14 (20) '2.0'\n-19700 Created OS            00 (0) 'MS-DOS'\n-19701 Extract Zip Spec      14 (20) '2.0'\n-19702 Extract OS            00 (0) 'MS-DOS'\n-19703 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19705 Compression Method    0000 (0) 'Stored'\n-19707 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1970B CRC                   8F7CA09F (2407309471)\n-1970F Compressed Size       00000085 (133)\n-19713 Uncompressed Size     00000085 (133)\n-19717 Filename Length       003D (61)\n-19719 Extra Length          0009 (9)\n-1971B Comment Length        0000 (0)\n-1971D Disk Start            0000 (0)\n-1971F Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19721 Ext File Attributes   00000000 (0)\n-19725 Local Header Offset   000039C1 (14785)\n-19729 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19729: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19766 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19768   Length              0005 (5)\n-1976A   Flags               01 (1) 'Modification'\n-1976B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1976F CENTRAL HEADER #9     02014B50 (33639248)\n-19773 Created Zip Spec      14 (20) '2.0'\n-19774 Created OS            00 (0) 'MS-DOS'\n-19775 Extract Zip Spec      14 (20) '2.0'\n-19776 Extract OS            00 (0) 'MS-DOS'\n-19777 General Purpose Flag  0000 (0)\n-19779 Compression Method    0000 (0) 'Stored'\n-1977B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1977F CRC                   00000000 (0)\n-19783 Compressed Size       00000000 (0)\n-19787 Uncompressed Size     00000000 (0)\n-1978B Filename Length       000F (15)\n-1978D Extra Length          0009 (9)\n-1978F Comment Length        0000 (0)\n-19791 Disk Start            0000 (0)\n-19793 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19795 Ext File Attributes   00000000 (0)\n-19799 Local Header Offset   00003ABA (15034)\n-1979D Filename              'XXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1979D: Filename 'XXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-197AC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-197AE   Length              0005 (5)\n-197B0   Flags               01 (1) 'Modification'\n-197B1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-197B5 CENTRAL HEADER #10    02014B50 (33639248)\n-197B9 Created Zip Spec      14 (20) '2.0'\n-197BA Created OS            00 (0) 'MS-DOS'\n-197BB Extract Zip Spec      14 (20) '2.0'\n-197BC Extract OS            00 (0) 'MS-DOS'\n-197BD General Purpose Flag  0000 (0)\n-197BF Compression Method    0000 (0) 'Stored'\n-197C1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-197C5 CRC                   00000000 (0)\n-197C9 Compressed Size       00000000 (0)\n-197CD Uncompressed Size     00000000 (0)\n-197D1 Filename Length       0020 (32)\n-197D3 Extra Length          0009 (9)\n-197D5 Comment Length        0000 (0)\n-197D7 Disk Start            0000 (0)\n-197D9 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-197DB Ext File Attributes   00000000 (0)\n-197DF Local Header Offset   00003AF0 (15088)\n-197E3 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x197E3: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19803 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19805   Length              0005 (5)\n-19807   Flags               01 (1) 'Modification'\n-19808   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1980C CENTRAL HEADER #11    02014B50 (33639248)\n-19810 Created Zip Spec      14 (20) '2.0'\n-19811 Created OS            00 (0) 'MS-DOS'\n-19812 Extract Zip Spec      14 (20) '2.0'\n-19813 Extract OS            00 (0) 'MS-DOS'\n-19814 General Purpose Flag  0000 (0)\n-19816 Compression Method    0000 (0) 'Stored'\n-19818 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1981C CRC                   00000000 (0)\n-19820 Compressed Size       00000000 (0)\n-19824 Uncompressed Size     00000000 (0)\n-19828 Filename Length       0036 (54)\n-1982A Extra Length          0009 (9)\n-1982C Comment Length        0000 (0)\n-1982E Disk Start            0000 (0)\n-19830 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19832 Ext File Attributes   00000000 (0)\n-19836 Local Header Offset   00003B37 (15159)\n-1983A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1983A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19870 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19872   Length              0005 (5)\n-19874   Flags               01 (1) 'Modification'\n-19875   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19879 CENTRAL HEADER #12    02014B50 (33639248)\n-1987D Created Zip Spec      14 (20) '2.0'\n-1987E Created OS            00 (0) 'MS-DOS'\n-1987F Extract Zip Spec      14 (20) '2.0'\n-19880 Extract OS            00 (0) 'MS-DOS'\n-19881 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19883 Compression Method    0000 (0) 'Stored'\n-19885 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19889 CRC                   00000000 (0)\n-1988D Compressed Size       00000000 (0)\n-19891 Uncompressed Size     00000000 (0)\n-19895 Filename Length       0044 (68)\n-19897 Extra Length          0009 (9)\n-19899 Comment Length        0000 (0)\n-1989B Disk Start            0000 (0)\n-1989D Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1989F Ext File Attributes   00000000 (0)\n-198A3 Local Header Offset   00003B94 (15252)\n-198A7 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x198A7: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-198EB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-198ED   Length              0005 (5)\n-198EF   Flags               01 (1) 'Modification'\n-198F0   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-198F4 CENTRAL HEADER #13    02014B50 (33639248)\n-198F8 Created Zip Spec      14 (20) '2.0'\n-198F9 Created OS            00 (0) 'MS-DOS'\n-198FA Extract Zip Spec      14 (20) '2.0'\n-198FB Extract OS            00 (0) 'MS-DOS'\n-198FC General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-198FE Compression Method    0000 (0) 'Stored'\n-19900 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19904 CRC                   2E65EAC2 (778431170)\n-19908 Compressed Size       0000095F (2399)\n-1990C Uncompressed Size     0000095F (2399)\n-19910 Filename Length       003D (61)\n-19912 Extra Length          0009 (9)\n-19914 Comment Length        0000 (0)\n-19916 Disk Start            0000 (0)\n-19918 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1991A Ext File Attributes   00000000 (0)\n-1991E Local Header Offset   00003C0F (15375)\n-19922 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19922: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1995F Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19961   Length              0005 (5)\n-19963   Flags               01 (1) 'Modification'\n-19964   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19968 CENTRAL HEADER #14    02014B50 (33639248)\n-1996C Created Zip Spec      14 (20) '2.0'\n-1996D Created OS            00 (0) 'MS-DOS'\n-1996E Extract Zip Spec      14 (20) '2.0'\n-1996F Extract OS            00 (0) 'MS-DOS'\n-19970 General Purpose Flag  0000 (0)\n-19972 Compression Method    0000 (0) 'Stored'\n-19974 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19978 CRC                   00000000 (0)\n-1997C Compressed Size       00000000 (0)\n-19980 Uncompressed Size     00000000 (0)\n-19984 Filename Length       0004 (4)\n-19986 Extra Length          0009 (9)\n-19988 Comment Length        0000 (0)\n-1998A Disk Start            0000 (0)\n-1998C Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1998E Ext File Attributes   00000000 (0)\n-19992 Local Header Offset   000045E2 (17890)\n-19996 Filename              'XXXX'\n-#\n-# WARNING: Offset 0x19996: Filename 'XXXX'\n-#          Zero length filename\n-#\n-1999A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1999C   Length              0005 (5)\n-1999E   Flags               01 (1) 'Modification'\n-1999F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-199A3 CENTRAL HEADER #15    02014B50 (33639248)\n-199A7 Created Zip Spec      14 (20) '2.0'\n-199A8 Created OS            00 (0) 'MS-DOS'\n-199A9 Extract Zip Spec      14 (20) '2.0'\n-199AA Extract OS            00 (0) 'MS-DOS'\n-199AB General Purpose Flag  0000 (0)\n-199AD Compression Method    0000 (0) 'Stored'\n-199AF Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-199B3 CRC                   00000000 (0)\n-199B7 Compressed Size       00000000 (0)\n-199BB Uncompressed Size     00000000 (0)\n-199BF Filename Length       000B (11)\n-199C1 Extra Length          0009 (9)\n-199C3 Comment Length        0000 (0)\n-199C5 Disk Start            0000 (0)\n-199C7 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-199C9 Ext File Attributes   00000000 (0)\n-199CD Local Header Offset   0000460D (17933)\n-199D1 Filename              'XXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x199D1: Filename 'XXXXXXXXXXX'\n-#          Zero length filename\n-#\n-199DC Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-199DE   Length              0005 (5)\n-199E0   Flags               01 (1) 'Modification'\n-199E1   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-199E5 CENTRAL HEADER #16    02014B50 (33639248)\n-199E9 Created Zip Spec      14 (20) '2.0'\n-199EA Created OS            00 (0) 'MS-DOS'\n-199EB Extract Zip Spec      14 (20) '2.0'\n-199EC Extract OS            00 (0) 'MS-DOS'\n-199ED General Purpose Flag  0000 (0)\n-199EF Compression Method    0000 (0) 'Stored'\n-199F1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-199F5 CRC                   00000000 (0)\n-199F9 Compressed Size       00000000 (0)\n-199FD Uncompressed Size     00000000 (0)\n-19A01 Filename Length       0011 (17)\n-19A03 Extra Length          0009 (9)\n-19A05 Comment Length        0000 (0)\n-19A07 Disk Start            0000 (0)\n-19A09 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19A0B Ext File Attributes   00000000 (0)\n-19A0F Local Header Offset   0000463F (17983)\n-19A13 Filename              'XXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19A13: Filename 'XXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19A24 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19A26   Length              0005 (5)\n-19A28   Flags               01 (1) 'Modification'\n-19A29   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19A2D CENTRAL HEADER #17    02014B50 (33639248)\n-19A31 Created Zip Spec      14 (20) '2.0'\n-19A32 Created OS            00 (0) 'MS-DOS'\n-19A33 Extract Zip Spec      14 (20) '2.0'\n-19A34 Extract OS            00 (0) 'MS-DOS'\n-19A35 General Purpose Flag  0000 (0)\n-19A37 Compression Method    0000 (0) 'Stored'\n-19A39 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19A3D CRC                   00000000 (0)\n-19A41 Compressed Size       00000000 (0)\n-19A45 Uncompressed Size     00000000 (0)\n-19A49 Filename Length       001A (26)\n-19A4B Extra Length          0009 (9)\n-19A4D Comment Length        0000 (0)\n-19A4F Disk Start            0000 (0)\n-19A51 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19A53 Ext File Attributes   00000000 (0)\n-19A57 Local Header Offset   00004677 (18039)\n-19A5B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19A5B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19A75 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19A77   Length              0005 (5)\n-19A79   Flags               01 (1) 'Modification'\n-19A7A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19A7E CENTRAL HEADER #18    02014B50 (33639248)\n-19A82 Created Zip Spec      14 (20) '2.0'\n-19A83 Created OS            00 (0) 'MS-DOS'\n-19A84 Extract Zip Spec      14 (20) '2.0'\n-19A85 Extract OS            00 (0) 'MS-DOS'\n-19A86 General Purpose Flag  0000 (0)\n-19A88 Compression Method    0000 (0) 'Stored'\n-19A8A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19A8E CRC                   00000000 (0)\n-19A92 Compressed Size       00000000 (0)\n-19A96 Uncompressed Size     00000000 (0)\n-19A9A Filename Length       0024 (36)\n-19A9C Extra Length          0009 (9)\n-19A9E Comment Length        0000 (0)\n-19AA0 Disk Start            0000 (0)\n-19AA2 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19AA4 Ext File Attributes   00000000 (0)\n-19AA8 Local Header Offset   000046B8 (18104)\n-19AAC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19AAC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19AD0 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19AD2   Length              0005 (5)\n-19AD4   Flags               01 (1) 'Modification'\n-19AD5   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19AD9 CENTRAL HEADER #19    02014B50 (33639248)\n-19ADD Created Zip Spec      14 (20) '2.0'\n-19ADE Created OS            00 (0) 'MS-DOS'\n-19ADF Extract Zip Spec      14 (20) '2.0'\n-19AE0 Extract OS            00 (0) 'MS-DOS'\n-19AE1 General Purpose Flag  0000 (0)\n-19AE3 Compression Method    0000 (0) 'Stored'\n-19AE5 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19AE9 CRC                   00000000 (0)\n-19AED Compressed Size       00000000 (0)\n-19AF1 Uncompressed Size     00000000 (0)\n-19AF5 Filename Length       002B (43)\n-19AF7 Extra Length          0009 (9)\n-19AF9 Comment Length        0000 (0)\n-19AFB Disk Start            0000 (0)\n-19AFD Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19AFF Ext File Attributes   00000000 (0)\n-19B03 Local Header Offset   00004703 (18179)\n-19B07 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19B07: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19B32 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19B34   Length              0005 (5)\n-19B36   Flags               01 (1) 'Modification'\n-19B37   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19B3B CENTRAL HEADER #20    02014B50 (33639248)\n-19B3F Created Zip Spec      14 (20) '2.0'\n-19B40 Created OS            00 (0) 'MS-DOS'\n-19B41 Extract Zip Spec      14 (20) '2.0'\n-19B42 Extract OS            00 (0) 'MS-DOS'\n-19B43 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19B45 Compression Method    0000 (0) 'Stored'\n-19B47 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19B4B CRC                   73E7CE8A (1944571530)\n-19B4F Compressed Size       000027E6 (10214)\n-19B53 Uncompressed Size     000027E6 (10214)\n-19B57 Filename Length       0048 (72)\n-19B59 Extra Length          0009 (9)\n-19B5B Comment Length        0000 (0)\n-19B5D Disk Start            0000 (0)\n-19B5F Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19B61 Ext File Attributes   00000000 (0)\n-19B65 Local Header Offset   00004755 (18261)\n-19B69 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19B69: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19BB1 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19BB3   Length              0005 (5)\n-19BB5   Flags               01 (1) 'Modification'\n-19BB6   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19BBA CENTRAL HEADER #21    02014B50 (33639248)\n-19BBE Created Zip Spec      14 (20) '2.0'\n-19BBF Created OS            00 (0) 'MS-DOS'\n-19BC0 Extract Zip Spec      14 (20) '2.0'\n-19BC1 Extract OS            00 (0) 'MS-DOS'\n-19BC2 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19BC4 Compression Method    0000 (0) 'Stored'\n-19BC6 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19BCA CRC                   CD460ADB (3443919579)\n-19BCE Compressed Size       00002241 (8769)\n-19BD2 Uncompressed Size     00002241 (8769)\n-19BD6 Filename Length       003C (60)\n-19BD8 Extra Length          0009 (9)\n-19BDA Comment Length        0000 (0)\n-19BDC Disk Start            0000 (0)\n-19BDE Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19BE0 Ext File Attributes   00000000 (0)\n-19BE4 Local Header Offset   00006FBA (28602)\n-19BE8 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19BE8: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19C24 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19C26   Length              0005 (5)\n-19C28   Flags               01 (1) 'Modification'\n-19C29   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19C2D CENTRAL HEADER #22    02014B50 (33639248)\n-19C31 Created Zip Spec      14 (20) '2.0'\n-19C32 Created OS            00 (0) 'MS-DOS'\n-19C33 Extract Zip Spec      14 (20) '2.0'\n-19C34 Extract OS            00 (0) 'MS-DOS'\n-19C35 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19C37 Compression Method    0000 (0) 'Stored'\n-19C39 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19C3D CRC                   17148ACF (387222223)\n-19C41 Compressed Size       00002446 (9286)\n-19C45 Uncompressed Size     00002446 (9286)\n-19C49 Filename Length       003B (59)\n-19C4B Extra Length          0009 (9)\n-19C4D Comment Length        0000 (0)\n-19C4F Disk Start            0000 (0)\n-19C51 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19C53 Ext File Attributes   00000000 (0)\n-19C57 Local Header Offset   0000926E (37486)\n-19C5B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19C5B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19C96 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19C98   Length              0005 (5)\n-19C9A   Flags               01 (1) 'Modification'\n-19C9B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19C9F CENTRAL HEADER #23    02014B50 (33639248)\n-19CA3 Created Zip Spec      14 (20) '2.0'\n-19CA4 Created OS            00 (0) 'MS-DOS'\n-19CA5 Extract Zip Spec      14 (20) '2.0'\n-19CA6 Extract OS            00 (0) 'MS-DOS'\n-19CA7 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19CA9 Compression Method    0000 (0) 'Stored'\n-19CAB Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19CAF CRC                   15F2B7F5 (368228341)\n-19CB3 Compressed Size       00001869 (6249)\n-19CB7 Uncompressed Size     00001869 (6249)\n-19CBB Filename Length       0042 (66)\n-19CBD Extra Length          0009 (9)\n-19CBF Comment Length        0000 (0)\n-19CC1 Disk Start            0000 (0)\n-19CC3 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19CC5 Ext File Attributes   00000000 (0)\n-19CC9 Local Header Offset   0000B726 (46886)\n-19CCD Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19CCD: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19D0F Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19D11   Length              0005 (5)\n-19D13   Flags               01 (1) 'Modification'\n-19D14   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19D18 CENTRAL HEADER #24    02014B50 (33639248)\n-19D1C Created Zip Spec      14 (20) '2.0'\n-19D1D Created OS            00 (0) 'MS-DOS'\n-19D1E Extract Zip Spec      14 (20) '2.0'\n-19D1F Extract OS            00 (0) 'MS-DOS'\n-19D20 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19D22 Compression Method    0000 (0) 'Stored'\n-19D24 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19D28 CRC                   BA9CD18D (3130839437)\n-19D2C Compressed Size       00000DDB (3547)\n-19D30 Uncompressed Size     00000DDB (3547)\n-19D34 Filename Length       0041 (65)\n-19D36 Extra Length          0009 (9)\n-19D38 Comment Length        0000 (0)\n-19D3A Disk Start            0000 (0)\n-19D3C Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19D3E Ext File Attributes   00000000 (0)\n-19D42 Local Header Offset   0000D008 (53256)\n-19D46 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19D46: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19D87 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19D89   Length              0005 (5)\n-19D8B   Flags               01 (1) 'Modification'\n-19D8C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19D90 CENTRAL HEADER #25    02014B50 (33639248)\n-19D94 Created Zip Spec      14 (20) '2.0'\n-19D95 Created OS            00 (0) 'MS-DOS'\n-19D96 Extract Zip Spec      14 (20) '2.0'\n-19D97 Extract OS            00 (0) 'MS-DOS'\n-19D98 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19D9A Compression Method    0000 (0) 'Stored'\n-19D9C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19DA0 CRC                   16F071B0 (384856496)\n-19DA4 Compressed Size       00000A5E (2654)\n-19DA8 Uncompressed Size     00000A5E (2654)\n-19DAC Filename Length       0045 (69)\n-19DAE Extra Length          0009 (9)\n-19DB0 Comment Length        0000 (0)\n-19DB2 Disk Start            0000 (0)\n-19DB4 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19DB6 Ext File Attributes   00000000 (0)\n-19DBA Local Header Offset   0000DE5B (56923)\n-19DBE Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19DBE: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19E03 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19E05   Length              0005 (5)\n-19E07   Flags               01 (1) 'Modification'\n-19E08   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19E0C CENTRAL HEADER #26    02014B50 (33639248)\n-19E10 Created Zip Spec      14 (20) '2.0'\n-19E11 Created OS            00 (0) 'MS-DOS'\n-19E12 Extract Zip Spec      14 (20) '2.0'\n-19E13 Extract OS            00 (0) 'MS-DOS'\n-19E14 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19E16 Compression Method    0000 (0) 'Stored'\n-19E18 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19E1C CRC                   99FF093E (2583628094)\n-19E20 Compressed Size       00001F03 (7939)\n-19E24 Uncompressed Size     00001F03 (7939)\n-19E28 Filename Length       003B (59)\n-19E2A Extra Length          0009 (9)\n-19E2C Comment Length        0000 (0)\n-19E2E Disk Start            0000 (0)\n-19E30 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19E32 Ext File Attributes   00000000 (0)\n-19E36 Local Header Offset   0000E935 (59701)\n-19E3A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19E3A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19E75 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19E77   Length              0005 (5)\n-19E79   Flags               01 (1) 'Modification'\n-19E7A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19E7E CENTRAL HEADER #27    02014B50 (33639248)\n-19E82 Created Zip Spec      14 (20) '2.0'\n-19E83 Created OS            00 (0) 'MS-DOS'\n-19E84 Extract Zip Spec      14 (20) '2.0'\n-19E85 Extract OS            00 (0) 'MS-DOS'\n-19E86 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19E88 Compression Method    0000 (0) 'Stored'\n-19E8A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19E8E CRC                   7ED127C7 (2127636423)\n-19E92 Compressed Size       0000147B (5243)\n-19E96 Uncompressed Size     0000147B (5243)\n-19E9A Filename Length       0042 (66)\n-19E9C Extra Length          0009 (9)\n-19E9E Comment Length        0000 (0)\n-19EA0 Disk Start            0000 (0)\n-19EA2 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19EA4 Ext File Attributes   00000000 (0)\n-19EA8 Local Header Offset   000108AA (67754)\n-19EAC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19EAC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19EEE Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19EF0   Length              0005 (5)\n-19EF2   Flags               01 (1) 'Modification'\n-19EF3   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19EF7 CENTRAL HEADER #28    02014B50 (33639248)\n-19EFB Created Zip Spec      14 (20) '2.0'\n-19EFC Created OS            00 (0) 'MS-DOS'\n-19EFD Extract Zip Spec      14 (20) '2.0'\n-19EFE Extract OS            00 (0) 'MS-DOS'\n-19EFF General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19F01 Compression Method    0000 (0) 'Stored'\n-19F03 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19F07 CRC                   4AAC1D37 (1252793655)\n-19F0B Compressed Size       0000064E (1614)\n-19F0F Uncompressed Size     0000064E (1614)\n-19F13 Filename Length       0040 (64)\n-19F15 Extra Length          0009 (9)\n-19F17 Comment Length        0000 (0)\n-19F19 Disk Start            0000 (0)\n-19F1B Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19F1D Ext File Attributes   00000000 (0)\n-19F21 Local Header Offset   00011D9E (73118)\n-19F25 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19F25: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19F65 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19F67   Length              0005 (5)\n-19F69   Flags               01 (1) 'Modification'\n-19F6A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19F6E CENTRAL HEADER #29    02014B50 (33639248)\n-19F72 Created Zip Spec      14 (20) '2.0'\n-19F73 Created OS            00 (0) 'MS-DOS'\n-19F74 Extract Zip Spec      14 (20) '2.0'\n-19F75 Extract OS            00 (0) 'MS-DOS'\n-19F76 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19F78 Compression Method    0000 (0) 'Stored'\n-19F7A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19F7E CRC                   155577E8 (357922792)\n-19F82 Compressed Size       000015AE (5550)\n-19F86 Uncompressed Size     000015AE (5550)\n-19F8A Filename Length       003B (59)\n-19F8C Extra Length          0009 (9)\n-19F8E Comment Length        0000 (0)\n-19F90 Disk Start            0000 (0)\n-19F92 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-19F94 Ext File Attributes   00000000 (0)\n-19F98 Local Header Offset   00012463 (74851)\n-19F9C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x19F9C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-19FD7 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-19FD9   Length              0005 (5)\n-19FDB   Flags               01 (1) 'Modification'\n-19FDC   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-19FE0 CENTRAL HEADER #30    02014B50 (33639248)\n-19FE4 Created Zip Spec      14 (20) '2.0'\n-19FE5 Created OS            00 (0) 'MS-DOS'\n-19FE6 Extract Zip Spec      14 (20) '2.0'\n-19FE7 Extract OS            00 (0) 'MS-DOS'\n-19FE8 General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-19FEA Compression Method    0000 (0) 'Stored'\n-19FEC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-19FF0 CRC                   FC50D2E5 (4233155301)\n-19FF4 Compressed Size       000016CB (5835)\n-19FF8 Uncompressed Size     000016CB (5835)\n-19FFC Filename Length       0045 (69)\n-19FFE Extra Length          0009 (9)\n-1A000 Comment Length        0000 (0)\n-1A002 Disk Start            0000 (0)\n-1A004 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1A006 Ext File Attributes   00000000 (0)\n-1A00A Local Header Offset   00013A83 (80515)\n-1A00E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1A00E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1A053 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1A055   Length              0005 (5)\n-1A057   Flags               01 (1) 'Modification'\n-1A058   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1A05C CENTRAL HEADER #31    02014B50 (33639248)\n-1A060 Created Zip Spec      14 (20) '2.0'\n-1A061 Created OS            00 (0) 'MS-DOS'\n-1A062 Extract Zip Spec      14 (20) '2.0'\n-1A063 Extract OS            00 (0) 'MS-DOS'\n-1A064 General Purpose Flag  0000 (0)\n-1A066 Compression Method    0000 (0) 'Stored'\n-1A068 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1A06C CRC                   00000000 (0)\n-1A070 Compressed Size       00000000 (0)\n-1A074 Uncompressed Size     00000000 (0)\n-1A078 Filename Length       0033 (51)\n-1A07A Extra Length          0009 (9)\n-1A07C Comment Length        0000 (0)\n-1A07E Disk Start            0000 (0)\n-1A080 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1A082 Ext File Attributes   00000000 (0)\n-1A086 Local Header Offset   000151CA (86474)\n-1A08A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1A08A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1A0BD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1A0BF   Length              0005 (5)\n-1A0C1   Flags               01 (1) 'Modification'\n-1A0C2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1A0C6 CENTRAL HEADER #32    02014B50 (33639248)\n-1A0CA Created Zip Spec      14 (20) '2.0'\n-1A0CB Created OS            00 (0) 'MS-DOS'\n-1A0CC Extract Zip Spec      14 (20) '2.0'\n-1A0CD Extract OS            00 (0) 'MS-DOS'\n-1A0CE General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1A0D0 Compression Method    0000 (0) 'Stored'\n-1A0D2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1A0D6 CRC                   58FEAB57 (1493085015)\n-1A0DA Compressed Size       000008C3 (2243)\n-1A0DE Uncompressed Size     000008C3 (2243)\n-1A0E2 Filename Length       0047 (71)\n-1A0E4 Extra Length          0009 (9)\n-1A0E6 Comment Length        0000 (0)\n-1A0E8 Disk Start            0000 (0)\n-1A0EA Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1A0EC Ext File Attributes   00000000 (0)\n-1A0F0 Local Header Offset   00015224 (86564)\n-1A0F4 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1A0F4: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1A13B Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1A13D   Length              0005 (5)\n-1A13F   Flags               01 (1) 'Modification'\n-1A140   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1A144 CENTRAL HEADER #33    02014B50 (33639248)\n-1A148 Created Zip Spec      14 (20) '2.0'\n-1A149 Created OS            00 (0) 'MS-DOS'\n-1A14A Extract Zip Spec      14 (20) '2.0'\n-1A14B Extract OS            00 (0) 'MS-DOS'\n-1A14C General Purpose Flag  0008 (8)\n-      [Bit  3]              1 'Streamed'\n-1A14E Compression Method    0000 (0) 'Stored'\n-1A150 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n-1A154 CRC                   BC1F87C6 (3156182982)\n-1A158 Compressed Size       0000391E (14622)\n-1A15C Uncompressed Size     0000391E (14622)\n-1A160 Filename Length       0048 (72)\n-1A162 Extra Length          0009 (9)\n-1A164 Comment Length        0000 (0)\n-1A166 Disk Start            0000 (0)\n-1A168 Int File Attributes   0000 (0)\n-      [Bit 0]               0 'Binary Data'\n-1A16A Ext File Attributes   00000000 (0)\n-1A16E Local Header Offset   00015B65 (88933)\n-1A172 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#\n-# WARNING: Offset 0x1A172: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n-#          Zero length filename\n-#\n-1A1BA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n-1A1BC   Length              0005 (5)\n-1A1BE   Flags               01 (1) 'Modification'\n-1A1BF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n-\n-1A1C3 END CENTRAL HEADER    06054B50 (101010256)\n-1A1C7 Number of this disk   0000 (0)\n-1A1C9 Central Dir Disk no   0000 (0)\n-1A1CB Entries in this disk  0021 (33)\n-1A1CD Total Entries         0021 (33)\n-1A1CF Size of Central Dir   00000CC1 (3265)\n-1A1D3 Offset to Central Dir 00019502 (103682)\n-1A1D7 Comment Length        0000 (0)\n+04597 DATA DESCRIPTOR       08074B50 (134695760)\n+0459B CRC                   1D29AE65 (489270885)\n+0459F Compressed Size       00000924 (2340)\n+045A3 Uncompressed Size     00000924 (2340)\n+\n+045A7 LOCAL HEADER #14      04034B50 (67324752)\n+045AB Extract Zip Spec      14 (20) '2.0'\n+045AC Extract OS            00 (0) 'MS-DOS'\n+045AD General Purpose Flag  0000 (0)\n+045AF Compression Method    0000 (0) 'Stored'\n+045B1 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+045B5 CRC                   00000000 (0)\n+045B9 Compressed Size       00000000 (0)\n+045BD Uncompressed Size     00000000 (0)\n+045C1 Filename Length       0004 (4)\n+045C3 Extra Length          0009 (9)\n+045C5 Filename              'XXXX'\n+#\n+# WARNING: Offset 0x45C5: Filename 'XXXX'\n+#          Zero length filename\n+#\n+045C9 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+045CB   Length              0005 (5)\n+045CD   Flags               01 (1) 'Modification'\n+045CE   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+045D2 LOCAL HEADER #15      04034B50 (67324752)\n+045D6 Extract Zip Spec      14 (20) '2.0'\n+045D7 Extract OS            00 (0) 'MS-DOS'\n+045D8 General Purpose Flag  0000 (0)\n+045DA Compression Method    0000 (0) 'Stored'\n+045DC Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+045E0 CRC                   00000000 (0)\n+045E4 Compressed Size       00000000 (0)\n+045E8 Uncompressed Size     00000000 (0)\n+045EC Filename Length       000B (11)\n+045EE Extra Length          0009 (9)\n+045F0 Filename              'XXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x45F0: Filename 'XXXXXXXXXXX'\n+#          Zero length filename\n+#\n+045FB Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+045FD   Length              0005 (5)\n+045FF   Flags               01 (1) 'Modification'\n+04600   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+04604 LOCAL HEADER #16      04034B50 (67324752)\n+04608 Extract Zip Spec      14 (20) '2.0'\n+04609 Extract OS            00 (0) 'MS-DOS'\n+0460A General Purpose Flag  0000 (0)\n+0460C Compression Method    0000 (0) 'Stored'\n+0460E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+04612 CRC                   00000000 (0)\n+04616 Compressed Size       00000000 (0)\n+0461A Uncompressed Size     00000000 (0)\n+0461E Filename Length       0011 (17)\n+04620 Extra Length          0009 (9)\n+04622 Filename              'XXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x4622: Filename 'XXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04633 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04635   Length              0005 (5)\n+04637   Flags               01 (1) 'Modification'\n+04638   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+0463C LOCAL HEADER #17      04034B50 (67324752)\n+04640 Extract Zip Spec      14 (20) '2.0'\n+04641 Extract OS            00 (0) 'MS-DOS'\n+04642 General Purpose Flag  0000 (0)\n+04644 Compression Method    0000 (0) 'Stored'\n+04646 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0464A CRC                   00000000 (0)\n+0464E Compressed Size       00000000 (0)\n+04652 Uncompressed Size     00000000 (0)\n+04656 Filename Length       001A (26)\n+04658 Extra Length          0009 (9)\n+0465A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x465A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04674 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04676   Length              0005 (5)\n+04678   Flags               01 (1) 'Modification'\n+04679   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+0467D LOCAL HEADER #18      04034B50 (67324752)\n+04681 Extract Zip Spec      14 (20) '2.0'\n+04682 Extract OS            00 (0) 'MS-DOS'\n+04683 General Purpose Flag  0000 (0)\n+04685 Compression Method    0000 (0) 'Stored'\n+04687 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0468B CRC                   00000000 (0)\n+0468F Compressed Size       00000000 (0)\n+04693 Uncompressed Size     00000000 (0)\n+04697 Filename Length       0024 (36)\n+04699 Extra Length          0009 (9)\n+0469B Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x469B: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+046BF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+046C1   Length              0005 (5)\n+046C3   Flags               01 (1) 'Modification'\n+046C4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+046C8 LOCAL HEADER #19      04034B50 (67324752)\n+046CC Extract Zip Spec      14 (20) '2.0'\n+046CD Extract OS            00 (0) 'MS-DOS'\n+046CE General Purpose Flag  0000 (0)\n+046D0 Compression Method    0000 (0) 'Stored'\n+046D2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+046D6 CRC                   00000000 (0)\n+046DA Compressed Size       00000000 (0)\n+046DE Uncompressed Size     00000000 (0)\n+046E2 Filename Length       002B (43)\n+046E4 Extra Length          0009 (9)\n+046E6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x46E6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04711 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04713   Length              0005 (5)\n+04715   Flags               01 (1) 'Modification'\n+04716   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+0471A LOCAL HEADER #20      04034B50 (67324752)\n+0471E Extract Zip Spec      14 (20) '2.0'\n+0471F Extract OS            00 (0) 'MS-DOS'\n+04720 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+04722 Compression Method    0000 (0) 'Stored'\n+04724 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+04728 CRC                   00000000 (0)\n+0472C Compressed Size       00000000 (0)\n+04730 Uncompressed Size     00000000 (0)\n+04734 Filename Length       0048 (72)\n+04736 Extra Length          0009 (9)\n+04738 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x4738: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+04780 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+04782   Length              0005 (5)\n+04784   Flags               01 (1) 'Modification'\n+04785   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+04789 PAYLOAD\n+\n+06F6F DATA DESCRIPTOR       08074B50 (134695760)\n+06F73 CRC                   73E7CE8A (1944571530)\n+06F77 Compressed Size       000027E6 (10214)\n+06F7B Uncompressed Size     000027E6 (10214)\n+\n+06F7F LOCAL HEADER #21      04034B50 (67324752)\n+06F83 Extract Zip Spec      14 (20) '2.0'\n+06F84 Extract OS            00 (0) 'MS-DOS'\n+06F85 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+06F87 Compression Method    0000 (0) 'Stored'\n+06F89 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+06F8D CRC                   00000000 (0)\n+06F91 Compressed Size       00000000 (0)\n+06F95 Uncompressed Size     00000000 (0)\n+06F99 Filename Length       003C (60)\n+06F9B Extra Length          0009 (9)\n+06F9D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x6F9D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+06FD9 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+06FDB   Length              0005 (5)\n+06FDD   Flags               01 (1) 'Modification'\n+06FDE   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+06FE2 PAYLOAD\n+\n+09337 DATA DESCRIPTOR       08074B50 (134695760)\n+0933B CRC                   EADF50E0 (3940503776)\n+0933F Compressed Size       00002355 (9045)\n+09343 Uncompressed Size     00002355 (9045)\n+\n+09347 LOCAL HEADER #22      04034B50 (67324752)\n+0934B Extract Zip Spec      14 (20) '2.0'\n+0934C Extract OS            00 (0) 'MS-DOS'\n+0934D General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0934F Compression Method    0000 (0) 'Stored'\n+09351 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+09355 CRC                   00000000 (0)\n+09359 Compressed Size       00000000 (0)\n+0935D Uncompressed Size     00000000 (0)\n+09361 Filename Length       003B (59)\n+09363 Extra Length          0009 (9)\n+09365 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x9365: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+093A0 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+093A2   Length              0005 (5)\n+093A4   Flags               01 (1) 'Modification'\n+093A5   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+093A9 PAYLOAD\n+\n+0B8C8 DATA DESCRIPTOR       08074B50 (134695760)\n+0B8CC CRC                   1CB2BCAF (481475759)\n+0B8D0 Compressed Size       0000251F (9503)\n+0B8D4 Uncompressed Size     0000251F (9503)\n+\n+0B8D8 LOCAL HEADER #23      04034B50 (67324752)\n+0B8DC Extract Zip Spec      14 (20) '2.0'\n+0B8DD Extract OS            00 (0) 'MS-DOS'\n+0B8DE General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0B8E0 Compression Method    0000 (0) 'Stored'\n+0B8E2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0B8E6 CRC                   00000000 (0)\n+0B8EA Compressed Size       00000000 (0)\n+0B8EE Uncompressed Size     00000000 (0)\n+0B8F2 Filename Length       0042 (66)\n+0B8F4 Extra Length          0009 (9)\n+0B8F6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xB8F6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0B938 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0B93A   Length              0005 (5)\n+0B93C   Flags               01 (1) 'Modification'\n+0B93D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0B941 PAYLOAD\n+\n+0D24B DATA DESCRIPTOR       08074B50 (134695760)\n+0D24F CRC                   7DE2A421 (2112005153)\n+0D253 Compressed Size       0000190A (6410)\n+0D257 Uncompressed Size     0000190A (6410)\n+\n+0D25B LOCAL HEADER #24      04034B50 (67324752)\n+0D25F Extract Zip Spec      14 (20) '2.0'\n+0D260 Extract OS            00 (0) 'MS-DOS'\n+0D261 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0D263 Compression Method    0000 (0) 'Stored'\n+0D265 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0D269 CRC                   00000000 (0)\n+0D26D Compressed Size       00000000 (0)\n+0D271 Uncompressed Size     00000000 (0)\n+0D275 Filename Length       0041 (65)\n+0D277 Extra Length          0009 (9)\n+0D279 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xD279: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0D2BA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0D2BC   Length              0005 (5)\n+0D2BE   Flags               01 (1) 'Modification'\n+0D2BF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0D2C3 PAYLOAD\n+\n+0E103 DATA DESCRIPTOR       08074B50 (134695760)\n+0E107 CRC                   3BA2E25A (1000530522)\n+0E10B Compressed Size       00000E40 (3648)\n+0E10F Uncompressed Size     00000E40 (3648)\n+\n+0E113 LOCAL HEADER #25      04034B50 (67324752)\n+0E117 Extract Zip Spec      14 (20) '2.0'\n+0E118 Extract OS            00 (0) 'MS-DOS'\n+0E119 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0E11B Compression Method    0000 (0) 'Stored'\n+0E11D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0E121 CRC                   00000000 (0)\n+0E125 Compressed Size       00000000 (0)\n+0E129 Uncompressed Size     00000000 (0)\n+0E12D Filename Length       0045 (69)\n+0E12F Extra Length          0009 (9)\n+0E131 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xE131: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0E176 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0E178   Length              0005 (5)\n+0E17A   Flags               01 (1) 'Modification'\n+0E17B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0E17F PAYLOAD\n+\n+0EC19 DATA DESCRIPTOR       08074B50 (134695760)\n+0EC1D CRC                   1E5B2A86 (509291142)\n+0EC21 Compressed Size       00000A9A (2714)\n+0EC25 Uncompressed Size     00000A9A (2714)\n+\n+0EC29 LOCAL HEADER #26      04034B50 (67324752)\n+0EC2D Extract Zip Spec      14 (20) '2.0'\n+0EC2E Extract OS            00 (0) 'MS-DOS'\n+0EC2F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+0EC31 Compression Method    0000 (0) 'Stored'\n+0EC33 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+0EC37 CRC                   00000000 (0)\n+0EC3B Compressed Size       00000000 (0)\n+0EC3F Uncompressed Size     00000000 (0)\n+0EC43 Filename Length       003B (59)\n+0EC45 Extra Length          0009 (9)\n+0EC47 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0xEC47: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+0EC82 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+0EC84   Length              0005 (5)\n+0EC86   Flags               01 (1) 'Modification'\n+0EC87   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+0EC8B PAYLOAD\n+\n+10C58 DATA DESCRIPTOR       08074B50 (134695760)\n+10C5C CRC                   1CDD10AA (484249770)\n+10C60 Compressed Size       00001FCD (8141)\n+10C64 Uncompressed Size     00001FCD (8141)\n+\n+10C68 LOCAL HEADER #27      04034B50 (67324752)\n+10C6C Extract Zip Spec      14 (20) '2.0'\n+10C6D Extract OS            00 (0) 'MS-DOS'\n+10C6E General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+10C70 Compression Method    0000 (0) 'Stored'\n+10C72 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+10C76 CRC                   00000000 (0)\n+10C7A Compressed Size       00000000 (0)\n+10C7E Uncompressed Size     00000000 (0)\n+10C82 Filename Length       0042 (66)\n+10C84 Extra Length          0009 (9)\n+10C86 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x10C86: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+10CC8 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+10CCA   Length              0005 (5)\n+10CCC   Flags               01 (1) 'Modification'\n+10CCD   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+10CD1 PAYLOAD\n+\n+121D6 DATA DESCRIPTOR       08074B50 (134695760)\n+121DA CRC                   52A8EAC6 (1386801862)\n+121DE Compressed Size       00001505 (5381)\n+121E2 Uncompressed Size     00001505 (5381)\n+\n+121E6 LOCAL HEADER #28      04034B50 (67324752)\n+121EA Extract Zip Spec      14 (20) '2.0'\n+121EB Extract OS            00 (0) 'MS-DOS'\n+121EC General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+121EE Compression Method    0000 (0) 'Stored'\n+121F0 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+121F4 CRC                   00000000 (0)\n+121F8 Compressed Size       00000000 (0)\n+121FC Uncompressed Size     00000000 (0)\n+12200 Filename Length       0040 (64)\n+12202 Extra Length          0009 (9)\n+12204 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x12204: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+12244 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+12246   Length              0005 (5)\n+12248   Flags               01 (1) 'Modification'\n+12249   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1224D PAYLOAD\n+\n+128C6 DATA DESCRIPTOR       08074B50 (134695760)\n+128CA CRC                   1AC58108 (449151240)\n+128CE Compressed Size       00000679 (1657)\n+128D2 Uncompressed Size     00000679 (1657)\n+\n+128D6 LOCAL HEADER #29      04034B50 (67324752)\n+128DA Extract Zip Spec      14 (20) '2.0'\n+128DB Extract OS            00 (0) 'MS-DOS'\n+128DC General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+128DE Compression Method    0000 (0) 'Stored'\n+128E0 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+128E4 CRC                   00000000 (0)\n+128E8 Compressed Size       00000000 (0)\n+128EC Uncompressed Size     00000000 (0)\n+128F0 Filename Length       003B (59)\n+128F2 Extra Length          0009 (9)\n+128F4 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x128F4: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1292F Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+12931   Length              0005 (5)\n+12933   Flags               01 (1) 'Modification'\n+12934   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+12938 PAYLOAD\n+\n+13F5F DATA DESCRIPTOR       08074B50 (134695760)\n+13F63 CRC                   377C624A (930898506)\n+13F67 Compressed Size       00001627 (5671)\n+13F6B Uncompressed Size     00001627 (5671)\n+\n+13F6F LOCAL HEADER #30      04034B50 (67324752)\n+13F73 Extract Zip Spec      14 (20) '2.0'\n+13F74 Extract OS            00 (0) 'MS-DOS'\n+13F75 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+13F77 Compression Method    0000 (0) 'Stored'\n+13F79 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+13F7D CRC                   00000000 (0)\n+13F81 Compressed Size       00000000 (0)\n+13F85 Uncompressed Size     00000000 (0)\n+13F89 Filename Length       0045 (69)\n+13F8B Extra Length          0009 (9)\n+13F8D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x13F8D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+13FD2 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+13FD4   Length              0005 (5)\n+13FD6   Flags               01 (1) 'Modification'\n+13FD7   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+13FDB PAYLOAD\n+\n+15733 DATA DESCRIPTOR       08074B50 (134695760)\n+15737 CRC                   37334079 (926105721)\n+1573B Compressed Size       00001758 (5976)\n+1573F Uncompressed Size     00001758 (5976)\n+\n+15743 LOCAL HEADER #31      04034B50 (67324752)\n+15747 Extract Zip Spec      14 (20) '2.0'\n+15748 Extract OS            00 (0) 'MS-DOS'\n+15749 General Purpose Flag  0000 (0)\n+1574B Compression Method    0000 (0) 'Stored'\n+1574D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+15751 CRC                   00000000 (0)\n+15755 Compressed Size       00000000 (0)\n+15759 Uncompressed Size     00000000 (0)\n+1575D Filename Length       0033 (51)\n+1575F Extra Length          0009 (9)\n+15761 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x15761: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+15794 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+15796   Length              0005 (5)\n+15798   Flags               01 (1) 'Modification'\n+15799   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1579D LOCAL HEADER #32      04034B50 (67324752)\n+157A1 Extract Zip Spec      14 (20) '2.0'\n+157A2 Extract OS            00 (0) 'MS-DOS'\n+157A3 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+157A5 Compression Method    0000 (0) 'Stored'\n+157A7 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+157AB CRC                   00000000 (0)\n+157AF Compressed Size       00000000 (0)\n+157B3 Uncompressed Size     00000000 (0)\n+157B7 Filename Length       0047 (71)\n+157B9 Extra Length          0009 (9)\n+157BB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x157BB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+15802 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+15804   Length              0005 (5)\n+15806   Flags               01 (1) 'Modification'\n+15807   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1580B PAYLOAD\n+\n+160CE DATA DESCRIPTOR       08074B50 (134695760)\n+160D2 CRC                   58FEAB57 (1493085015)\n+160D6 Compressed Size       000008C3 (2243)\n+160DA Uncompressed Size     000008C3 (2243)\n+\n+160DE LOCAL HEADER #33      04034B50 (67324752)\n+160E2 Extract Zip Spec      14 (20) '2.0'\n+160E3 Extract OS            00 (0) 'MS-DOS'\n+160E4 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+160E6 Compression Method    0000 (0) 'Stored'\n+160E8 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+160EC CRC                   00000000 (0)\n+160F0 Compressed Size       00000000 (0)\n+160F4 Uncompressed Size     00000000 (0)\n+160F8 Filename Length       0048 (72)\n+160FA Extra Length          0009 (9)\n+160FC Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x160FC: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+16144 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+16146   Length              0005 (5)\n+16148   Flags               01 (1) 'Modification'\n+16149   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+1614D PAYLOAD\n+\n+19C05 DATA DESCRIPTOR       08074B50 (134695760)\n+19C09 CRC                   A355BCB4 (2740305076)\n+19C0D Compressed Size       00003AB8 (15032)\n+19C11 Uncompressed Size     00003AB8 (15032)\n+\n+19C15 CENTRAL HEADER #1     02014B50 (33639248)\n+19C19 Created Zip Spec      14 (20) '2.0'\n+19C1A Created OS            00 (0) 'MS-DOS'\n+19C1B Extract Zip Spec      14 (20) '2.0'\n+19C1C Extract OS            00 (0) 'MS-DOS'\n+19C1D General Purpose Flag  0000 (0)\n+19C1F Compression Method    0000 (0) 'Stored'\n+19C21 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19C25 CRC                   00000000 (0)\n+19C29 Compressed Size       00000000 (0)\n+19C2D Uncompressed Size     00000000 (0)\n+19C31 Filename Length       0009 (9)\n+19C33 Extra Length          0009 (9)\n+19C35 Comment Length        0000 (0)\n+19C37 Disk Start            0000 (0)\n+19C39 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19C3B Ext File Attributes   00000000 (0)\n+19C3F Local Header Offset   00000000 (0)\n+19C43 Filename              'XXXXXXXXX'\n+#\n+# WARNING: Offset 0x19C43: Filename 'XXXXXXXXX'\n+#          Zero length filename\n+#\n+19C4C Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19C4E   Length              0005 (5)\n+19C50   Flags               01 (1) 'Modification'\n+19C51   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19C55 CENTRAL HEADER #2     02014B50 (33639248)\n+19C59 Created Zip Spec      14 (20) '2.0'\n+19C5A Created OS            00 (0) 'MS-DOS'\n+19C5B Extract Zip Spec      14 (20) '2.0'\n+19C5C Extract OS            00 (0) 'MS-DOS'\n+19C5D General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19C5F Compression Method    0000 (0) 'Stored'\n+19C61 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19C65 CRC                   0F83987F (260282495)\n+19C69 Compressed Size       00000ACF (2767)\n+19C6D Uncompressed Size     00000ACF (2767)\n+19C71 Filename Length       0015 (21)\n+19C73 Extra Length          0009 (9)\n+19C75 Comment Length        0000 (0)\n+19C77 Disk Start            0000 (0)\n+19C79 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19C7B Ext File Attributes   00000000 (0)\n+19C7F Local Header Offset   00000030 (48)\n+19C83 Filename              'XXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19C83: Filename 'XXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19C98 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19C9A   Length              0005 (5)\n+19C9C   Flags               01 (1) 'Modification'\n+19C9D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19CA1 CENTRAL HEADER #3     02014B50 (33639248)\n+19CA5 Created Zip Spec      14 (20) '2.0'\n+19CA6 Created OS            00 (0) 'MS-DOS'\n+19CA7 Extract Zip Spec      14 (20) '2.0'\n+19CA8 Extract OS            00 (0) 'MS-DOS'\n+19CA9 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19CAB Compression Method    0000 (0) 'Stored'\n+19CAD Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19CB1 CRC                   86E2B4B4 (2263004340)\n+19CB5 Compressed Size       00002C5E (11358)\n+19CB9 Uncompressed Size     00002C5E (11358)\n+19CBD Filename Length       0010 (16)\n+19CBF Extra Length          0009 (9)\n+19CC1 Comment Length        0000 (0)\n+19CC3 Disk Start            0000 (0)\n+19CC5 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19CC7 Ext File Attributes   00000000 (0)\n+19CCB Local Header Offset   00000B4B (2891)\n+19CCF Filename              'XXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19CCF: Filename 'XXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19CDF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19CE1   Length              0005 (5)\n+19CE3   Flags               01 (1) 'Modification'\n+19CE4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19CE8 CENTRAL HEADER #4     02014B50 (33639248)\n+19CEC Created Zip Spec      14 (20) '2.0'\n+19CED Created OS            00 (0) 'MS-DOS'\n+19CEE Extract Zip Spec      14 (20) '2.0'\n+19CEF Extract OS            00 (0) 'MS-DOS'\n+19CF0 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19CF2 Compression Method    0000 (0) 'Stored'\n+19CF4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19CF8 CRC                   EE027FB2 (3993141170)\n+19CFC Compressed Size       00000019 (25)\n+19D00 Uncompressed Size     00000019 (25)\n+19D04 Filename Length       0014 (20)\n+19D06 Extra Length          0009 (9)\n+19D08 Comment Length        0000 (0)\n+19D0A Disk Start            0000 (0)\n+19D0C Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19D0E Ext File Attributes   00000000 (0)\n+19D12 Local Header Offset   000037F0 (14320)\n+19D16 Filename              'XXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19D16: Filename 'XXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19D2A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19D2C   Length              0005 (5)\n+19D2E   Flags               01 (1) 'Modification'\n+19D2F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19D33 CENTRAL HEADER #5     02014B50 (33639248)\n+19D37 Created Zip Spec      14 (20) '2.0'\n+19D38 Created OS            00 (0) 'MS-DOS'\n+19D39 Extract Zip Spec      14 (20) '2.0'\n+19D3A Extract OS            00 (0) 'MS-DOS'\n+19D3B General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19D3D Compression Method    0000 (0) 'Stored'\n+19D3F Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19D43 CRC                   5A29D305 (1512690437)\n+19D47 Compressed Size       000000B2 (178)\n+19D4B Uncompressed Size     000000B2 (178)\n+19D4F Filename Length       000F (15)\n+19D51 Extra Length          0009 (9)\n+19D53 Comment Length        0000 (0)\n+19D55 Disk Start            0000 (0)\n+19D57 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19D59 Ext File Attributes   00000000 (0)\n+19D5D Local Header Offset   00003854 (14420)\n+19D61 Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19D61: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19D70 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19D72   Length              0005 (5)\n+19D74   Flags               01 (1) 'Modification'\n+19D75   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19D79 CENTRAL HEADER #6     02014B50 (33639248)\n+19D7D Created Zip Spec      14 (20) '2.0'\n+19D7E Created OS            00 (0) 'MS-DOS'\n+19D7F Extract Zip Spec      14 (20) '2.0'\n+19D80 Extract OS            00 (0) 'MS-DOS'\n+19D81 General Purpose Flag  0000 (0)\n+19D83 Compression Method    0000 (0) 'Stored'\n+19D85 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19D89 CRC                   00000000 (0)\n+19D8D Compressed Size       00000000 (0)\n+19D91 Uncompressed Size     00000000 (0)\n+19D95 Filename Length       000F (15)\n+19D97 Extra Length          0009 (9)\n+19D99 Comment Length        0000 (0)\n+19D9B Disk Start            0000 (0)\n+19D9D Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19D9F Ext File Attributes   00000000 (0)\n+19DA3 Local Header Offset   0000394C (14668)\n+19DA7 Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19DA7: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19DB6 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19DB8   Length              0005 (5)\n+19DBA   Flags               01 (1) 'Modification'\n+19DBB   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19DBF CENTRAL HEADER #7     02014B50 (33639248)\n+19DC3 Created Zip Spec      14 (20) '2.0'\n+19DC4 Created OS            00 (0) 'MS-DOS'\n+19DC5 Extract Zip Spec      14 (20) '2.0'\n+19DC6 Extract OS            00 (0) 'MS-DOS'\n+19DC7 General Purpose Flag  0000 (0)\n+19DC9 Compression Method    0000 (0) 'Stored'\n+19DCB Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19DCF CRC                   00000000 (0)\n+19DD3 Compressed Size       00000000 (0)\n+19DD7 Uncompressed Size     00000000 (0)\n+19DDB Filename Length       0018 (24)\n+19DDD Extra Length          0009 (9)\n+19DDF Comment Length        0000 (0)\n+19DE1 Disk Start            0000 (0)\n+19DE3 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19DE5 Ext File Attributes   00000000 (0)\n+19DE9 Local Header Offset   00003982 (14722)\n+19DED Filename              'XXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19DED: Filename 'XXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19E05 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19E07   Length              0005 (5)\n+19E09   Flags               01 (1) 'Modification'\n+19E0A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19E0E CENTRAL HEADER #8     02014B50 (33639248)\n+19E12 Created Zip Spec      14 (20) '2.0'\n+19E13 Created OS            00 (0) 'MS-DOS'\n+19E14 Extract Zip Spec      14 (20) '2.0'\n+19E15 Extract OS            00 (0) 'MS-DOS'\n+19E16 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19E18 Compression Method    0000 (0) 'Stored'\n+19E1A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19E1E CRC                   8F7CA09F (2407309471)\n+19E22 Compressed Size       00000085 (133)\n+19E26 Uncompressed Size     00000085 (133)\n+19E2A Filename Length       003D (61)\n+19E2C Extra Length          0009 (9)\n+19E2E Comment Length        0000 (0)\n+19E30 Disk Start            0000 (0)\n+19E32 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19E34 Ext File Attributes   00000000 (0)\n+19E38 Local Header Offset   000039C1 (14785)\n+19E3C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19E3C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19E79 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19E7B   Length              0005 (5)\n+19E7D   Flags               01 (1) 'Modification'\n+19E7E   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19E82 CENTRAL HEADER #9     02014B50 (33639248)\n+19E86 Created Zip Spec      14 (20) '2.0'\n+19E87 Created OS            00 (0) 'MS-DOS'\n+19E88 Extract Zip Spec      14 (20) '2.0'\n+19E89 Extract OS            00 (0) 'MS-DOS'\n+19E8A General Purpose Flag  0000 (0)\n+19E8C Compression Method    0000 (0) 'Stored'\n+19E8E Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19E92 CRC                   00000000 (0)\n+19E96 Compressed Size       00000000 (0)\n+19E9A Uncompressed Size     00000000 (0)\n+19E9E Filename Length       000F (15)\n+19EA0 Extra Length          0009 (9)\n+19EA2 Comment Length        0000 (0)\n+19EA4 Disk Start            0000 (0)\n+19EA6 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19EA8 Ext File Attributes   00000000 (0)\n+19EAC Local Header Offset   00003ABA (15034)\n+19EB0 Filename              'XXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19EB0: Filename 'XXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19EBF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19EC1   Length              0005 (5)\n+19EC3   Flags               01 (1) 'Modification'\n+19EC4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19EC8 CENTRAL HEADER #10    02014B50 (33639248)\n+19ECC Created Zip Spec      14 (20) '2.0'\n+19ECD Created OS            00 (0) 'MS-DOS'\n+19ECE Extract Zip Spec      14 (20) '2.0'\n+19ECF Extract OS            00 (0) 'MS-DOS'\n+19ED0 General Purpose Flag  0000 (0)\n+19ED2 Compression Method    0000 (0) 'Stored'\n+19ED4 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19ED8 CRC                   00000000 (0)\n+19EDC Compressed Size       00000000 (0)\n+19EE0 Uncompressed Size     00000000 (0)\n+19EE4 Filename Length       0020 (32)\n+19EE6 Extra Length          0009 (9)\n+19EE8 Comment Length        0000 (0)\n+19EEA Disk Start            0000 (0)\n+19EEC Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19EEE Ext File Attributes   00000000 (0)\n+19EF2 Local Header Offset   00003AF0 (15088)\n+19EF6 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19EF6: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19F16 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19F18   Length              0005 (5)\n+19F1A   Flags               01 (1) 'Modification'\n+19F1B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19F1F CENTRAL HEADER #11    02014B50 (33639248)\n+19F23 Created Zip Spec      14 (20) '2.0'\n+19F24 Created OS            00 (0) 'MS-DOS'\n+19F25 Extract Zip Spec      14 (20) '2.0'\n+19F26 Extract OS            00 (0) 'MS-DOS'\n+19F27 General Purpose Flag  0000 (0)\n+19F29 Compression Method    0000 (0) 'Stored'\n+19F2B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19F2F CRC                   00000000 (0)\n+19F33 Compressed Size       00000000 (0)\n+19F37 Uncompressed Size     00000000 (0)\n+19F3B Filename Length       0036 (54)\n+19F3D Extra Length          0009 (9)\n+19F3F Comment Length        0000 (0)\n+19F41 Disk Start            0000 (0)\n+19F43 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19F45 Ext File Attributes   00000000 (0)\n+19F49 Local Header Offset   00003B37 (15159)\n+19F4D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19F4D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19F83 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+19F85   Length              0005 (5)\n+19F87   Flags               01 (1) 'Modification'\n+19F88   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+19F8C CENTRAL HEADER #12    02014B50 (33639248)\n+19F90 Created Zip Spec      14 (20) '2.0'\n+19F91 Created OS            00 (0) 'MS-DOS'\n+19F92 Extract Zip Spec      14 (20) '2.0'\n+19F93 Extract OS            00 (0) 'MS-DOS'\n+19F94 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+19F96 Compression Method    0000 (0) 'Stored'\n+19F98 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+19F9C CRC                   00000000 (0)\n+19FA0 Compressed Size       00000000 (0)\n+19FA4 Uncompressed Size     00000000 (0)\n+19FA8 Filename Length       0044 (68)\n+19FAA Extra Length          0009 (9)\n+19FAC Comment Length        0000 (0)\n+19FAE Disk Start            0000 (0)\n+19FB0 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+19FB2 Ext File Attributes   00000000 (0)\n+19FB6 Local Header Offset   00003B94 (15252)\n+19FBA Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x19FBA: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+19FFE Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A000   Length              0005 (5)\n+1A002   Flags               01 (1) 'Modification'\n+1A003   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A007 CENTRAL HEADER #13    02014B50 (33639248)\n+1A00B Created Zip Spec      14 (20) '2.0'\n+1A00C Created OS            00 (0) 'MS-DOS'\n+1A00D Extract Zip Spec      14 (20) '2.0'\n+1A00E Extract OS            00 (0) 'MS-DOS'\n+1A00F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A011 Compression Method    0000 (0) 'Stored'\n+1A013 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A017 CRC                   1D29AE65 (489270885)\n+1A01B Compressed Size       00000924 (2340)\n+1A01F Uncompressed Size     00000924 (2340)\n+1A023 Filename Length       003D (61)\n+1A025 Extra Length          0009 (9)\n+1A027 Comment Length        0000 (0)\n+1A029 Disk Start            0000 (0)\n+1A02B Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A02D Ext File Attributes   00000000 (0)\n+1A031 Local Header Offset   00003C0F (15375)\n+1A035 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A035: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A072 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A074   Length              0005 (5)\n+1A076   Flags               01 (1) 'Modification'\n+1A077   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A07B CENTRAL HEADER #14    02014B50 (33639248)\n+1A07F Created Zip Spec      14 (20) '2.0'\n+1A080 Created OS            00 (0) 'MS-DOS'\n+1A081 Extract Zip Spec      14 (20) '2.0'\n+1A082 Extract OS            00 (0) 'MS-DOS'\n+1A083 General Purpose Flag  0000 (0)\n+1A085 Compression Method    0000 (0) 'Stored'\n+1A087 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A08B CRC                   00000000 (0)\n+1A08F Compressed Size       00000000 (0)\n+1A093 Uncompressed Size     00000000 (0)\n+1A097 Filename Length       0004 (4)\n+1A099 Extra Length          0009 (9)\n+1A09B Comment Length        0000 (0)\n+1A09D Disk Start            0000 (0)\n+1A09F Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A0A1 Ext File Attributes   00000000 (0)\n+1A0A5 Local Header Offset   000045A7 (17831)\n+1A0A9 Filename              'XXXX'\n+#\n+# WARNING: Offset 0x1A0A9: Filename 'XXXX'\n+#          Zero length filename\n+#\n+1A0AD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A0AF   Length              0005 (5)\n+1A0B1   Flags               01 (1) 'Modification'\n+1A0B2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A0B6 CENTRAL HEADER #15    02014B50 (33639248)\n+1A0BA Created Zip Spec      14 (20) '2.0'\n+1A0BB Created OS            00 (0) 'MS-DOS'\n+1A0BC Extract Zip Spec      14 (20) '2.0'\n+1A0BD Extract OS            00 (0) 'MS-DOS'\n+1A0BE General Purpose Flag  0000 (0)\n+1A0C0 Compression Method    0000 (0) 'Stored'\n+1A0C2 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A0C6 CRC                   00000000 (0)\n+1A0CA Compressed Size       00000000 (0)\n+1A0CE Uncompressed Size     00000000 (0)\n+1A0D2 Filename Length       000B (11)\n+1A0D4 Extra Length          0009 (9)\n+1A0D6 Comment Length        0000 (0)\n+1A0D8 Disk Start            0000 (0)\n+1A0DA Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A0DC Ext File Attributes   00000000 (0)\n+1A0E0 Local Header Offset   000045D2 (17874)\n+1A0E4 Filename              'XXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A0E4: Filename 'XXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A0EF Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A0F1   Length              0005 (5)\n+1A0F3   Flags               01 (1) 'Modification'\n+1A0F4   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A0F8 CENTRAL HEADER #16    02014B50 (33639248)\n+1A0FC Created Zip Spec      14 (20) '2.0'\n+1A0FD Created OS            00 (0) 'MS-DOS'\n+1A0FE Extract Zip Spec      14 (20) '2.0'\n+1A0FF Extract OS            00 (0) 'MS-DOS'\n+1A100 General Purpose Flag  0000 (0)\n+1A102 Compression Method    0000 (0) 'Stored'\n+1A104 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A108 CRC                   00000000 (0)\n+1A10C Compressed Size       00000000 (0)\n+1A110 Uncompressed Size     00000000 (0)\n+1A114 Filename Length       0011 (17)\n+1A116 Extra Length          0009 (9)\n+1A118 Comment Length        0000 (0)\n+1A11A Disk Start            0000 (0)\n+1A11C Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A11E Ext File Attributes   00000000 (0)\n+1A122 Local Header Offset   00004604 (17924)\n+1A126 Filename              'XXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A126: Filename 'XXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A137 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A139   Length              0005 (5)\n+1A13B   Flags               01 (1) 'Modification'\n+1A13C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A140 CENTRAL HEADER #17    02014B50 (33639248)\n+1A144 Created Zip Spec      14 (20) '2.0'\n+1A145 Created OS            00 (0) 'MS-DOS'\n+1A146 Extract Zip Spec      14 (20) '2.0'\n+1A147 Extract OS            00 (0) 'MS-DOS'\n+1A148 General Purpose Flag  0000 (0)\n+1A14A Compression Method    0000 (0) 'Stored'\n+1A14C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A150 CRC                   00000000 (0)\n+1A154 Compressed Size       00000000 (0)\n+1A158 Uncompressed Size     00000000 (0)\n+1A15C Filename Length       001A (26)\n+1A15E Extra Length          0009 (9)\n+1A160 Comment Length        0000 (0)\n+1A162 Disk Start            0000 (0)\n+1A164 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A166 Ext File Attributes   00000000 (0)\n+1A16A Local Header Offset   0000463C (17980)\n+1A16E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A16E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A188 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A18A   Length              0005 (5)\n+1A18C   Flags               01 (1) 'Modification'\n+1A18D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A191 CENTRAL HEADER #18    02014B50 (33639248)\n+1A195 Created Zip Spec      14 (20) '2.0'\n+1A196 Created OS            00 (0) 'MS-DOS'\n+1A197 Extract Zip Spec      14 (20) '2.0'\n+1A198 Extract OS            00 (0) 'MS-DOS'\n+1A199 General Purpose Flag  0000 (0)\n+1A19B Compression Method    0000 (0) 'Stored'\n+1A19D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A1A1 CRC                   00000000 (0)\n+1A1A5 Compressed Size       00000000 (0)\n+1A1A9 Uncompressed Size     00000000 (0)\n+1A1AD Filename Length       0024 (36)\n+1A1AF Extra Length          0009 (9)\n+1A1B1 Comment Length        0000 (0)\n+1A1B3 Disk Start            0000 (0)\n+1A1B5 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A1B7 Ext File Attributes   00000000 (0)\n+1A1BB Local Header Offset   0000467D (18045)\n+1A1BF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A1BF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A1E3 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A1E5   Length              0005 (5)\n+1A1E7   Flags               01 (1) 'Modification'\n+1A1E8   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A1EC CENTRAL HEADER #19    02014B50 (33639248)\n+1A1F0 Created Zip Spec      14 (20) '2.0'\n+1A1F1 Created OS            00 (0) 'MS-DOS'\n+1A1F2 Extract Zip Spec      14 (20) '2.0'\n+1A1F3 Extract OS            00 (0) 'MS-DOS'\n+1A1F4 General Purpose Flag  0000 (0)\n+1A1F6 Compression Method    0000 (0) 'Stored'\n+1A1F8 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A1FC CRC                   00000000 (0)\n+1A200 Compressed Size       00000000 (0)\n+1A204 Uncompressed Size     00000000 (0)\n+1A208 Filename Length       002B (43)\n+1A20A Extra Length          0009 (9)\n+1A20C Comment Length        0000 (0)\n+1A20E Disk Start            0000 (0)\n+1A210 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A212 Ext File Attributes   00000000 (0)\n+1A216 Local Header Offset   000046C8 (18120)\n+1A21A Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A21A: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A245 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A247   Length              0005 (5)\n+1A249   Flags               01 (1) 'Modification'\n+1A24A   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A24E CENTRAL HEADER #20    02014B50 (33639248)\n+1A252 Created Zip Spec      14 (20) '2.0'\n+1A253 Created OS            00 (0) 'MS-DOS'\n+1A254 Extract Zip Spec      14 (20) '2.0'\n+1A255 Extract OS            00 (0) 'MS-DOS'\n+1A256 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A258 Compression Method    0000 (0) 'Stored'\n+1A25A Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A25E CRC                   73E7CE8A (1944571530)\n+1A262 Compressed Size       000027E6 (10214)\n+1A266 Uncompressed Size     000027E6 (10214)\n+1A26A Filename Length       0048 (72)\n+1A26C Extra Length          0009 (9)\n+1A26E Comment Length        0000 (0)\n+1A270 Disk Start            0000 (0)\n+1A272 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A274 Ext File Attributes   00000000 (0)\n+1A278 Local Header Offset   0000471A (18202)\n+1A27C Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A27C: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A2C4 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A2C6   Length              0005 (5)\n+1A2C8   Flags               01 (1) 'Modification'\n+1A2C9   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A2CD CENTRAL HEADER #21    02014B50 (33639248)\n+1A2D1 Created Zip Spec      14 (20) '2.0'\n+1A2D2 Created OS            00 (0) 'MS-DOS'\n+1A2D3 Extract Zip Spec      14 (20) '2.0'\n+1A2D4 Extract OS            00 (0) 'MS-DOS'\n+1A2D5 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A2D7 Compression Method    0000 (0) 'Stored'\n+1A2D9 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A2DD CRC                   EADF50E0 (3940503776)\n+1A2E1 Compressed Size       00002355 (9045)\n+1A2E5 Uncompressed Size     00002355 (9045)\n+1A2E9 Filename Length       003C (60)\n+1A2EB Extra Length          0009 (9)\n+1A2ED Comment Length        0000 (0)\n+1A2EF Disk Start            0000 (0)\n+1A2F1 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A2F3 Ext File Attributes   00000000 (0)\n+1A2F7 Local Header Offset   00006F7F (28543)\n+1A2FB Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A2FB: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A337 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A339   Length              0005 (5)\n+1A33B   Flags               01 (1) 'Modification'\n+1A33C   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A340 CENTRAL HEADER #22    02014B50 (33639248)\n+1A344 Created Zip Spec      14 (20) '2.0'\n+1A345 Created OS            00 (0) 'MS-DOS'\n+1A346 Extract Zip Spec      14 (20) '2.0'\n+1A347 Extract OS            00 (0) 'MS-DOS'\n+1A348 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A34A Compression Method    0000 (0) 'Stored'\n+1A34C Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A350 CRC                   1CB2BCAF (481475759)\n+1A354 Compressed Size       0000251F (9503)\n+1A358 Uncompressed Size     0000251F (9503)\n+1A35C Filename Length       003B (59)\n+1A35E Extra Length          0009 (9)\n+1A360 Comment Length        0000 (0)\n+1A362 Disk Start            0000 (0)\n+1A364 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A366 Ext File Attributes   00000000 (0)\n+1A36A Local Header Offset   00009347 (37703)\n+1A36E Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A36E: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A3A9 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A3AB   Length              0005 (5)\n+1A3AD   Flags               01 (1) 'Modification'\n+1A3AE   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A3B2 CENTRAL HEADER #23    02014B50 (33639248)\n+1A3B6 Created Zip Spec      14 (20) '2.0'\n+1A3B7 Created OS            00 (0) 'MS-DOS'\n+1A3B8 Extract Zip Spec      14 (20) '2.0'\n+1A3B9 Extract OS            00 (0) 'MS-DOS'\n+1A3BA General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A3BC Compression Method    0000 (0) 'Stored'\n+1A3BE Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A3C2 CRC                   7DE2A421 (2112005153)\n+1A3C6 Compressed Size       0000190A (6410)\n+1A3CA Uncompressed Size     0000190A (6410)\n+1A3CE Filename Length       0042 (66)\n+1A3D0 Extra Length          0009 (9)\n+1A3D2 Comment Length        0000 (0)\n+1A3D4 Disk Start            0000 (0)\n+1A3D6 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A3D8 Ext File Attributes   00000000 (0)\n+1A3DC Local Header Offset   0000B8D8 (47320)\n+1A3E0 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A3E0: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A422 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A424   Length              0005 (5)\n+1A426   Flags               01 (1) 'Modification'\n+1A427   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A42B CENTRAL HEADER #24    02014B50 (33639248)\n+1A42F Created Zip Spec      14 (20) '2.0'\n+1A430 Created OS            00 (0) 'MS-DOS'\n+1A431 Extract Zip Spec      14 (20) '2.0'\n+1A432 Extract OS            00 (0) 'MS-DOS'\n+1A433 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A435 Compression Method    0000 (0) 'Stored'\n+1A437 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A43B CRC                   3BA2E25A (1000530522)\n+1A43F Compressed Size       00000E40 (3648)\n+1A443 Uncompressed Size     00000E40 (3648)\n+1A447 Filename Length       0041 (65)\n+1A449 Extra Length          0009 (9)\n+1A44B Comment Length        0000 (0)\n+1A44D Disk Start            0000 (0)\n+1A44F Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A451 Ext File Attributes   00000000 (0)\n+1A455 Local Header Offset   0000D25B (53851)\n+1A459 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A459: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A49A Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A49C   Length              0005 (5)\n+1A49E   Flags               01 (1) 'Modification'\n+1A49F   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A4A3 CENTRAL HEADER #25    02014B50 (33639248)\n+1A4A7 Created Zip Spec      14 (20) '2.0'\n+1A4A8 Created OS            00 (0) 'MS-DOS'\n+1A4A9 Extract Zip Spec      14 (20) '2.0'\n+1A4AA Extract OS            00 (0) 'MS-DOS'\n+1A4AB General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A4AD Compression Method    0000 (0) 'Stored'\n+1A4AF Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A4B3 CRC                   1E5B2A86 (509291142)\n+1A4B7 Compressed Size       00000A9A (2714)\n+1A4BB Uncompressed Size     00000A9A (2714)\n+1A4BF Filename Length       0045 (69)\n+1A4C1 Extra Length          0009 (9)\n+1A4C3 Comment Length        0000 (0)\n+1A4C5 Disk Start            0000 (0)\n+1A4C7 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A4C9 Ext File Attributes   00000000 (0)\n+1A4CD Local Header Offset   0000E113 (57619)\n+1A4D1 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A4D1: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A516 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A518   Length              0005 (5)\n+1A51A   Flags               01 (1) 'Modification'\n+1A51B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A51F CENTRAL HEADER #26    02014B50 (33639248)\n+1A523 Created Zip Spec      14 (20) '2.0'\n+1A524 Created OS            00 (0) 'MS-DOS'\n+1A525 Extract Zip Spec      14 (20) '2.0'\n+1A526 Extract OS            00 (0) 'MS-DOS'\n+1A527 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A529 Compression Method    0000 (0) 'Stored'\n+1A52B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A52F CRC                   1CDD10AA (484249770)\n+1A533 Compressed Size       00001FCD (8141)\n+1A537 Uncompressed Size     00001FCD (8141)\n+1A53B Filename Length       003B (59)\n+1A53D Extra Length          0009 (9)\n+1A53F Comment Length        0000 (0)\n+1A541 Disk Start            0000 (0)\n+1A543 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A545 Ext File Attributes   00000000 (0)\n+1A549 Local Header Offset   0000EC29 (60457)\n+1A54D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A54D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A588 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A58A   Length              0005 (5)\n+1A58C   Flags               01 (1) 'Modification'\n+1A58D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A591 CENTRAL HEADER #27    02014B50 (33639248)\n+1A595 Created Zip Spec      14 (20) '2.0'\n+1A596 Created OS            00 (0) 'MS-DOS'\n+1A597 Extract Zip Spec      14 (20) '2.0'\n+1A598 Extract OS            00 (0) 'MS-DOS'\n+1A599 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A59B Compression Method    0000 (0) 'Stored'\n+1A59D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A5A1 CRC                   52A8EAC6 (1386801862)\n+1A5A5 Compressed Size       00001505 (5381)\n+1A5A9 Uncompressed Size     00001505 (5381)\n+1A5AD Filename Length       0042 (66)\n+1A5AF Extra Length          0009 (9)\n+1A5B1 Comment Length        0000 (0)\n+1A5B3 Disk Start            0000 (0)\n+1A5B5 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A5B7 Ext File Attributes   00000000 (0)\n+1A5BB Local Header Offset   00010C68 (68712)\n+1A5BF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A5BF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A601 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A603   Length              0005 (5)\n+1A605   Flags               01 (1) 'Modification'\n+1A606   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A60A CENTRAL HEADER #28    02014B50 (33639248)\n+1A60E Created Zip Spec      14 (20) '2.0'\n+1A60F Created OS            00 (0) 'MS-DOS'\n+1A610 Extract Zip Spec      14 (20) '2.0'\n+1A611 Extract OS            00 (0) 'MS-DOS'\n+1A612 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A614 Compression Method    0000 (0) 'Stored'\n+1A616 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A61A CRC                   1AC58108 (449151240)\n+1A61E Compressed Size       00000679 (1657)\n+1A622 Uncompressed Size     00000679 (1657)\n+1A626 Filename Length       0040 (64)\n+1A628 Extra Length          0009 (9)\n+1A62A Comment Length        0000 (0)\n+1A62C Disk Start            0000 (0)\n+1A62E Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A630 Ext File Attributes   00000000 (0)\n+1A634 Local Header Offset   000121E6 (74214)\n+1A638 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A638: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A678 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A67A   Length              0005 (5)\n+1A67C   Flags               01 (1) 'Modification'\n+1A67D   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A681 CENTRAL HEADER #29    02014B50 (33639248)\n+1A685 Created Zip Spec      14 (20) '2.0'\n+1A686 Created OS            00 (0) 'MS-DOS'\n+1A687 Extract Zip Spec      14 (20) '2.0'\n+1A688 Extract OS            00 (0) 'MS-DOS'\n+1A689 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A68B Compression Method    0000 (0) 'Stored'\n+1A68D Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A691 CRC                   377C624A (930898506)\n+1A695 Compressed Size       00001627 (5671)\n+1A699 Uncompressed Size     00001627 (5671)\n+1A69D Filename Length       003B (59)\n+1A69F Extra Length          0009 (9)\n+1A6A1 Comment Length        0000 (0)\n+1A6A3 Disk Start            0000 (0)\n+1A6A5 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A6A7 Ext File Attributes   00000000 (0)\n+1A6AB Local Header Offset   000128D6 (75990)\n+1A6AF Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A6AF: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A6EA Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A6EC   Length              0005 (5)\n+1A6EE   Flags               01 (1) 'Modification'\n+1A6EF   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A6F3 CENTRAL HEADER #30    02014B50 (33639248)\n+1A6F7 Created Zip Spec      14 (20) '2.0'\n+1A6F8 Created OS            00 (0) 'MS-DOS'\n+1A6F9 Extract Zip Spec      14 (20) '2.0'\n+1A6FA Extract OS            00 (0) 'MS-DOS'\n+1A6FB General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A6FD Compression Method    0000 (0) 'Stored'\n+1A6FF Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A703 CRC                   37334079 (926105721)\n+1A707 Compressed Size       00001758 (5976)\n+1A70B Uncompressed Size     00001758 (5976)\n+1A70F Filename Length       0045 (69)\n+1A711 Extra Length          0009 (9)\n+1A713 Comment Length        0000 (0)\n+1A715 Disk Start            0000 (0)\n+1A717 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A719 Ext File Attributes   00000000 (0)\n+1A71D Local Header Offset   00013F6F (81775)\n+1A721 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A721: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A766 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A768   Length              0005 (5)\n+1A76A   Flags               01 (1) 'Modification'\n+1A76B   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A76F CENTRAL HEADER #31    02014B50 (33639248)\n+1A773 Created Zip Spec      14 (20) '2.0'\n+1A774 Created OS            00 (0) 'MS-DOS'\n+1A775 Extract Zip Spec      14 (20) '2.0'\n+1A776 Extract OS            00 (0) 'MS-DOS'\n+1A777 General Purpose Flag  0000 (0)\n+1A779 Compression Method    0000 (0) 'Stored'\n+1A77B Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A77F CRC                   00000000 (0)\n+1A783 Compressed Size       00000000 (0)\n+1A787 Uncompressed Size     00000000 (0)\n+1A78B Filename Length       0033 (51)\n+1A78D Extra Length          0009 (9)\n+1A78F Comment Length        0000 (0)\n+1A791 Disk Start            0000 (0)\n+1A793 Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A795 Ext File Attributes   00000000 (0)\n+1A799 Local Header Offset   00015743 (87875)\n+1A79D Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A79D: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A7D0 Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A7D2   Length              0005 (5)\n+1A7D4   Flags               01 (1) 'Modification'\n+1A7D5   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A7D9 CENTRAL HEADER #32    02014B50 (33639248)\n+1A7DD Created Zip Spec      14 (20) '2.0'\n+1A7DE Created OS            00 (0) 'MS-DOS'\n+1A7DF Extract Zip Spec      14 (20) '2.0'\n+1A7E0 Extract OS            00 (0) 'MS-DOS'\n+1A7E1 General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A7E3 Compression Method    0000 (0) 'Stored'\n+1A7E5 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A7E9 CRC                   58FEAB57 (1493085015)\n+1A7ED Compressed Size       000008C3 (2243)\n+1A7F1 Uncompressed Size     000008C3 (2243)\n+1A7F5 Filename Length       0047 (71)\n+1A7F7 Extra Length          0009 (9)\n+1A7F9 Comment Length        0000 (0)\n+1A7FB Disk Start            0000 (0)\n+1A7FD Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A7FF Ext File Attributes   00000000 (0)\n+1A803 Local Header Offset   0001579D (87965)\n+1A807 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A807: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A84E Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A850   Length              0005 (5)\n+1A852   Flags               01 (1) 'Modification'\n+1A853   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A857 CENTRAL HEADER #33    02014B50 (33639248)\n+1A85B Created Zip Spec      14 (20) '2.0'\n+1A85C Created OS            00 (0) 'MS-DOS'\n+1A85D Extract Zip Spec      14 (20) '2.0'\n+1A85E Extract OS            00 (0) 'MS-DOS'\n+1A85F General Purpose Flag  0008 (8)\n+      [Bit  3]              1 'Streamed'\n+1A861 Compression Method    0000 (0) 'Stored'\n+1A863 Modification Time     EC210000 (3961585664) 'Wed Jan  1 00:00:00 2098'\n+1A867 CRC                   A355BCB4 (2740305076)\n+1A86B Compressed Size       00003AB8 (15032)\n+1A86F Uncompressed Size     00003AB8 (15032)\n+1A873 Filename Length       0048 (72)\n+1A875 Extra Length          0009 (9)\n+1A877 Comment Length        0000 (0)\n+1A879 Disk Start            0000 (0)\n+1A87B Int File Attributes   0000 (0)\n+      [Bit 0]               0 'Binary Data'\n+1A87D Ext File Attributes   00000000 (0)\n+1A881 Local Header Offset   000160DE (90334)\n+1A885 Filename              'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#\n+# WARNING: Offset 0x1A885: Filename 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'\n+#          Zero length filename\n+#\n+1A8CD Extra ID #1           5455 (21589) 'Extended Timestamp [UT]'\n+1A8CF   Length              0005 (5)\n+1A8D1   Flags               01 (1) 'Modification'\n+1A8D2   Modification Time   00000000 (0) 'Thu Jan  1 00:00:00 1970'\n+\n+1A8D6 END CENTRAL HEADER    06054B50 (101010256)\n+1A8DA Number of this disk   0000 (0)\n+1A8DC Central Dir Disk no   0000 (0)\n+1A8DE Entries in this disk  0021 (33)\n+1A8E0 Total Entries         0021 (33)\n+1A8E2 Size of Central Dir   00000CC1 (3265)\n+1A8E6 Offset to Central Dir 00019C15 (105493)\n+1A8EA Comment Length        0000 (0)\n #\n # Warning Count: 66\n #\n # Done\n"}, {"source1": "META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml", "source2": "META-INF/maven/org.apache.dubbo/dubbo-remoting-netty4/pom.xml", "comments": ["Format-specific differences are supported for XML files but no file-specific differences were detected; falling back to a binary diff. file(1) reports: XML 1.0 document, ASCII text, with CRLF line terminators"], "has_internal_linenos": true, "unified_diff": "@@ -1,150 +1,147 @@\n 00000000: 3c3f 786d 6c20 7665 7273 696f 6e3d 2231  <?xml version=\"1\n 00000010: 2e30 2220 656e 636f 6469 6e67 3d22 5554  .0\" encoding=\"UT\n-00000020: 462d 3822 3f3e 0d0a 3c21 2d2d 0d0a 2020  F-8\"?>..<!--..  \n-00000030: 4c69 6365 6e73 6564 2074 6f20 7468 6520  Licensed to the \n-00000040: 4170 6163 6865 2053 6f66 7477 6172 6520  Apache Software \n-00000050: 466f 756e 6461 7469 6f6e 2028 4153 4629  Foundation (ASF)\n-00000060: 2075 6e64 6572 206f 6e65 206f 7220 6d6f   under one or mo\n-00000070: 7265 0d0a 2020 636f 6e74 7269 6275 746f  re..  contributo\n-00000080: 7220 6c69 6365 6e73 6520 6167 7265 656d  r license agreem\n-00000090: 656e 7473 2e20 2053 6565 2074 6865 204e  ents.  See the N\n-000000a0: 4f54 4943 4520 6669 6c65 2064 6973 7472  OTICE file distr\n-000000b0: 6962 7574 6564 2077 6974 680d 0a20 2074  ibuted with..  t\n-000000c0: 6869 7320 776f 726b 2066 6f72 2061 6464  his work for add\n-000000d0: 6974 696f 6e61 6c20 696e 666f 726d 6174  itional informat\n-000000e0: 696f 6e20 7265 6761 7264 696e 6720 636f  ion regarding co\n-000000f0: 7079 7269 6768 7420 6f77 6e65 7273 6869  pyright ownershi\n-00000100: 702e 0d0a 2020 5468 6520 4153 4620 6c69  p...  The ASF li\n-00000110: 6365 6e73 6573 2074 6869 7320 6669 6c65  censes this file\n-00000120: 2074 6f20 596f 7520 756e 6465 7220 7468   to You under th\n-00000130: 6520 4170 6163 6865 204c 6963 656e 7365  e Apache License\n-00000140: 2c20 5665 7273 696f 6e20 322e 300d 0a20  , Version 2.0.. \n-00000150: 2028 7468 6520 224c 6963 656e 7365 2229   (the \"License\")\n-00000160: 3b20 796f 7520 6d61 7920 6e6f 7420 7573  ; you may not us\n-00000170: 6520 7468 6973 2066 696c 6520 6578 6365  e this file exce\n-00000180: 7074 2069 6e20 636f 6d70 6c69 616e 6365  pt in compliance\n-00000190: 2077 6974 680d 0a20 2074 6865 204c 6963   with..  the Lic\n-000001a0: 656e 7365 2e20 2059 6f75 206d 6179 206f  ense.  You may o\n-000001b0: 6274 6169 6e20 6120 636f 7079 206f 6620  btain a copy of \n-000001c0: 7468 6520 4c69 6365 6e73 6520 6174 0d0a  the License at..\n-000001d0: 0d0a 2020 2020 2020 6874 7470 3a2f 2f77  ..      http://w\n-000001e0: 7777 2e61 7061 6368 652e 6f72 672f 6c69  ww.apache.org/li\n-000001f0: 6365 6e73 6573 2f4c 4943 454e 5345 2d32  censes/LICENSE-2\n-00000200: 2e30 0d0a 0d0a 2020 556e 6c65 7373 2072  .0....  Unless r\n-00000210: 6571 7569 7265 6420 6279 2061 7070 6c69  equired by appli\n-00000220: 6361 626c 6520 6c61 7720 6f72 2061 6772  cable law or agr\n-00000230: 6565 6420 746f 2069 6e20 7772 6974 696e  eed to in writin\n-00000240: 672c 2073 6f66 7477 6172 650d 0a20 2064  g, software..  d\n-00000250: 6973 7472 6962 7574 6564 2075 6e64 6572  istributed under\n-00000260: 2074 6865 204c 6963 656e 7365 2069 7320   the License is \n-00000270: 6469 7374 7269 6275 7465 6420 6f6e 2061  distributed on a\n-00000280: 6e20 2241 5320 4953 2220 4241 5349 532c  n \"AS IS\" BASIS,\n-00000290: 0d0a 2020 5749 5448 4f55 5420 5741 5252  ..  WITHOUT WARR\n-000002a0: 414e 5449 4553 204f 5220 434f 4e44 4954  ANTIES OR CONDIT\n-000002b0: 494f 4e53 204f 4620 414e 5920 4b49 4e44  IONS OF ANY KIND\n-000002c0: 2c20 6569 7468 6572 2065 7870 7265 7373  , either express\n-000002d0: 206f 7220 696d 706c 6965 642e 0d0a 2020   or implied...  \n-000002e0: 5365 6520 7468 6520 4c69 6365 6e73 6520  See the License \n-000002f0: 666f 7220 7468 6520 7370 6563 6966 6963  for the specific\n-00000300: 206c 616e 6775 6167 6520 676f 7665 726e   language govern\n-00000310: 696e 6720 7065 726d 6973 7369 6f6e 7320  ing permissions \n-00000320: 616e 640d 0a20 206c 696d 6974 6174 696f  and..  limitatio\n-00000330: 6e73 2075 6e64 6572 2074 6865 204c 6963  ns under the Lic\n-00000340: 656e 7365 2e0d 0a20 202d 2d3e 0d0a 3c70  ense...  -->..<p\n-00000350: 726f 6a65 6374 2078 7369 3a73 6368 656d  roject xsi:schem\n-00000360: 614c 6f63 6174 696f 6e3d 2268 7474 703a  aLocation=\"http:\n-00000370: 2f2f 6d61 7665 6e2e 6170 6163 6865 2e6f  //maven.apache.o\n-00000380: 7267 2f50 4f4d 2f34 2e30 2e30 2068 7474  rg/POM/4.0.0 htt\n-00000390: 7073 3a2f 2f6d 6176 656e 2e61 7061 6368  ps://maven.apach\n-000003a0: 652e 6f72 672f 7873 642f 6d61 7665 6e2d  e.org/xsd/maven-\n-000003b0: 342e 302e 302e 7873 6422 2078 6d6c 6e73  4.0.0.xsd\" xmlns\n-000003c0: 3d22 6874 7470 3a2f 2f6d 6176 656e 2e61  =\"http://maven.a\n-000003d0: 7061 6368 652e 6f72 672f 504f 4d2f 342e  pache.org/POM/4.\n-000003e0: 302e 3022 0d0a 2020 2020 786d 6c6e 733a  0.0\"..    xmlns:\n-000003f0: 7873 693d 2268 7474 703a 2f2f 7777 772e  xsi=\"http://www.\n-00000400: 7733 2e6f 7267 2f32 3030 312f 584d 4c53  w3.org/2001/XMLS\n-00000410: 6368 656d 612d 696e 7374 616e 6365 223e  chema-instance\">\n-00000420: 0d0a 2020 3c6d 6f64 656c 5665 7273 696f  ..  <modelVersio\n-00000430: 6e3e 342e 302e 303c 2f6d 6f64 656c 5665  n>4.0.0</modelVe\n-00000440: 7273 696f 6e3e 0d0a 2020 3c70 6172 656e  rsion>..  <paren\n-00000450: 743e 0d0a 2020 2020 3c67 726f 7570 4964  t>..    <groupId\n-00000460: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n-00000470: 6f3c 2f67 726f 7570 4964 3e0d 0a20 2020  o</groupId>..   \n-00000480: 203c 6172 7469 6661 6374 4964 3e64 7562   <artifactId>dub\n-00000490: 626f 2d72 656d 6f74 696e 673c 2f61 7274  bo-remoting</art\n-000004a0: 6966 6163 7449 643e 0d0a 2020 2020 3c76  ifactId>..    <v\n-000004b0: 6572 7369 6f6e 3e32 2e37 2e31 303c 2f76  ersion>2.7.10</v\n-000004c0: 6572 7369 6f6e 3e0d 0a20 203c 2f70 6172  ersion>..  </par\n-000004d0: 656e 743e 0d0a 2020 3c67 726f 7570 4964  ent>..  <groupId\n-000004e0: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n-000004f0: 6f3c 2f67 726f 7570 4964 3e0d 0a20 203c  o</groupId>..  <\n-00000500: 6172 7469 6661 6374 4964 3e64 7562 626f  artifactId>dubbo\n-00000510: 2d72 656d 6f74 696e 672d 6e65 7474 7934  -remoting-netty4\n-00000520: 3c2f 6172 7469 6661 6374 4964 3e0d 0a20  </artifactId>.. \n-00000530: 203c 7665 7273 696f 6e3e 322e 372e 3130   <version>2.7.10\n-00000540: 3c2f 7665 7273 696f 6e3e 0d0a 2020 3c6e  </version>..  <n\n-00000550: 616d 653e 247b 7072 6f6a 6563 742e 6172  ame>${project.ar\n-00000560: 7469 6661 6374 4964 7d3c 2f6e 616d 653e  tifactId}</name>\n-00000570: 0d0a 2020 3c64 6573 6372 6970 7469 6f6e  ..  <description\n-00000580: 3e54 6865 206e 6574 7479 3420 7265 6d6f  >The netty4 remo\n-00000590: 7469 6e67 206d 6f64 756c 6520 6f66 2064  ting module of d\n-000005a0: 7562 626f 2070 726f 6a65 6374 3c2f 6465  ubbo project</de\n-000005b0: 7363 7269 7074 696f 6e3e 0d0a 2020 3c6c  scription>..  <l\n-000005c0: 6963 656e 7365 733e 0d0a 2020 2020 3c6c  icenses>..    <l\n-000005d0: 6963 656e 7365 3e0d 0a20 2020 2020 203c  icense>..      <\n-000005e0: 6e61 6d65 3e41 7061 6368 6520 4c69 6365  name>Apache Lice\n-000005f0: 6e73 652c 2056 6572 7369 6f6e 2032 2e30  nse, Version 2.0\n-00000600: 3c2f 6e61 6d65 3e0d 0a20 2020 2020 203c  </name>..      <\n-00000610: 7572 6c3e 6874 7470 3a2f 2f77 7777 2e61  url>http://www.a\n-00000620: 7061 6368 652e 6f72 672f 6c69 6365 6e73  pache.org/licens\n-00000630: 6573 2f4c 4943 454e 5345 2d32 2e30 3c2f  es/LICENSE-2.0</\n-00000640: 7572 6c3e 0d0a 2020 2020 2020 3c64 6973  url>..      <dis\n-00000650: 7472 6962 7574 696f 6e3e 7265 706f 3c2f  tribution>repo</\n-00000660: 6469 7374 7269 6275 7469 6f6e 3e0d 0a20  distribution>.. \n-00000670: 2020 203c 2f6c 6963 656e 7365 3e0d 0a20     </license>.. \n-00000680: 203c 2f6c 6963 656e 7365 733e 0d0a 2020   </licenses>..  \n-00000690: 3c70 726f 7065 7274 6965 733e 0d0a 2020  <properties>..  \n-000006a0: 2020 3c73 6b69 705f 6d61 7665 6e5f 6465    <skip_maven_de\n-000006b0: 706c 6f79 3e66 616c 7365 3c2f 736b 6970  ploy>false</skip\n-000006c0: 5f6d 6176 656e 5f64 6570 6c6f 793e 0d0a  _maven_deploy>..\n-000006d0: 2020 2020 3c70 726f 6a65 6374 2e62 7569      <project.bui\n-000006e0: 6c64 2e73 6f75 7263 6545 6e63 6f64 696e  ld.sourceEncodin\n-000006f0: 673e 5554 462d 383c 2f70 726f 6a65 6374  g>UTF-8</project\n-00000700: 2e62 7569 6c64 2e73 6f75 7263 6545 6e63  .build.sourceEnc\n-00000710: 6f64 696e 673e 0d0a 2020 3c2f 7072 6f70  oding>..  </prop\n-00000720: 6572 7469 6573 3e0d 0a20 203c 6465 7065  erties>..  <depe\n-00000730: 6e64 656e 6369 6573 3e0d 0a20 2020 203c  ndencies>..    <\n-00000740: 6465 7065 6e64 656e 6379 3e0d 0a20 2020  dependency>..   \n-00000750: 2020 203c 6772 6f75 7049 643e 6f72 672e     <groupId>org.\n-00000760: 6170 6163 6865 2e64 7562 626f 3c2f 6772  apache.dubbo</gr\n-00000770: 6f75 7049 643e 0d0a 2020 2020 2020 3c61  oupId>..      <a\n-00000780: 7274 6966 6163 7449 643e 6475 6262 6f2d  rtifactId>dubbo-\n-00000790: 7265 6d6f 7469 6e67 2d61 7069 3c2f 6172  remoting-api</ar\n-000007a0: 7469 6661 6374 4964 3e0d 0a20 2020 2020  tifactId>..     \n-000007b0: 203c 7665 7273 696f 6e3e 247b 7072 6f6a   <version>${proj\n-000007c0: 6563 742e 7061 7265 6e74 2e76 6572 7369  ect.parent.versi\n-000007d0: 6f6e 7d3c 2f76 6572 7369 6f6e 3e0d 0a20  on}</version>.. \n-000007e0: 2020 203c 2f64 6570 656e 6465 6e63 793e     </dependency>\n-000007f0: 0d0a 2020 2020 3c64 6570 656e 6465 6e63  ..    <dependenc\n-00000800: 793e 0d0a 2020 2020 2020 3c67 726f 7570  y>..      <group\n-00000810: 4964 3e69 6f2e 6e65 7474 793c 2f67 726f  Id>io.netty</gro\n-00000820: 7570 4964 3e0d 0a20 2020 2020 203c 6172  upId>..      <ar\n-00000830: 7469 6661 6374 4964 3e6e 6574 7479 2d61  tifactId>netty-a\n-00000840: 6c6c 3c2f 6172 7469 6661 6374 4964 3e0d  ll</artifactId>.\n-00000850: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n-00000860: 793e 0d0a 2020 2020 3c64 6570 656e 6465  y>..    <depende\n-00000870: 6e63 793e 0d0a 2020 2020 2020 3c67 726f  ncy>..      <gro\n-00000880: 7570 4964 3e6f 7267 2e61 7061 6368 652e  upId>org.apache.\n-00000890: 6475 6262 6f3c 2f67 726f 7570 4964 3e0d  dubbo</groupId>.\n-000008a0: 0a20 2020 2020 203c 6172 7469 6661 6374  .      <artifact\n-000008b0: 4964 3e64 7562 626f 2d73 6572 6961 6c69  Id>dubbo-seriali\n-000008c0: 7a61 7469 6f6e 2d68 6573 7369 616e 323c  zation-hessian2<\n-000008d0: 2f61 7274 6966 6163 7449 643e 0d0a 2020  /artifactId>..  \n-000008e0: 2020 2020 3c76 6572 7369 6f6e 3e24 7b70      <version>${p\n-000008f0: 726f 6a65 6374 2e70 6172 656e 742e 7665  roject.parent.ve\n-00000900: 7273 696f 6e7d 3c2f 7665 7273 696f 6e3e  rsion}</version>\n-00000910: 0d0a 2020 2020 2020 3c73 636f 7065 3e74  ..      <scope>t\n-00000920: 6573 743c 2f73 636f 7065 3e0d 0a20 2020  est</scope>..   \n-00000930: 203c 2f64 6570 656e 6465 6e63 793e 0d0a   </dependency>..\n-00000940: 2020 3c2f 6465 7065 6e64 656e 6369 6573    </dependencies\n-00000950: 3e0d 0a3c 2f70 726f 6a65 6374 3e0d 0a    >..</project>..\n+00000020: 462d 3822 3f3e 0a3c 212d 2d0a 2020 4c69  F-8\"?>.<!--.  Li\n+00000030: 6365 6e73 6564 2074 6f20 7468 6520 4170  censed to the Ap\n+00000040: 6163 6865 2053 6f66 7477 6172 6520 466f  ache Software Fo\n+00000050: 756e 6461 7469 6f6e 2028 4153 4629 2075  undation (ASF) u\n+00000060: 6e64 6572 206f 6e65 206f 7220 6d6f 7265  nder one or more\n+00000070: 0a20 2063 6f6e 7472 6962 7574 6f72 206c  .  contributor l\n+00000080: 6963 656e 7365 2061 6772 6565 6d65 6e74  icense agreement\n+00000090: 732e 2020 5365 6520 7468 6520 4e4f 5449  s.  See the NOTI\n+000000a0: 4345 2066 696c 6520 6469 7374 7269 6275  CE file distribu\n+000000b0: 7465 6420 7769 7468 0a20 2074 6869 7320  ted with.  this \n+000000c0: 776f 726b 2066 6f72 2061 6464 6974 696f  work for additio\n+000000d0: 6e61 6c20 696e 666f 726d 6174 696f 6e20  nal information \n+000000e0: 7265 6761 7264 696e 6720 636f 7079 7269  regarding copyri\n+000000f0: 6768 7420 6f77 6e65 7273 6869 702e 0a20  ght ownership.. \n+00000100: 2054 6865 2041 5346 206c 6963 656e 7365   The ASF license\n+00000110: 7320 7468 6973 2066 696c 6520 746f 2059  s this file to Y\n+00000120: 6f75 2075 6e64 6572 2074 6865 2041 7061  ou under the Apa\n+00000130: 6368 6520 4c69 6365 6e73 652c 2056 6572  che License, Ver\n+00000140: 7369 6f6e 2032 2e30 0a20 2028 7468 6520  sion 2.0.  (the \n+00000150: 224c 6963 656e 7365 2229 3b20 796f 7520  \"License\"); you \n+00000160: 6d61 7920 6e6f 7420 7573 6520 7468 6973  may not use this\n+00000170: 2066 696c 6520 6578 6365 7074 2069 6e20   file except in \n+00000180: 636f 6d70 6c69 616e 6365 2077 6974 680a  compliance with.\n+00000190: 2020 7468 6520 4c69 6365 6e73 652e 2020    the License.  \n+000001a0: 596f 7520 6d61 7920 6f62 7461 696e 2061  You may obtain a\n+000001b0: 2063 6f70 7920 6f66 2074 6865 204c 6963   copy of the Lic\n+000001c0: 656e 7365 2061 740a 0a20 2020 2020 2068  ense at..      h\n+000001d0: 7474 703a 2f2f 7777 772e 6170 6163 6865  ttp://www.apache\n+000001e0: 2e6f 7267 2f6c 6963 656e 7365 732f 4c49  .org/licenses/LI\n+000001f0: 4345 4e53 452d 322e 300a 0a20 2055 6e6c  CENSE-2.0..  Unl\n+00000200: 6573 7320 7265 7175 6972 6564 2062 7920  ess required by \n+00000210: 6170 706c 6963 6162 6c65 206c 6177 206f  applicable law o\n+00000220: 7220 6167 7265 6564 2074 6f20 696e 2077  r agreed to in w\n+00000230: 7269 7469 6e67 2c20 736f 6674 7761 7265  riting, software\n+00000240: 0a20 2064 6973 7472 6962 7574 6564 2075  .  distributed u\n+00000250: 6e64 6572 2074 6865 204c 6963 656e 7365  nder the License\n+00000260: 2069 7320 6469 7374 7269 6275 7465 6420   is distributed \n+00000270: 6f6e 2061 6e20 2241 5320 4953 2220 4241  on an \"AS IS\" BA\n+00000280: 5349 532c 0a20 2057 4954 484f 5554 2057  SIS,.  WITHOUT W\n+00000290: 4152 5241 4e54 4945 5320 4f52 2043 4f4e  ARRANTIES OR CON\n+000002a0: 4449 5449 4f4e 5320 4f46 2041 4e59 204b  DITIONS OF ANY K\n+000002b0: 494e 442c 2065 6974 6865 7220 6578 7072  IND, either expr\n+000002c0: 6573 7320 6f72 2069 6d70 6c69 6564 2e0a  ess or implied..\n+000002d0: 2020 5365 6520 7468 6520 4c69 6365 6e73    See the Licens\n+000002e0: 6520 666f 7220 7468 6520 7370 6563 6966  e for the specif\n+000002f0: 6963 206c 616e 6775 6167 6520 676f 7665  ic language gove\n+00000300: 726e 696e 6720 7065 726d 6973 7369 6f6e  rning permission\n+00000310: 7320 616e 640a 2020 6c69 6d69 7461 7469  s and.  limitati\n+00000320: 6f6e 7320 756e 6465 7220 7468 6520 4c69  ons under the Li\n+00000330: 6365 6e73 652e 0a20 202d 2d3e 0a3c 7072  cense..  -->.<pr\n+00000340: 6f6a 6563 7420 7873 693a 7363 6865 6d61  oject xsi:schema\n+00000350: 4c6f 6361 7469 6f6e 3d22 6874 7470 3a2f  Location=\"http:/\n+00000360: 2f6d 6176 656e 2e61 7061 6368 652e 6f72  /maven.apache.or\n+00000370: 672f 504f 4d2f 342e 302e 3020 6874 7470  g/POM/4.0.0 http\n+00000380: 733a 2f2f 6d61 7665 6e2e 6170 6163 6865  s://maven.apache\n+00000390: 2e6f 7267 2f78 7364 2f6d 6176 656e 2d34  .org/xsd/maven-4\n+000003a0: 2e30 2e30 2e78 7364 2220 786d 6c6e 733d  .0.0.xsd\" xmlns=\n+000003b0: 2268 7474 703a 2f2f 6d61 7665 6e2e 6170  \"http://maven.ap\n+000003c0: 6163 6865 2e6f 7267 2f50 4f4d 2f34 2e30  ache.org/POM/4.0\n+000003d0: 2e30 220a 2020 2020 786d 6c6e 733a 7873  .0\".    xmlns:xs\n+000003e0: 693d 2268 7474 703a 2f2f 7777 772e 7733  i=\"http://www.w3\n+000003f0: 2e6f 7267 2f32 3030 312f 584d 4c53 6368  .org/2001/XMLSch\n+00000400: 656d 612d 696e 7374 616e 6365 223e 0a20  ema-instance\">. \n+00000410: 203c 6d6f 6465 6c56 6572 7369 6f6e 3e34   <modelVersion>4\n+00000420: 2e30 2e30 3c2f 6d6f 6465 6c56 6572 7369  .0.0</modelVersi\n+00000430: 6f6e 3e0a 2020 3c70 6172 656e 743e 0a20  on>.  <parent>. \n+00000440: 2020 203c 6772 6f75 7049 643e 6f72 672e     <groupId>org.\n+00000450: 6170 6163 6865 2e64 7562 626f 3c2f 6772  apache.dubbo</gr\n+00000460: 6f75 7049 643e 0a20 2020 203c 6172 7469  oupId>.    <arti\n+00000470: 6661 6374 4964 3e64 7562 626f 2d72 656d  factId>dubbo-rem\n+00000480: 6f74 696e 673c 2f61 7274 6966 6163 7449  oting</artifactI\n+00000490: 643e 0a20 2020 203c 7665 7273 696f 6e3e  d>.    <version>\n+000004a0: 322e 372e 3130 3c2f 7665 7273 696f 6e3e  2.7.10</version>\n+000004b0: 0a20 203c 2f70 6172 656e 743e 0a20 203c  .  </parent>.  <\n+000004c0: 6772 6f75 7049 643e 6f72 672e 6170 6163  groupId>org.apac\n+000004d0: 6865 2e64 7562 626f 3c2f 6772 6f75 7049  he.dubbo</groupI\n+000004e0: 643e 0a20 203c 6172 7469 6661 6374 4964  d>.  <artifactId\n+000004f0: 3e64 7562 626f 2d72 656d 6f74 696e 672d  >dubbo-remoting-\n+00000500: 6e65 7474 7934 3c2f 6172 7469 6661 6374  netty4</artifact\n+00000510: 4964 3e0a 2020 3c76 6572 7369 6f6e 3e32  Id>.  <version>2\n+00000520: 2e37 2e31 303c 2f76 6572 7369 6f6e 3e0a  .7.10</version>.\n+00000530: 2020 3c6e 616d 653e 247b 7072 6f6a 6563    <name>${projec\n+00000540: 742e 6172 7469 6661 6374 4964 7d3c 2f6e  t.artifactId}</n\n+00000550: 616d 653e 0a20 203c 6465 7363 7269 7074  ame>.  <descript\n+00000560: 696f 6e3e 5468 6520 6e65 7474 7934 2072  ion>The netty4 r\n+00000570: 656d 6f74 696e 6720 6d6f 6475 6c65 206f  emoting module o\n+00000580: 6620 6475 6262 6f20 7072 6f6a 6563 743c  f dubbo project<\n+00000590: 2f64 6573 6372 6970 7469 6f6e 3e0a 2020  /description>.  \n+000005a0: 3c6c 6963 656e 7365 733e 0a20 2020 203c  <licenses>.    <\n+000005b0: 6c69 6365 6e73 653e 0a20 2020 2020 203c  license>.      <\n+000005c0: 6e61 6d65 3e41 7061 6368 6520 4c69 6365  name>Apache Lice\n+000005d0: 6e73 652c 2056 6572 7369 6f6e 2032 2e30  nse, Version 2.0\n+000005e0: 3c2f 6e61 6d65 3e0a 2020 2020 2020 3c75  </name>.      <u\n+000005f0: 726c 3e68 7474 703a 2f2f 7777 772e 6170  rl>http://www.ap\n+00000600: 6163 6865 2e6f 7267 2f6c 6963 656e 7365  ache.org/license\n+00000610: 732f 4c49 4345 4e53 452d 322e 303c 2f75  s/LICENSE-2.0</u\n+00000620: 726c 3e0a 2020 2020 2020 3c64 6973 7472  rl>.      <distr\n+00000630: 6962 7574 696f 6e3e 7265 706f 3c2f 6469  ibution>repo</di\n+00000640: 7374 7269 6275 7469 6f6e 3e0a 2020 2020  stribution>.    \n+00000650: 3c2f 6c69 6365 6e73 653e 0a20 203c 2f6c  </license>.  </l\n+00000660: 6963 656e 7365 733e 0a20 203c 7072 6f70  icenses>.  <prop\n+00000670: 6572 7469 6573 3e0a 2020 2020 3c73 6b69  erties>.    <ski\n+00000680: 705f 6d61 7665 6e5f 6465 706c 6f79 3e66  p_maven_deploy>f\n+00000690: 616c 7365 3c2f 736b 6970 5f6d 6176 656e  alse</skip_maven\n+000006a0: 5f64 6570 6c6f 793e 0a20 2020 203c 7072  _deploy>.    <pr\n+000006b0: 6f6a 6563 742e 6275 696c 642e 736f 7572  oject.build.sour\n+000006c0: 6365 456e 636f 6469 6e67 3e55 5446 2d38  ceEncoding>UTF-8\n+000006d0: 3c2f 7072 6f6a 6563 742e 6275 696c 642e  </project.build.\n+000006e0: 736f 7572 6365 456e 636f 6469 6e67 3e0a  sourceEncoding>.\n+000006f0: 2020 3c2f 7072 6f70 6572 7469 6573 3e0a    </properties>.\n+00000700: 2020 3c64 6570 656e 6465 6e63 6965 733e    <dependencies>\n+00000710: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n+00000720: 3e0a 2020 2020 2020 3c67 726f 7570 4964  >.      <groupId\n+00000730: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n+00000740: 6f3c 2f67 726f 7570 4964 3e0a 2020 2020  o</groupId>.    \n+00000750: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n+00000760: 6262 6f2d 7265 6d6f 7469 6e67 2d61 7069  bbo-remoting-api\n+00000770: 3c2f 6172 7469 6661 6374 4964 3e0a 2020  </artifactId>.  \n+00000780: 2020 2020 3c76 6572 7369 6f6e 3e24 7b70      <version>${p\n+00000790: 726f 6a65 6374 2e70 6172 656e 742e 7665  roject.parent.ve\n+000007a0: 7273 696f 6e7d 3c2f 7665 7273 696f 6e3e  rsion}</version>\n+000007b0: 0a20 2020 203c 2f64 6570 656e 6465 6e63  .    </dependenc\n+000007c0: 793e 0a20 2020 203c 6465 7065 6e64 656e  y>.    <dependen\n+000007d0: 6379 3e0a 2020 2020 2020 3c67 726f 7570  cy>.      <group\n+000007e0: 4964 3e69 6f2e 6e65 7474 793c 2f67 726f  Id>io.netty</gro\n+000007f0: 7570 4964 3e0a 2020 2020 2020 3c61 7274  upId>.      <art\n+00000800: 6966 6163 7449 643e 6e65 7474 792d 616c  ifactId>netty-al\n+00000810: 6c3c 2f61 7274 6966 6163 7449 643e 0a20  l</artifactId>. \n+00000820: 2020 203c 2f64 6570 656e 6465 6e63 793e     </dependency>\n+00000830: 0a20 2020 203c 6465 7065 6e64 656e 6379  .    <dependency\n+00000840: 3e0a 2020 2020 2020 3c67 726f 7570 4964  >.      <groupId\n+00000850: 3e6f 7267 2e61 7061 6368 652e 6475 6262  >org.apache.dubb\n+00000860: 6f3c 2f67 726f 7570 4964 3e0a 2020 2020  o</groupId>.    \n+00000870: 2020 3c61 7274 6966 6163 7449 643e 6475    <artifactId>du\n+00000880: 6262 6f2d 7365 7269 616c 697a 6174 696f  bbo-serializatio\n+00000890: 6e2d 6865 7373 6961 6e32 3c2f 6172 7469  n-hessian2</arti\n+000008a0: 6661 6374 4964 3e0a 2020 2020 2020 3c76  factId>.      <v\n+000008b0: 6572 7369 6f6e 3e24 7b70 726f 6a65 6374  ersion>${project\n+000008c0: 2e70 6172 656e 742e 7665 7273 696f 6e7d  .parent.version}\n+000008d0: 3c2f 7665 7273 696f 6e3e 0a20 2020 2020  </version>.     \n+000008e0: 203c 7363 6f70 653e 7465 7374 3c2f 7363   <scope>test</sc\n+000008f0: 6f70 653e 0a20 2020 203c 2f64 6570 656e  ope>.    </depen\n+00000900: 6465 6e63 793e 0a20 203c 2f64 6570 656e  dency>.  </depen\n+00000910: 6465 6e63 6965 733e 0a3c 2f70 726f 6a65  dencies>.</proje\n+00000920: 6374 3e0a                                ct>.\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyChannel.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyChannel.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,276 +1,276 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.transport.AbstractChannel;\n-import org.apache.dubbo.remoting.utils.PayloadDropper;\n-\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelFuture;\n-\n-import java.net.InetSocketAddress;\n-import java.util.Map;\n-import java.util.concurrent.ConcurrentHashMap;\n-import java.util.concurrent.ConcurrentMap;\n-import java.util.concurrent.atomic.AtomicBoolean;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\n-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\n-\n-/**\n- * NettyChannel maintains the cache of channel.\n- */\n-final class NettyChannel extends AbstractChannel {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class);\n-    /**\n-     * the cache for netty channel and dubbo channel\n-     */\n-    private static final ConcurrentMap<Channel, NettyChannel> CHANNEL_MAP = new ConcurrentHashMap<Channel, NettyChannel>();\n-    /**\n-     * netty channel\n-     */\n-    private final Channel channel;\n-\n-    private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();\n-\n-    private final AtomicBoolean active = new AtomicBoolean(false);\n-\n-    /**\n-     * The constructor of NettyChannel.\n-     * It is private so NettyChannel usually create by {@link NettyChannel#getOrAddChannel(Channel, URL, ChannelHandler)}\n-     *\n-     * @param channel netty channel\n-     * @param url\n-     * @param handler dubbo handler that contain netty handler\n-     */\n-    private NettyChannel(Channel channel, URL url, ChannelHandler handler) {\n-        super(url, handler);\n-        if (channel == null) {\n-            throw new IllegalArgumentException(\"netty channel == null;\");\n-        }\n-        this.channel = channel;\n-    }\n-\n-    /**\n-     * Get dubbo channel by netty channel through channel cache.\n-     * Put netty channel into it if dubbo channel don't exist in the cache.\n-     *\n-     * @param ch      netty channel\n-     * @param url\n-     * @param handler dubbo handler that contain netty's handler\n-     * @return\n-     */\n-    static NettyChannel getOrAddChannel(Channel ch, URL url, ChannelHandler handler) {\n-        if (ch == null) {\n-            return null;\n-        }\n-        NettyChannel ret = CHANNEL_MAP.get(ch);\n-        if (ret == null) {\n-            NettyChannel nettyChannel = new NettyChannel(ch, url, handler);\n-            if (ch.isActive()) {\n-                nettyChannel.markActive(true);\n-                ret = CHANNEL_MAP.putIfAbsent(ch, nettyChannel);\n-            }\n-            if (ret == null) {\n-                ret = nettyChannel;\n-            }\n-        }\n-        return ret;\n-    }\n-\n-    /**\n-     * Remove the inactive channel.\n-     *\n-     * @param ch netty channel\n-     */\n-    static void removeChannelIfDisconnected(Channel ch) {\n-        if (ch != null && !ch.isActive()) {\n-            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\n-            if (nettyChannel != null) {\n-                nettyChannel.markActive(false);\n-            }\n-        }\n-    }\n-\n-    static void removeChannel(Channel ch) {\n-        if (ch != null) {\n-            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\n-            if (nettyChannel != null) {\n-                nettyChannel.markActive(false);\n-            }\n-        }\n-    }\n-\n-    @Override\n-    public InetSocketAddress getLocalAddress() {\n-        return (InetSocketAddress) channel.localAddress();\n-    }\n-\n-    @Override\n-    public InetSocketAddress getRemoteAddress() {\n-        return (InetSocketAddress) channel.remoteAddress();\n-    }\n-\n-    @Override\n-    public boolean isConnected() {\n-        return !isClosed() && active.get();\n-    }\n-\n-    public boolean isActive() {\n-        return active.get();\n-    }\n-\n-    public void markActive(boolean isActive) {\n-        active.set(isActive);\n-    }\n-\n-    /**\n-     * Send message by netty and whether to wait the completion of the send.\n-     *\n-     * @param message message that need send.\n-     * @param sent    whether to ack async-sent\n-     * @throws RemotingException throw RemotingException if wait until timeout or any exception thrown by method body that surrounded by try-catch.\n-     */\n-    @Override\n-    public void send(Object message, boolean sent) throws RemotingException {\n-        // whether the channel is closed\n-        super.send(message, sent);\n-\n-        boolean success = true;\n-        int timeout = 0;\n-        try {\n-            ChannelFuture future = channel.writeAndFlush(message);\n-            if (sent) {\n-                // wait timeout ms\n-                timeout = getUrl().getPositiveParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);\n-                success = future.await(timeout);\n-            }\n-            Throwable cause = future.cause();\n-            if (cause != null) {\n-                throw cause;\n-            }\n-        } catch (Throwable e) {\n-            removeChannelIfDisconnected(channel);\n-            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress() + \", cause: \" + e.getMessage(), e);\n-        }\n-        if (!success) {\n-            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress()\n-                    + \"in timeout(\" + timeout + \"ms) limit\");\n-        }\n-    }\n-\n-    @Override\n-    public void close() {\n-        try {\n-            super.close();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            removeChannelIfDisconnected(channel);\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            attributes.clear();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (logger.isInfoEnabled()) {\n-                logger.info(\"Close netty channel \" + channel);\n-            }\n-            channel.close();\n-        } catch (Exception e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public boolean hasAttribute(String key) {\n-        return attributes.containsKey(key);\n-    }\n-\n-    @Override\n-    public Object getAttribute(String key) {\n-        return attributes.get(key);\n-    }\n-\n-    @Override\n-    public void setAttribute(String key, Object value) {\n-        // The null value is unallowed in the ConcurrentHashMap.\n-        if (value == null) {\n-            attributes.remove(key);\n-        } else {\n-            attributes.put(key, value);\n-        }\n-    }\n-\n-    @Override\n-    public void removeAttribute(String key) {\n-        attributes.remove(key);\n-    }\n-\n-    @Override\n-    public int hashCode() {\n-        final int prime = 31;\n-        int result = 1;\n-        result = prime * result + ((channel == null) ? 0 : channel.hashCode());\n-        return result;\n-    }\n-\n-    @Override\n-    public boolean equals(Object obj) {\n-        if (this == obj) {\n-            return true;\n-        }\n-        if (obj == null) {\n-            return false;\n-        }\n-\n-        // FIXME: a hack to make org.apache.dubbo.remoting.exchange.support.DefaultFuture.closeChannel work\n-        if (obj instanceof NettyClient) {\n-            NettyClient client = (NettyClient) obj;\n-            return channel.equals(client.getNettyChannel());\n-        }\n-\n-        if (getClass() != obj.getClass()) {\n-            return false;\n-        }\n-        NettyChannel other = (NettyChannel) obj;\n-        if (channel == null) {\n-            if (other.channel != null) {\n-                return false;\n-            }\n-        } else if (!channel.equals(other.channel)) {\n-            return false;\n-        }\n-        return true;\n-    }\n-\n-    @Override\n-    public String toString() {\n-        return \"NettyChannel [channel=\" + channel + \"]\";\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.transport.AbstractChannel;\r\n+import org.apache.dubbo.remoting.utils.PayloadDropper;\r\n+\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelFuture;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.Map;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+import java.util.concurrent.ConcurrentMap;\r\n+import java.util.concurrent.atomic.AtomicBoolean;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;\r\n+\r\n+/**\r\n+ * NettyChannel maintains the cache of channel.\r\n+ */\r\n+final class NettyChannel extends AbstractChannel {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyChannel.class);\r\n+    /**\r\n+     * the cache for netty channel and dubbo channel\r\n+     */\r\n+    private static final ConcurrentMap<Channel, NettyChannel> CHANNEL_MAP = new ConcurrentHashMap<Channel, NettyChannel>();\r\n+    /**\r\n+     * netty channel\r\n+     */\r\n+    private final Channel channel;\r\n+\r\n+    private final Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();\r\n+\r\n+    private final AtomicBoolean active = new AtomicBoolean(false);\r\n+\r\n+    /**\r\n+     * The constructor of NettyChannel.\r\n+     * It is private so NettyChannel usually create by {@link NettyChannel#getOrAddChannel(Channel, URL, ChannelHandler)}\r\n+     *\r\n+     * @param channel netty channel\r\n+     * @param url\r\n+     * @param handler dubbo handler that contain netty handler\r\n+     */\r\n+    private NettyChannel(Channel channel, URL url, ChannelHandler handler) {\r\n+        super(url, handler);\r\n+        if (channel == null) {\r\n+            throw new IllegalArgumentException(\"netty channel == null;\");\r\n+        }\r\n+        this.channel = channel;\r\n+    }\r\n+\r\n+    /**\r\n+     * Get dubbo channel by netty channel through channel cache.\r\n+     * Put netty channel into it if dubbo channel don't exist in the cache.\r\n+     *\r\n+     * @param ch      netty channel\r\n+     * @param url\r\n+     * @param handler dubbo handler that contain netty's handler\r\n+     * @return\r\n+     */\r\n+    static NettyChannel getOrAddChannel(Channel ch, URL url, ChannelHandler handler) {\r\n+        if (ch == null) {\r\n+            return null;\r\n+        }\r\n+        NettyChannel ret = CHANNEL_MAP.get(ch);\r\n+        if (ret == null) {\r\n+            NettyChannel nettyChannel = new NettyChannel(ch, url, handler);\r\n+            if (ch.isActive()) {\r\n+                nettyChannel.markActive(true);\r\n+                ret = CHANNEL_MAP.putIfAbsent(ch, nettyChannel);\r\n+            }\r\n+            if (ret == null) {\r\n+                ret = nettyChannel;\r\n+            }\r\n+        }\r\n+        return ret;\r\n+    }\r\n+\r\n+    /**\r\n+     * Remove the inactive channel.\r\n+     *\r\n+     * @param ch netty channel\r\n+     */\r\n+    static void removeChannelIfDisconnected(Channel ch) {\r\n+        if (ch != null && !ch.isActive()) {\r\n+            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\r\n+            if (nettyChannel != null) {\r\n+                nettyChannel.markActive(false);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    static void removeChannel(Channel ch) {\r\n+        if (ch != null) {\r\n+            NettyChannel nettyChannel = CHANNEL_MAP.remove(ch);\r\n+            if (nettyChannel != null) {\r\n+                nettyChannel.markActive(false);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getLocalAddress() {\r\n+        return (InetSocketAddress) channel.localAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public InetSocketAddress getRemoteAddress() {\r\n+        return (InetSocketAddress) channel.remoteAddress();\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isConnected() {\r\n+        return !isClosed() && active.get();\r\n+    }\r\n+\r\n+    public boolean isActive() {\r\n+        return active.get();\r\n+    }\r\n+\r\n+    public void markActive(boolean isActive) {\r\n+        active.set(isActive);\r\n+    }\r\n+\r\n+    /**\r\n+     * Send message by netty and whether to wait the completion of the send.\r\n+     *\r\n+     * @param message message that need send.\r\n+     * @param sent    whether to ack async-sent\r\n+     * @throws RemotingException throw RemotingException if wait until timeout or any exception thrown by method body that surrounded by try-catch.\r\n+     */\r\n+    @Override\r\n+    public void send(Object message, boolean sent) throws RemotingException {\r\n+        // whether the channel is closed\r\n+        super.send(message, sent);\r\n+\r\n+        boolean success = true;\r\n+        int timeout = 0;\r\n+        try {\r\n+            ChannelFuture future = channel.writeAndFlush(message);\r\n+            if (sent) {\r\n+                // wait timeout ms\r\n+                timeout = getUrl().getPositiveParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT);\r\n+                success = future.await(timeout);\r\n+            }\r\n+            Throwable cause = future.cause();\r\n+            if (cause != null) {\r\n+                throw cause;\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            removeChannelIfDisconnected(channel);\r\n+            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress() + \", cause: \" + e.getMessage(), e);\r\n+        }\r\n+        if (!success) {\r\n+            throw new RemotingException(this, \"Failed to send message \" + PayloadDropper.getRequestWithoutData(message) + \" to \" + getRemoteAddress()\r\n+                    + \"in timeout(\" + timeout + \"ms) limit\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void close() {\r\n+        try {\r\n+            super.close();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            removeChannelIfDisconnected(channel);\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            attributes.clear();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (logger.isInfoEnabled()) {\r\n+                logger.info(\"Close netty channel \" + channel);\r\n+            }\r\n+            channel.close();\r\n+        } catch (Exception e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean hasAttribute(String key) {\r\n+        return attributes.containsKey(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public Object getAttribute(String key) {\r\n+        return attributes.get(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void setAttribute(String key, Object value) {\r\n+        // The null value is unallowed in the ConcurrentHashMap.\r\n+        if (value == null) {\r\n+            attributes.remove(key);\r\n+        } else {\r\n+            attributes.put(key, value);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void removeAttribute(String key) {\r\n+        attributes.remove(key);\r\n+    }\r\n+\r\n+    @Override\r\n+    public int hashCode() {\r\n+        final int prime = 31;\r\n+        int result = 1;\r\n+        result = prime * result + ((channel == null) ? 0 : channel.hashCode());\r\n+        return result;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean equals(Object obj) {\r\n+        if (this == obj) {\r\n+            return true;\r\n+        }\r\n+        if (obj == null) {\r\n+            return false;\r\n+        }\r\n+\r\n+        // FIXME: a hack to make org.apache.dubbo.remoting.exchange.support.DefaultFuture.closeChannel work\r\n+        if (obj instanceof NettyClient) {\r\n+            NettyClient client = (NettyClient) obj;\r\n+            return channel.equals(client.getNettyChannel());\r\n+        }\r\n+\r\n+        if (getClass() != obj.getClass()) {\r\n+            return false;\r\n+        }\r\n+        NettyChannel other = (NettyChannel) obj;\r\n+        if (channel == null) {\r\n+            if (other.channel != null) {\r\n+                return false;\r\n+            }\r\n+        } else if (!channel.equals(other.channel)) {\r\n+            return false;\r\n+        }\r\n+        return true;\r\n+    }\r\n+\r\n+    @Override\r\n+    public String toString() {\r\n+        return \"NettyChannel [channel=\" + channel + \"]\";\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyClient.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyClient.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,217 +1,217 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.Version;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ConfigUtils;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.transport.AbstractClient;\n-import org.apache.dubbo.remoting.utils.UrlUtils;\n-\n-import io.netty.bootstrap.Bootstrap;\n-import io.netty.buffer.PooledByteBufAllocator;\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelFuture;\n-import io.netty.channel.ChannelInitializer;\n-import io.netty.channel.ChannelOption;\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.handler.proxy.Socks5ProxyHandler;\n-import io.netty.handler.timeout.IdleStateHandler;\n-\n-import java.net.InetSocketAddress;\n-\n-import static java.util.concurrent.TimeUnit.MILLISECONDS;\n-import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\n-import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.eventLoopGroup;\n-import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.socketChannelClass;\n-\n-/**\n- * NettyClient.\n- */\n-public class NettyClient extends AbstractClient {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);\n-    /**\n-     * netty client bootstrap\n-     */\n-    private static final EventLoopGroup NIO_EVENT_LOOP_GROUP = eventLoopGroup(Constants.DEFAULT_IO_THREADS, \"NettyClientWorker\");\n-\n-    private static final String SOCKS_PROXY_HOST = \"socksProxyHost\";\n-\n-    private static final String SOCKS_PROXY_PORT = \"socksProxyPort\";\n-\n-    private static final String DEFAULT_SOCKS_PROXY_PORT = \"1080\";\n-\n-    private Bootstrap bootstrap;\n-\n-    /**\n-     * current channel. Each successful invocation of {@link NettyClient#doConnect()} will\n-     * replace this with new channel and close old channel.\n-     * <b>volatile, please copy reference to use.</b>\n-     */\n-    private volatile Channel channel;\n-\n-    /**\n-     * The constructor of NettyClient.\n-     * It wil init and start netty.\n-     */\n-    public NettyClient(final URL url, final ChannelHandler handler) throws RemotingException {\n-    \t// you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\n-    \t// the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\n-    \tsuper(url, wrapChannelHandler(url, handler));\n-    }\n-\n-    /**\n-     * Init bootstrap\n-     *\n-     * @throws Throwable\n-     */\n-    @Override\n-    protected void doOpen() throws Throwable {\n-        final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);\n-        bootstrap = new Bootstrap();\n-        bootstrap.group(NIO_EVENT_LOOP_GROUP)\n-                .option(ChannelOption.SO_KEEPALIVE, true)\n-                .option(ChannelOption.TCP_NODELAY, true)\n-                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\n-                //.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getTimeout())\n-                .channel(socketChannelClass());\n-\n-        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.max(3000, getConnectTimeout()));\n-        bootstrap.handler(new ChannelInitializer<SocketChannel>() {\n-\n-            @Override\n-            protected void initChannel(SocketChannel ch) throws Exception {\n-                int heartbeatInterval = UrlUtils.getHeartbeat(getUrl());\n-\n-                if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\n-                    ch.pipeline().addLast(\"negotiation\", SslHandlerInitializer.sslClientHandler(getUrl(), nettyClientHandler));\n-                }\n-\n-                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);\n-                ch.pipeline()//.addLast(\"logging\",new LoggingHandler(LogLevel.INFO))//for debug\n-                        .addLast(\"decoder\", adapter.getDecoder())\n-                        .addLast(\"encoder\", adapter.getEncoder())\n-                        .addLast(\"client-idle-handler\", new IdleStateHandler(heartbeatInterval, 0, 0, MILLISECONDS))\n-                        .addLast(\"handler\", nettyClientHandler);\n-\n-                String socksProxyHost = ConfigUtils.getProperty(SOCKS_PROXY_HOST);\n-                if(socksProxyHost != null) {\n-                    int socksProxyPort = Integer.parseInt(ConfigUtils.getProperty(SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT));\n-                    Socks5ProxyHandler socks5ProxyHandler = new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort));\n-                    ch.pipeline().addFirst(socks5ProxyHandler);\n-                }\n-            }\n-        });\n-    }\n-\n-    @Override\n-    protected void doConnect() throws Throwable {\n-        long start = System.currentTimeMillis();\n-        ChannelFuture future = bootstrap.connect(getConnectAddress());\n-        try {\n-            boolean ret = future.awaitUninterruptibly(getConnectTimeout(), MILLISECONDS);\n-\n-            if (ret && future.isSuccess()) {\n-                Channel newChannel = future.channel();\n-                try {\n-                    // Close old channel\n-                    // copy reference\n-                    Channel oldChannel = NettyClient.this.channel;\n-                    if (oldChannel != null) {\n-                        try {\n-                            if (logger.isInfoEnabled()) {\n-                                logger.info(\"Close old netty channel \" + oldChannel + \" on create new netty channel \" + newChannel);\n-                            }\n-                            oldChannel.close();\n-                        } finally {\n-                            NettyChannel.removeChannelIfDisconnected(oldChannel);\n-                        }\n-                    }\n-                } finally {\n-                    if (NettyClient.this.isClosed()) {\n-                        try {\n-                            if (logger.isInfoEnabled()) {\n-                                logger.info(\"Close new netty channel \" + newChannel + \", because the client closed.\");\n-                            }\n-                            newChannel.close();\n-                        } finally {\n-                            NettyClient.this.channel = null;\n-                            NettyChannel.removeChannelIfDisconnected(newChannel);\n-                        }\n-                    } else {\n-                        NettyClient.this.channel = newChannel;\n-                    }\n-                }\n-            } else if (future.cause() != null) {\n-                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\n-                        + getRemoteAddress() + \", error message is:\" + future.cause().getMessage(), future.cause());\n-            } else {\n-                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\n-                        + getRemoteAddress() + \" client-side timeout \"\n-                        + getConnectTimeout() + \"ms (elapsed: \" + (System.currentTimeMillis() - start) + \"ms) from netty client \"\n-                        + NetUtils.getLocalHost() + \" using dubbo version \" + Version.getVersion());\n-            }\n-        } finally {\n-            // just add new valid channel to NettyChannel's cache\n-            if (!isConnected()) {\n-                //future.cancel(true);\n-            }\n-        }\n-    }\n-\n-    @Override\n-    protected void doDisConnect() throws Throwable {\n-        try {\n-            NettyChannel.removeChannelIfDisconnected(channel);\n-        } catch (Throwable t) {\n-            logger.warn(t.getMessage());\n-        }\n-    }\n-\n-    @Override\n-    protected void doClose() throws Throwable {\n-        // can't shutdown nioEventLoopGroup because the method will be invoked when closing one channel but not a client,\n-        // but when and how to close the nioEventLoopGroup ?\n-        // nioEventLoopGroup.shutdownGracefully();\n-    }\n-\n-    @Override\n-    protected org.apache.dubbo.remoting.Channel getChannel() {\n-        Channel c = channel;\n-        if (c == null) {\n-            return null;\n-        }\n-        return NettyChannel.getOrAddChannel(c, getUrl(), this);\n-    }\n-\n-    Channel getNettyChannel() {\n-        return channel;\n-    }\n-\n-    @Override\n-    public boolean canHandleIdle() {\n-        return true;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.Version;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ConfigUtils;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.transport.AbstractClient;\r\n+import org.apache.dubbo.remoting.utils.UrlUtils;\r\n+\r\n+import io.netty.bootstrap.Bootstrap;\r\n+import io.netty.buffer.PooledByteBufAllocator;\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelFuture;\r\n+import io.netty.channel.ChannelInitializer;\r\n+import io.netty.channel.ChannelOption;\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.handler.proxy.Socks5ProxyHandler;\r\n+import io.netty.handler.timeout.IdleStateHandler;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+\r\n+import static java.util.concurrent.TimeUnit.MILLISECONDS;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\r\n+import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.eventLoopGroup;\r\n+import static org.apache.dubbo.remoting.transport.netty4.NettyEventLoopFactory.socketChannelClass;\r\n+\r\n+/**\r\n+ * NettyClient.\r\n+ */\r\n+public class NettyClient extends AbstractClient {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyClient.class);\r\n+    /**\r\n+     * netty client bootstrap\r\n+     */\r\n+    private static final EventLoopGroup NIO_EVENT_LOOP_GROUP = eventLoopGroup(Constants.DEFAULT_IO_THREADS, \"NettyClientWorker\");\r\n+\r\n+    private static final String SOCKS_PROXY_HOST = \"socksProxyHost\";\r\n+\r\n+    private static final String SOCKS_PROXY_PORT = \"socksProxyPort\";\r\n+\r\n+    private static final String DEFAULT_SOCKS_PROXY_PORT = \"1080\";\r\n+\r\n+    private Bootstrap bootstrap;\r\n+\r\n+    /**\r\n+     * current channel. Each successful invocation of {@link NettyClient#doConnect()} will\r\n+     * replace this with new channel and close old channel.\r\n+     * <b>volatile, please copy reference to use.</b>\r\n+     */\r\n+    private volatile Channel channel;\r\n+\r\n+    /**\r\n+     * The constructor of NettyClient.\r\n+     * It wil init and start netty.\r\n+     */\r\n+    public NettyClient(final URL url, final ChannelHandler handler) throws RemotingException {\r\n+    \t// you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\r\n+    \t// the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\r\n+    \tsuper(url, wrapChannelHandler(url, handler));\r\n+    }\r\n+\r\n+    /**\r\n+     * Init bootstrap\r\n+     *\r\n+     * @throws Throwable\r\n+     */\r\n+    @Override\r\n+    protected void doOpen() throws Throwable {\r\n+        final NettyClientHandler nettyClientHandler = new NettyClientHandler(getUrl(), this);\r\n+        bootstrap = new Bootstrap();\r\n+        bootstrap.group(NIO_EVENT_LOOP_GROUP)\r\n+                .option(ChannelOption.SO_KEEPALIVE, true)\r\n+                .option(ChannelOption.TCP_NODELAY, true)\r\n+                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\r\n+                //.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, getTimeout())\r\n+                .channel(socketChannelClass());\r\n+\r\n+        bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, Math.max(3000, getConnectTimeout()));\r\n+        bootstrap.handler(new ChannelInitializer<SocketChannel>() {\r\n+\r\n+            @Override\r\n+            protected void initChannel(SocketChannel ch) throws Exception {\r\n+                int heartbeatInterval = UrlUtils.getHeartbeat(getUrl());\r\n+\r\n+                if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\r\n+                    ch.pipeline().addLast(\"negotiation\", SslHandlerInitializer.sslClientHandler(getUrl(), nettyClientHandler));\r\n+                }\r\n+\r\n+                NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);\r\n+                ch.pipeline()//.addLast(\"logging\",new LoggingHandler(LogLevel.INFO))//for debug\r\n+                        .addLast(\"decoder\", adapter.getDecoder())\r\n+                        .addLast(\"encoder\", adapter.getEncoder())\r\n+                        .addLast(\"client-idle-handler\", new IdleStateHandler(heartbeatInterval, 0, 0, MILLISECONDS))\r\n+                        .addLast(\"handler\", nettyClientHandler);\r\n+\r\n+                String socksProxyHost = ConfigUtils.getProperty(SOCKS_PROXY_HOST);\r\n+                if(socksProxyHost != null) {\r\n+                    int socksProxyPort = Integer.parseInt(ConfigUtils.getProperty(SOCKS_PROXY_PORT, DEFAULT_SOCKS_PROXY_PORT));\r\n+                    Socks5ProxyHandler socks5ProxyHandler = new Socks5ProxyHandler(new InetSocketAddress(socksProxyHost, socksProxyPort));\r\n+                    ch.pipeline().addFirst(socks5ProxyHandler);\r\n+                }\r\n+            }\r\n+        });\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doConnect() throws Throwable {\r\n+        long start = System.currentTimeMillis();\r\n+        ChannelFuture future = bootstrap.connect(getConnectAddress());\r\n+        try {\r\n+            boolean ret = future.awaitUninterruptibly(getConnectTimeout(), MILLISECONDS);\r\n+\r\n+            if (ret && future.isSuccess()) {\r\n+                Channel newChannel = future.channel();\r\n+                try {\r\n+                    // Close old channel\r\n+                    // copy reference\r\n+                    Channel oldChannel = NettyClient.this.channel;\r\n+                    if (oldChannel != null) {\r\n+                        try {\r\n+                            if (logger.isInfoEnabled()) {\r\n+                                logger.info(\"Close old netty channel \" + oldChannel + \" on create new netty channel \" + newChannel);\r\n+                            }\r\n+                            oldChannel.close();\r\n+                        } finally {\r\n+                            NettyChannel.removeChannelIfDisconnected(oldChannel);\r\n+                        }\r\n+                    }\r\n+                } finally {\r\n+                    if (NettyClient.this.isClosed()) {\r\n+                        try {\r\n+                            if (logger.isInfoEnabled()) {\r\n+                                logger.info(\"Close new netty channel \" + newChannel + \", because the client closed.\");\r\n+                            }\r\n+                            newChannel.close();\r\n+                        } finally {\r\n+                            NettyClient.this.channel = null;\r\n+                            NettyChannel.removeChannelIfDisconnected(newChannel);\r\n+                        }\r\n+                    } else {\r\n+                        NettyClient.this.channel = newChannel;\r\n+                    }\r\n+                }\r\n+            } else if (future.cause() != null) {\r\n+                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\r\n+                        + getRemoteAddress() + \", error message is:\" + future.cause().getMessage(), future.cause());\r\n+            } else {\r\n+                throw new RemotingException(this, \"client(url: \" + getUrl() + \") failed to connect to server \"\r\n+                        + getRemoteAddress() + \" client-side timeout \"\r\n+                        + getConnectTimeout() + \"ms (elapsed: \" + (System.currentTimeMillis() - start) + \"ms) from netty client \"\r\n+                        + NetUtils.getLocalHost() + \" using dubbo version \" + Version.getVersion());\r\n+            }\r\n+        } finally {\r\n+            // just add new valid channel to NettyChannel's cache\r\n+            if (!isConnected()) {\r\n+                //future.cancel(true);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doDisConnect() throws Throwable {\r\n+        try {\r\n+            NettyChannel.removeChannelIfDisconnected(channel);\r\n+        } catch (Throwable t) {\r\n+            logger.warn(t.getMessage());\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doClose() throws Throwable {\r\n+        // can't shutdown nioEventLoopGroup because the method will be invoked when closing one channel but not a client,\r\n+        // but when and how to close the nioEventLoopGroup ?\r\n+        // nioEventLoopGroup.shutdownGracefully();\r\n+    }\r\n+\r\n+    @Override\r\n+    protected org.apache.dubbo.remoting.Channel getChannel() {\r\n+        Channel c = channel;\r\n+        if (c == null) {\r\n+            return null;\r\n+        }\r\n+        return NettyChannel.getOrAddChannel(c, getUrl(), this);\r\n+    }\r\n+\r\n+    Channel getNettyChannel() {\r\n+        return channel;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean canHandleIdle() {\r\n+        return true;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,161 +1,161 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.Version;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.StringUtils;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.exchange.Request;\n-import org.apache.dubbo.remoting.exchange.Response;\n-\n-import io.netty.channel.ChannelDuplexHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelPromise;\n-import io.netty.handler.timeout.IdleStateEvent;\n-\n-import static org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;\n-\n-/**\n- * NettyClientHandler\n- */\n-@io.netty.channel.ChannelHandler.Sharable\n-public class NettyClientHandler extends ChannelDuplexHandler {\n-    private static final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);\n-\n-    private final URL url;\n-\n-    private final ChannelHandler handler;\n-\n-    public NettyClientHandler(URL url, ChannelHandler handler) {\n-        if (url == null) {\n-            throw new IllegalArgumentException(\"url == null\");\n-        }\n-        if (handler == null) {\n-            throw new IllegalArgumentException(\"handler == null\");\n-        }\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    @Override\n-    public void channelActive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.connected(channel);\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is established.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.disconnected(channel);\n-        } finally {\n-            NettyChannel.removeChannel(ctx.channel());\n-        }\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is disconnected.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.received(channel, msg);\n-    }\n-\n-    @Override\n-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\n-        super.write(ctx, msg, promise);\n-        final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        final boolean isRequest = msg instanceof Request;\n-\n-        // We add listeners to make sure our out bound event is correct.\n-        // If our out bound event has an error (in most cases the encoder fails),\n-        // we need to have the request return directly instead of blocking the invoke process.\n-        promise.addListener(future -> {\n-            if (future.isSuccess()) {\n-                // if our future is success, mark the future to sent.\n-                handler.sent(channel, msg);\n-                return;\n-            }\n-\n-            Throwable t = future.cause();\n-            if (t != null && isRequest) {\n-                Request request = (Request) msg;\n-                Response response = buildErrorResponse(request, t);\n-                handler.received(channel, response);\n-            }\n-        });\n-    }\n-\n-    @Override\n-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-        // send heartbeat when read idle.\n-        if (evt instanceof IdleStateEvent) {\n-            try {\n-                NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-                if (logger.isDebugEnabled()) {\n-                    logger.debug(\"IdleStateEvent triggered, send heartbeat to channel \" + channel);\n-                }\n-                Request req = new Request();\n-                req.setVersion(Version.getProtocolVersion());\n-                req.setTwoWay(true);\n-                req.setEvent(HEARTBEAT_EVENT);\n-                channel.send(req);\n-            } finally {\n-                NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-            }\n-        } else {\n-            super.userEventTriggered(ctx, evt);\n-        }\n-    }\n-\n-    @Override\n-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\n-            throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.caught(channel, cause);\n-        } finally {\n-            NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-        }\n-    }\n-\n-    public void handshakeCompleted(SslHandlerInitializer.HandshakeCompletionEvent evt) {\n-        // TODO\n-    }\n-\n-    /**\n-     * build a bad request's response\n-     *\n-     * @param request the request\n-     * @param t       the throwable. In most cases, serialization fails.\n-     * @return the response\n-     */\n-    private static Response buildErrorResponse(Request request, Throwable t) {\n-        Response response = new Response(request.getId(), request.getVersion());\n-        response.setStatus(Response.BAD_REQUEST);\n-        response.setErrorMessage(StringUtils.toString(t));\n-        return response;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.Version;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.StringUtils;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.exchange.Request;\r\n+import org.apache.dubbo.remoting.exchange.Response;\r\n+\r\n+import io.netty.channel.ChannelDuplexHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelPromise;\r\n+import io.netty.handler.timeout.IdleStateEvent;\r\n+\r\n+import static org.apache.dubbo.common.constants.CommonConstants.HEARTBEAT_EVENT;\r\n+\r\n+/**\r\n+ * NettyClientHandler\r\n+ */\r\n+@io.netty.channel.ChannelHandler.Sharable\r\n+public class NettyClientHandler extends ChannelDuplexHandler {\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyClientHandler.class);\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final ChannelHandler handler;\r\n+\r\n+    public NettyClientHandler(URL url, ChannelHandler handler) {\r\n+        if (url == null) {\r\n+            throw new IllegalArgumentException(\"url == null\");\r\n+        }\r\n+        if (handler == null) {\r\n+            throw new IllegalArgumentException(\"handler == null\");\r\n+        }\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelActive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.connected(channel);\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is established.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.disconnected(channel);\r\n+        } finally {\r\n+            NettyChannel.removeChannel(ctx.channel());\r\n+        }\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getLocalAddress() + \" -> \" + channel.getRemoteAddress() + \" is disconnected.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.received(channel, msg);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\r\n+        super.write(ctx, msg, promise);\r\n+        final NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        final boolean isRequest = msg instanceof Request;\r\n+\r\n+        // We add listeners to make sure our out bound event is correct.\r\n+        // If our out bound event has an error (in most cases the encoder fails),\r\n+        // we need to have the request return directly instead of blocking the invoke process.\r\n+        promise.addListener(future -> {\r\n+            if (future.isSuccess()) {\r\n+                // if our future is success, mark the future to sent.\r\n+                handler.sent(channel, msg);\r\n+                return;\r\n+            }\r\n+\r\n+            Throwable t = future.cause();\r\n+            if (t != null && isRequest) {\r\n+                Request request = (Request) msg;\r\n+                Response response = buildErrorResponse(request, t);\r\n+                handler.received(channel, response);\r\n+            }\r\n+        });\r\n+    }\r\n+\r\n+    @Override\r\n+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+        // send heartbeat when read idle.\r\n+        if (evt instanceof IdleStateEvent) {\r\n+            try {\r\n+                NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+                if (logger.isDebugEnabled()) {\r\n+                    logger.debug(\"IdleStateEvent triggered, send heartbeat to channel \" + channel);\r\n+                }\r\n+                Request req = new Request();\r\n+                req.setVersion(Version.getProtocolVersion());\r\n+                req.setTwoWay(true);\r\n+                req.setEvent(HEARTBEAT_EVENT);\r\n+                channel.send(req);\r\n+            } finally {\r\n+                NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+            }\r\n+        } else {\r\n+            super.userEventTriggered(ctx, evt);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\r\n+            throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.caught(channel, cause);\r\n+        } finally {\r\n+            NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+        }\r\n+    }\r\n+\r\n+    public void handshakeCompleted(SslHandlerInitializer.HandshakeCompletionEvent evt) {\r\n+        // TODO\r\n+    }\r\n+\r\n+    /**\r\n+     * build a bad request's response\r\n+     *\r\n+     * @param request the request\r\n+     * @param t       the throwable. In most cases, serialization fails.\r\n+     * @return the response\r\n+     */\r\n+    private static Response buildErrorResponse(Request request, Throwable t) {\r\n+        Response response = new Response(request.getId(), request.getVersion());\r\n+        response.setStatus(Response.BAD_REQUEST);\r\n+        response.setErrorMessage(StringUtils.toString(t));\r\n+        return response;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyCodecAdapter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,101 +1,101 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.Codec2;\n-import org.apache.dubbo.remoting.buffer.ChannelBuffer;\n-\n-import io.netty.buffer.ByteBuf;\n-import io.netty.channel.Channel;\n-import io.netty.channel.ChannelHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.handler.codec.ByteToMessageDecoder;\n-import io.netty.handler.codec.MessageToByteEncoder;\n-\n-import java.io.IOException;\n-import java.util.List;\n-\n-/**\n- * NettyCodecAdapter.\n- */\n-final public class NettyCodecAdapter {\n-\n-    private final ChannelHandler encoder = new InternalEncoder();\n-\n-    private final ChannelHandler decoder = new InternalDecoder();\n-\n-    private final Codec2 codec;\n-\n-    private final URL url;\n-\n-    private final org.apache.dubbo.remoting.ChannelHandler handler;\n-\n-    public NettyCodecAdapter(Codec2 codec, URL url, org.apache.dubbo.remoting.ChannelHandler handler) {\n-        this.codec = codec;\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    public ChannelHandler getEncoder() {\n-        return encoder;\n-    }\n-\n-    public ChannelHandler getDecoder() {\n-        return decoder;\n-    }\n-\n-    private class InternalEncoder extends MessageToByteEncoder {\n-\n-        @Override\n-        protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {\n-            org.apache.dubbo.remoting.buffer.ChannelBuffer buffer = new NettyBackedChannelBuffer(out);\n-            Channel ch = ctx.channel();\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);\n-            codec.encode(channel, buffer, msg);\n-        }\n-    }\n-\n-    private class InternalDecoder extends ByteToMessageDecoder {\n-\n-        @Override\n-        protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {\n-\n-            ChannelBuffer message = new NettyBackedChannelBuffer(input);\n-\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-\n-            // decode object.\n-            do {\n-                int saveReaderIndex = message.readerIndex();\n-                Object msg = codec.decode(channel, message);\n-                if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {\n-                    message.readerIndex(saveReaderIndex);\n-                    break;\n-                } else {\n-                    //is it possible to go here ?\n-                    if (saveReaderIndex == message.readerIndex()) {\n-                        throw new IOException(\"Decode without read data.\");\n-                    }\n-                    if (msg != null) {\n-                        out.add(msg);\n-                    }\n-                }\n-            } while (message.readable());\n-        }\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.Codec2;\r\n+import org.apache.dubbo.remoting.buffer.ChannelBuffer;\r\n+\r\n+import io.netty.buffer.ByteBuf;\r\n+import io.netty.channel.Channel;\r\n+import io.netty.channel.ChannelHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.handler.codec.ByteToMessageDecoder;\r\n+import io.netty.handler.codec.MessageToByteEncoder;\r\n+\r\n+import java.io.IOException;\r\n+import java.util.List;\r\n+\r\n+/**\r\n+ * NettyCodecAdapter.\r\n+ */\r\n+final public class NettyCodecAdapter {\r\n+\r\n+    private final ChannelHandler encoder = new InternalEncoder();\r\n+\r\n+    private final ChannelHandler decoder = new InternalDecoder();\r\n+\r\n+    private final Codec2 codec;\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final org.apache.dubbo.remoting.ChannelHandler handler;\r\n+\r\n+    public NettyCodecAdapter(Codec2 codec, URL url, org.apache.dubbo.remoting.ChannelHandler handler) {\r\n+        this.codec = codec;\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    public ChannelHandler getEncoder() {\r\n+        return encoder;\r\n+    }\r\n+\r\n+    public ChannelHandler getDecoder() {\r\n+        return decoder;\r\n+    }\r\n+\r\n+    private class InternalEncoder extends MessageToByteEncoder {\r\n+\r\n+        @Override\r\n+        protected void encode(ChannelHandlerContext ctx, Object msg, ByteBuf out) throws Exception {\r\n+            org.apache.dubbo.remoting.buffer.ChannelBuffer buffer = new NettyBackedChannelBuffer(out);\r\n+            Channel ch = ctx.channel();\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);\r\n+            codec.encode(channel, buffer, msg);\r\n+        }\r\n+    }\r\n+\r\n+    private class InternalDecoder extends ByteToMessageDecoder {\r\n+\r\n+        @Override\r\n+        protected void decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out) throws Exception {\r\n+\r\n+            ChannelBuffer message = new NettyBackedChannelBuffer(input);\r\n+\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+\r\n+            // decode object.\r\n+            do {\r\n+                int saveReaderIndex = message.readerIndex();\r\n+                Object msg = codec.decode(channel, message);\r\n+                if (msg == Codec2.DecodeResult.NEED_MORE_INPUT) {\r\n+                    message.readerIndex(saveReaderIndex);\r\n+                    break;\r\n+                } else {\r\n+                    //is it possible to go here ?\r\n+                    if (saveReaderIndex == message.readerIndex()) {\r\n+                        throw new IOException(\"Decode without read data.\");\r\n+                    }\r\n+                    if (msg != null) {\r\n+                        out.add(msg);\r\n+                    }\r\n+                }\r\n+            } while (message.readable());\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyEventLoopFactory.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,60 +1,60 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.config.Configuration;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.epoll.Epoll;\n-import io.netty.channel.epoll.EpollEventLoopGroup;\n-import io.netty.channel.epoll.EpollServerSocketChannel;\n-import io.netty.channel.epoll.EpollSocketChannel;\n-import io.netty.channel.nio.NioEventLoopGroup;\n-import io.netty.channel.socket.ServerSocketChannel;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.channel.socket.nio.NioServerSocketChannel;\n-import io.netty.channel.socket.nio.NioSocketChannel;\n-import io.netty.util.concurrent.DefaultThreadFactory;\n-\n-import java.util.concurrent.ThreadFactory;\n-\n-public class NettyEventLoopFactory {\n-    public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {\n-        ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);\n-        return shouldEpoll() ? new EpollEventLoopGroup(threads, threadFactory) :\n-                new NioEventLoopGroup(threads, threadFactory);\n-    }\n-\n-    public static Class<? extends SocketChannel> socketChannelClass() {\n-        return shouldEpoll() ? EpollSocketChannel.class : NioSocketChannel.class;\n-    }\n-\n-    public static Class<? extends ServerSocketChannel> serverSocketChannelClass() {\n-        return shouldEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;\n-    }\n-\n-    private static boolean shouldEpoll() {\n-        Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();\n-        if (configuration.getBoolean(\"netty.epoll.enable\", false)) {\n-            String osName = configuration.getString(\"os.name\");\n-            return osName.toLowerCase().contains(\"linux\") && Epoll.isAvailable();\n-        }\n-\n-        return false;\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.config.Configuration;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.epoll.Epoll;\r\n+import io.netty.channel.epoll.EpollEventLoopGroup;\r\n+import io.netty.channel.epoll.EpollServerSocketChannel;\r\n+import io.netty.channel.epoll.EpollSocketChannel;\r\n+import io.netty.channel.nio.NioEventLoopGroup;\r\n+import io.netty.channel.socket.ServerSocketChannel;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.channel.socket.nio.NioServerSocketChannel;\r\n+import io.netty.channel.socket.nio.NioSocketChannel;\r\n+import io.netty.util.concurrent.DefaultThreadFactory;\r\n+\r\n+import java.util.concurrent.ThreadFactory;\r\n+\r\n+public class NettyEventLoopFactory {\r\n+    public static EventLoopGroup eventLoopGroup(int threads, String threadFactoryName) {\r\n+        ThreadFactory threadFactory = new DefaultThreadFactory(threadFactoryName, true);\r\n+        return shouldEpoll() ? new EpollEventLoopGroup(threads, threadFactory) :\r\n+                new NioEventLoopGroup(threads, threadFactory);\r\n+    }\r\n+\r\n+    public static Class<? extends SocketChannel> socketChannelClass() {\r\n+        return shouldEpoll() ? EpollSocketChannel.class : NioSocketChannel.class;\r\n+    }\r\n+\r\n+    public static Class<? extends ServerSocketChannel> serverSocketChannelClass() {\r\n+        return shouldEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class;\r\n+    }\r\n+\r\n+    private static boolean shouldEpoll() {\r\n+        Configuration configuration = ApplicationModel.getEnvironment().getConfiguration();\r\n+        if (configuration.getBoolean(\"netty.epoll.enable\", false)) {\r\n+            String osName = configuration.getString(\"os.name\");\r\n+            return osName.toLowerCase().contains(\"linux\") && Epoll.isAvailable();\r\n+        }\r\n+\r\n+        return false;\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyServer.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyServer.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,202 +1,202 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ExecutorUtil;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Constants;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.remoting.transport.AbstractServer;\n-import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;\n-import org.apache.dubbo.remoting.utils.UrlUtils;\n-\n-import io.netty.bootstrap.ServerBootstrap;\n-import io.netty.buffer.PooledByteBufAllocator;\n-import io.netty.channel.ChannelFuture;\n-import io.netty.channel.ChannelInitializer;\n-import io.netty.channel.ChannelOption;\n-import io.netty.channel.EventLoopGroup;\n-import io.netty.channel.socket.SocketChannel;\n-import io.netty.handler.timeout.IdleStateHandler;\n-\n-import java.net.InetSocketAddress;\n-import java.util.ArrayList;\n-import java.util.Collection;\n-import java.util.Map;\n-\n-import static java.util.concurrent.TimeUnit.MILLISECONDS;\n-import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.KEEP_ALIVE_KEY;\n-import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\n-\n-\n-/**\n- * NettyServer.\n- */\n-public class NettyServer extends AbstractServer implements RemotingServer {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);\n-    /**\n-     * the cache for alive worker channel.\n-     * <ip:port, dubbo channel>\n-     */\n-    private Map<String, Channel> channels;\n-    /**\n-     * netty server bootstrap.\n-     */\n-    private ServerBootstrap bootstrap;\n-    /**\n-     * the boss channel that receive connections and dispatch these to worker channel.\n-     */\n-\tprivate io.netty.channel.Channel channel;\n-\n-    private EventLoopGroup bossGroup;\n-    private EventLoopGroup workerGroup;\n-\n-    public NettyServer(URL url, ChannelHandler handler) throws RemotingException {\n-        // you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\n-        // the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\n-        super(ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME), ChannelHandlers.wrap(handler, url));\n-    }\n-\n-    /**\n-     * Init and start netty server\n-     *\n-     * @throws Throwable\n-     */\n-    @Override\n-    protected void doOpen() throws Throwable {\n-        bootstrap = new ServerBootstrap();\n-\n-        bossGroup = NettyEventLoopFactory.eventLoopGroup(1, \"NettyServerBoss\");\n-        workerGroup = NettyEventLoopFactory.eventLoopGroup(\n-                getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),\n-                \"NettyServerWorker\");\n-\n-        final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);\n-        channels = nettyServerHandler.getChannels();\n-\n-        boolean keepalive = getUrl().getParameter(KEEP_ALIVE_KEY, Boolean.FALSE);\n-\n-        bootstrap.group(bossGroup, workerGroup)\n-                .channel(NettyEventLoopFactory.serverSocketChannelClass())\n-                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)\n-                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)\n-                .childOption(ChannelOption.SO_KEEPALIVE, keepalive)\n-                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\n-                .childHandler(new ChannelInitializer<SocketChannel>() {\n-                    @Override\n-                    protected void initChannel(SocketChannel ch) throws Exception {\n-                        // FIXME: should we use getTimeout()?\n-                        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());\n-                        NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);\n-                        if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\n-                            ch.pipeline().addLast(\"negotiation\",\n-                                    SslHandlerInitializer.sslServerHandler(getUrl(), nettyServerHandler));\n-                        }\n-                        ch.pipeline()\n-                                .addLast(\"decoder\", adapter.getDecoder())\n-                                .addLast(\"encoder\", adapter.getEncoder())\n-                                .addLast(\"server-idle-handler\", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))\n-                                .addLast(\"handler\", nettyServerHandler);\n-                    }\n-                });\n-        // bind\n-        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());\n-        channelFuture.syncUninterruptibly();\n-        channel = channelFuture.channel();\n-\n-    }\n-\n-    @Override\n-    protected void doClose() throws Throwable {\n-        try {\n-            if (channel != null) {\n-                // unbind.\n-                channel.close();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            Collection<org.apache.dubbo.remoting.Channel> channels = getChannels();\n-            if (channels != null && channels.size() > 0) {\n-                for (org.apache.dubbo.remoting.Channel channel : channels) {\n-                    try {\n-                        channel.close();\n-                    } catch (Throwable e) {\n-                        logger.warn(e.getMessage(), e);\n-                    }\n-                }\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (bootstrap != null) {\n-                bossGroup.shutdownGracefully().syncUninterruptibly();\n-                workerGroup.shutdownGracefully().syncUninterruptibly();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-        try {\n-            if (channels != null) {\n-                channels.clear();\n-            }\n-        } catch (Throwable e) {\n-            logger.warn(e.getMessage(), e);\n-        }\n-    }\n-\n-    @Override\n-    public Collection<Channel> getChannels() {\n-        Collection<Channel> chs = new ArrayList<>(this.channels.size());\n-        chs.addAll(this.channels.values());\n-        // check of connection status is unnecessary since we are using channels in NettyServerHandler\n-//        for (Channel channel : this.channels.values()) {\n-//            if (channel.isConnected()) {\n-//                chs.add(channel);\n-//            } else {\n-//                channels.remove(NetUtils.toAddressString(channel.getRemoteAddress()));\n-//            }\n-//        }\n-        return chs;\n-    }\n-\n-    @Override\n-    public Channel getChannel(InetSocketAddress remoteAddress) {\n-        return channels.get(NetUtils.toAddressString(remoteAddress));\n-    }\n-\n-    @Override\n-    public boolean canHandleIdle() {\n-        return true;\n-    }\n-\n-    @Override\n-    public boolean isBound() {\n-        return channel.isActive();\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ExecutorUtil;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Constants;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.remoting.transport.AbstractServer;\r\n+import org.apache.dubbo.remoting.transport.dispatcher.ChannelHandlers;\r\n+import org.apache.dubbo.remoting.utils.UrlUtils;\r\n+\r\n+import io.netty.bootstrap.ServerBootstrap;\r\n+import io.netty.buffer.PooledByteBufAllocator;\r\n+import io.netty.channel.ChannelFuture;\r\n+import io.netty.channel.ChannelInitializer;\r\n+import io.netty.channel.ChannelOption;\r\n+import io.netty.channel.EventLoopGroup;\r\n+import io.netty.channel.socket.SocketChannel;\r\n+import io.netty.handler.timeout.IdleStateHandler;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.ArrayList;\r\n+import java.util.Collection;\r\n+import java.util.Map;\r\n+\r\n+import static java.util.concurrent.TimeUnit.MILLISECONDS;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.IO_THREADS_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.KEEP_ALIVE_KEY;\r\n+import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;\r\n+\r\n+\r\n+/**\r\n+ * NettyServer.\r\n+ */\r\n+public class NettyServer extends AbstractServer implements RemotingServer {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyServer.class);\r\n+    /**\r\n+     * the cache for alive worker channel.\r\n+     * <ip:port, dubbo channel>\r\n+     */\r\n+    private Map<String, Channel> channels;\r\n+    /**\r\n+     * netty server bootstrap.\r\n+     */\r\n+    private ServerBootstrap bootstrap;\r\n+    /**\r\n+     * the boss channel that receive connections and dispatch these to worker channel.\r\n+     */\r\n+\tprivate io.netty.channel.Channel channel;\r\n+\r\n+    private EventLoopGroup bossGroup;\r\n+    private EventLoopGroup workerGroup;\r\n+\r\n+    public NettyServer(URL url, ChannelHandler handler) throws RemotingException {\r\n+        // you can customize name and type of client thread pool by THREAD_NAME_KEY and THREADPOOL_KEY in CommonConstants.\r\n+        // the handler will be wrapped: MultiMessageHandler->HeartbeatHandler->handler\r\n+        super(ExecutorUtil.setThreadName(url, SERVER_THREAD_POOL_NAME), ChannelHandlers.wrap(handler, url));\r\n+    }\r\n+\r\n+    /**\r\n+     * Init and start netty server\r\n+     *\r\n+     * @throws Throwable\r\n+     */\r\n+    @Override\r\n+    protected void doOpen() throws Throwable {\r\n+        bootstrap = new ServerBootstrap();\r\n+\r\n+        bossGroup = NettyEventLoopFactory.eventLoopGroup(1, \"NettyServerBoss\");\r\n+        workerGroup = NettyEventLoopFactory.eventLoopGroup(\r\n+                getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),\r\n+                \"NettyServerWorker\");\r\n+\r\n+        final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);\r\n+        channels = nettyServerHandler.getChannels();\r\n+\r\n+        boolean keepalive = getUrl().getParameter(KEEP_ALIVE_KEY, Boolean.FALSE);\r\n+\r\n+        bootstrap.group(bossGroup, workerGroup)\r\n+                .channel(NettyEventLoopFactory.serverSocketChannelClass())\r\n+                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)\r\n+                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)\r\n+                .childOption(ChannelOption.SO_KEEPALIVE, keepalive)\r\n+                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)\r\n+                .childHandler(new ChannelInitializer<SocketChannel>() {\r\n+                    @Override\r\n+                    protected void initChannel(SocketChannel ch) throws Exception {\r\n+                        // FIXME: should we use getTimeout()?\r\n+                        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());\r\n+                        NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);\r\n+                        if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {\r\n+                            ch.pipeline().addLast(\"negotiation\",\r\n+                                    SslHandlerInitializer.sslServerHandler(getUrl(), nettyServerHandler));\r\n+                        }\r\n+                        ch.pipeline()\r\n+                                .addLast(\"decoder\", adapter.getDecoder())\r\n+                                .addLast(\"encoder\", adapter.getEncoder())\r\n+                                .addLast(\"server-idle-handler\", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))\r\n+                                .addLast(\"handler\", nettyServerHandler);\r\n+                    }\r\n+                });\r\n+        // bind\r\n+        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());\r\n+        channelFuture.syncUninterruptibly();\r\n+        channel = channelFuture.channel();\r\n+\r\n+    }\r\n+\r\n+    @Override\r\n+    protected void doClose() throws Throwable {\r\n+        try {\r\n+            if (channel != null) {\r\n+                // unbind.\r\n+                channel.close();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            Collection<org.apache.dubbo.remoting.Channel> channels = getChannels();\r\n+            if (channels != null && channels.size() > 0) {\r\n+                for (org.apache.dubbo.remoting.Channel channel : channels) {\r\n+                    try {\r\n+                        channel.close();\r\n+                    } catch (Throwable e) {\r\n+                        logger.warn(e.getMessage(), e);\r\n+                    }\r\n+                }\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (bootstrap != null) {\r\n+                bossGroup.shutdownGracefully().syncUninterruptibly();\r\n+                workerGroup.shutdownGracefully().syncUninterruptibly();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+        try {\r\n+            if (channels != null) {\r\n+                channels.clear();\r\n+            }\r\n+        } catch (Throwable e) {\r\n+            logger.warn(e.getMessage(), e);\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public Collection<Channel> getChannels() {\r\n+        Collection<Channel> chs = new ArrayList<>(this.channels.size());\r\n+        chs.addAll(this.channels.values());\r\n+        // check of connection status is unnecessary since we are using channels in NettyServerHandler\r\n+//        for (Channel channel : this.channels.values()) {\r\n+//            if (channel.isConnected()) {\r\n+//                chs.add(channel);\r\n+//            } else {\r\n+//                channels.remove(NetUtils.toAddressString(channel.getRemoteAddress()));\r\n+//            }\r\n+//        }\r\n+        return chs;\r\n+    }\r\n+\r\n+    @Override\r\n+    public Channel getChannel(InetSocketAddress remoteAddress) {\r\n+        return channels.get(NetUtils.toAddressString(remoteAddress));\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean canHandleIdle() {\r\n+        return true;\r\n+    }\r\n+\r\n+    @Override\r\n+    public boolean isBound() {\r\n+        return channel.isActive();\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,138 +1,138 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.NetUtils;\n-import org.apache.dubbo.remoting.Channel;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.transport.netty4.SslHandlerInitializer.HandshakeCompletionEvent;\n-\n-import io.netty.channel.ChannelDuplexHandler;\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelPromise;\n-import io.netty.handler.timeout.IdleStateEvent;\n-\n-import java.net.InetSocketAddress;\n-import java.util.Map;\n-import java.util.concurrent.ConcurrentHashMap;\n-\n-/**\n- * NettyServerHandler.\n- */\n-@io.netty.channel.ChannelHandler.Sharable\n-public class NettyServerHandler extends ChannelDuplexHandler {\n-    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);\n-    /**\n-     * the cache for alive worker channel.\n-     * <ip:port, dubbo channel>\n-     */\n-    private final Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();\n-\n-    private final URL url;\n-\n-    private final ChannelHandler handler;\n-\n-    public NettyServerHandler(URL url, ChannelHandler handler) {\n-        if (url == null) {\n-            throw new IllegalArgumentException(\"url == null\");\n-        }\n-        if (handler == null) {\n-            throw new IllegalArgumentException(\"handler == null\");\n-        }\n-        this.url = url;\n-        this.handler = handler;\n-    }\n-\n-    public Map<String, Channel> getChannels() {\n-        return channels;\n-    }\n-\n-    @Override\n-    public void channelActive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        if (channel != null) {\n-            channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);\n-        }\n-        handler.connected(channel);\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is established.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()));\n-            handler.disconnected(channel);\n-        } finally {\n-            NettyChannel.removeChannel(ctx.channel());\n-        }\n-\n-        if (logger.isInfoEnabled()) {\n-            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is disconnected.\");\n-        }\n-    }\n-\n-    @Override\n-    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.received(channel, msg);\n-    }\n-\n-\n-    @Override\n-    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\n-        super.write(ctx, msg, promise);\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        handler.sent(channel, msg);\n-    }\n-\n-    @Override\n-    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-        // server will close channel when server don't receive any heartbeat from client util timeout.\n-        if (evt instanceof IdleStateEvent) {\n-            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-            try {\n-                logger.info(\"IdleStateEvent triggered, close channel \" + channel);\n-                channel.close();\n-            } finally {\n-                NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-            }\n-        }\n-        super.userEventTriggered(ctx, evt);\n-    }\n-\n-    @Override\n-    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\n-            throws Exception {\n-        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\n-        try {\n-            handler.caught(channel, cause);\n-        } finally {\n-            NettyChannel.removeChannelIfDisconnected(ctx.channel());\n-        }\n-    }\n-\n-    public void handshakeCompleted(HandshakeCompletionEvent evt) {\n-        // TODO\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.NetUtils;\r\n+import org.apache.dubbo.remoting.Channel;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.transport.netty4.SslHandlerInitializer.HandshakeCompletionEvent;\r\n+\r\n+import io.netty.channel.ChannelDuplexHandler;\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelPromise;\r\n+import io.netty.handler.timeout.IdleStateEvent;\r\n+\r\n+import java.net.InetSocketAddress;\r\n+import java.util.Map;\r\n+import java.util.concurrent.ConcurrentHashMap;\r\n+\r\n+/**\r\n+ * NettyServerHandler.\r\n+ */\r\n+@io.netty.channel.ChannelHandler.Sharable\r\n+public class NettyServerHandler extends ChannelDuplexHandler {\r\n+    private static final Logger logger = LoggerFactory.getLogger(NettyServerHandler.class);\r\n+    /**\r\n+     * the cache for alive worker channel.\r\n+     * <ip:port, dubbo channel>\r\n+     */\r\n+    private final Map<String, Channel> channels = new ConcurrentHashMap<String, Channel>();\r\n+\r\n+    private final URL url;\r\n+\r\n+    private final ChannelHandler handler;\r\n+\r\n+    public NettyServerHandler(URL url, ChannelHandler handler) {\r\n+        if (url == null) {\r\n+            throw new IllegalArgumentException(\"url == null\");\r\n+        }\r\n+        if (handler == null) {\r\n+            throw new IllegalArgumentException(\"handler == null\");\r\n+        }\r\n+        this.url = url;\r\n+        this.handler = handler;\r\n+    }\r\n+\r\n+    public Map<String, Channel> getChannels() {\r\n+        return channels;\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelActive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        if (channel != null) {\r\n+            channels.put(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()), channel);\r\n+        }\r\n+        handler.connected(channel);\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is established.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            channels.remove(NetUtils.toAddressString((InetSocketAddress) ctx.channel().remoteAddress()));\r\n+            handler.disconnected(channel);\r\n+        } finally {\r\n+            NettyChannel.removeChannel(ctx.channel());\r\n+        }\r\n+\r\n+        if (logger.isInfoEnabled()) {\r\n+            logger.info(\"The connection of \" + channel.getRemoteAddress() + \" -> \" + channel.getLocalAddress() + \" is disconnected.\");\r\n+        }\r\n+    }\r\n+\r\n+    @Override\r\n+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.received(channel, msg);\r\n+    }\r\n+\r\n+\r\n+    @Override\r\n+    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {\r\n+        super.write(ctx, msg, promise);\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        handler.sent(channel, msg);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+        // server will close channel when server don't receive any heartbeat from client util timeout.\r\n+        if (evt instanceof IdleStateEvent) {\r\n+            NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+            try {\r\n+                logger.info(\"IdleStateEvent triggered, close channel \" + channel);\r\n+                channel.close();\r\n+            } finally {\r\n+                NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+            }\r\n+        }\r\n+        super.userEventTriggered(ctx, evt);\r\n+    }\r\n+\r\n+    @Override\r\n+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)\r\n+            throws Exception {\r\n+        NettyChannel channel = NettyChannel.getOrAddChannel(ctx.channel(), url, handler);\r\n+        try {\r\n+            handler.caught(channel, cause);\r\n+        } finally {\r\n+            NettyChannel.removeChannelIfDisconnected(ctx.channel());\r\n+        }\r\n+    }\r\n+\r\n+    public void handshakeCompleted(HandshakeCompletionEvent evt) {\r\n+        // TODO\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/NettyTransporter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,43 +1,43 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.remoting.ChannelHandler;\n-import org.apache.dubbo.remoting.Client;\n-import org.apache.dubbo.remoting.RemotingException;\n-import org.apache.dubbo.remoting.RemotingServer;\n-import org.apache.dubbo.remoting.Transporter;\n-\n-/**\n- * Default extension of {@link Transporter} using netty4.x.\n- */\n-public class NettyTransporter implements Transporter {\n-\n-    public static final String NAME = \"netty\";\n-\n-    @Override\n-    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {\n-        return new NettyServer(url, handler);\n-    }\n-\n-    @Override\n-    public Client connect(URL url, ChannelHandler handler) throws RemotingException {\n-        return new NettyClient(url, handler);\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.remoting.ChannelHandler;\r\n+import org.apache.dubbo.remoting.Client;\r\n+import org.apache.dubbo.remoting.RemotingException;\r\n+import org.apache.dubbo.remoting.RemotingServer;\r\n+import org.apache.dubbo.remoting.Transporter;\r\n+\r\n+/**\r\n+ * Default extension of {@link Transporter} using netty4.x.\r\n+ */\r\n+public class NettyTransporter implements Transporter {\r\n+\r\n+    public static final String NAME = \"netty\";\r\n+\r\n+    @Override\r\n+    public RemotingServer bind(URL url, ChannelHandler handler) throws RemotingException {\r\n+        return new NettyServer(url, handler);\r\n+    }\r\n+\r\n+    @Override\r\n+    public Client connect(URL url, ChannelHandler handler) throws RemotingException {\r\n+        return new NettyClient(url, handler);\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/SslContexts.java", "source2": "org/apache/dubbo/remoting/transport/netty4/SslContexts.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,121 +1,121 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.config.SslConfig;\n-import org.apache.dubbo.config.context.ConfigManager;\n-import org.apache.dubbo.rpc.model.ApplicationModel;\n-\n-import io.netty.handler.ssl.ClientAuth;\n-import io.netty.handler.ssl.OpenSsl;\n-import io.netty.handler.ssl.SslContext;\n-import io.netty.handler.ssl.SslContextBuilder;\n-import io.netty.handler.ssl.SslProvider;\n-\n-import javax.net.ssl.SSLException;\n-import java.io.InputStream;\n-import java.security.Provider;\n-import java.security.Security;\n-\n-public class SslContexts {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(SslContexts.class);\n-\n-    public static SslContext buildServerSslContext(URL url) {\n-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\n-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\n-\n-        SslContextBuilder sslClientContextBuilder = null;\n-        try {\n-            String password = sslConfig.getServerKeyPassword();\n-            if (password != null) {\n-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\n-                        sslConfig.getServerPrivateKeyPathStream(), password);\n-            } else {\n-                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\n-                        sslConfig.getServerPrivateKeyPathStream());\n-            }\n-\n-            if (sslConfig.getServerTrustCertCollectionPathStream() != null) {\n-                sslClientContextBuilder.trustManager(sslConfig.getServerTrustCertCollectionPathStream());\n-                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);\n-            }\n-        } catch (Exception e) {\n-            throw new IllegalArgumentException(\"Could not find certificate file or the certificate is invalid.\", e);\n-        }\n-        try {\n-            return sslClientContextBuilder.sslProvider(findSslProvider()).build();\n-        } catch (SSLException e) {\n-            throw new IllegalStateException(\"Build SslSession failed.\", e);\n-        }\n-    }\n-\n-    public static SslContext buildClientSslContext(URL url) {\n-        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\n-        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\n-\n-        SslContextBuilder builder = SslContextBuilder.forClient();\n-        try {\n-            if (sslConfig.getClientTrustCertCollectionPathStream() != null) {\n-                builder.trustManager(sslConfig.getClientTrustCertCollectionPathStream());\n-            }\n-\n-            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();\n-            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();\n-            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {\n-                String password = sslConfig.getClientKeyPassword();\n-                if (password != null) {\n-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password);\n-                } else {\n-                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath);\n-                }\n-            }\n-        } catch (Exception e) {\n-            throw new IllegalArgumentException(\"Could not find certificate file or find invalid certificate.\", e);\n-        }\n-        try {\n-            return builder.sslProvider(findSslProvider()).build();\n-        } catch (SSLException e) {\n-            throw new IllegalStateException(\"Build SslSession failed.\", e);\n-        }\n-    }\n-\n-    /**\n-     * Returns OpenSSL if available, otherwise returns the JDK provider.\n-     */\n-    private static SslProvider findSslProvider() {\n-        if (OpenSsl.isAvailable()) {\n-            logger.info(\"Using OPENSSL provider.\");\n-            return SslProvider.OPENSSL;\n-        } else if (checkJdkProvider()) {\n-            logger.info(\"Using JDK provider.\");\n-            return SslProvider.JDK;\n-        }\n-        throw new IllegalStateException(\n-                \"Could not find any valid TLS provider, please check your dependency or deployment environment, \" +\n-                        \"usually netty-tcnative, Conscrypt, or Jetty NPN/ALPN is needed.\");\n-    }\n-\n-    private static boolean checkJdkProvider() {\n-        Provider[] jdkProviders = Security.getProviders(\"SSLContext.TLS\");\n-        return (jdkProviders != null && jdkProviders.length > 0);\n-    }\n-\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.config.SslConfig;\r\n+import org.apache.dubbo.config.context.ConfigManager;\r\n+import org.apache.dubbo.rpc.model.ApplicationModel;\r\n+\r\n+import io.netty.handler.ssl.ClientAuth;\r\n+import io.netty.handler.ssl.OpenSsl;\r\n+import io.netty.handler.ssl.SslContext;\r\n+import io.netty.handler.ssl.SslContextBuilder;\r\n+import io.netty.handler.ssl.SslProvider;\r\n+\r\n+import javax.net.ssl.SSLException;\r\n+import java.io.InputStream;\r\n+import java.security.Provider;\r\n+import java.security.Security;\r\n+\r\n+public class SslContexts {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(SslContexts.class);\r\n+\r\n+    public static SslContext buildServerSslContext(URL url) {\r\n+        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\r\n+        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\r\n+\r\n+        SslContextBuilder sslClientContextBuilder = null;\r\n+        try {\r\n+            String password = sslConfig.getServerKeyPassword();\r\n+            if (password != null) {\r\n+                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\r\n+                        sslConfig.getServerPrivateKeyPathStream(), password);\r\n+            } else {\r\n+                sslClientContextBuilder = SslContextBuilder.forServer(sslConfig.getServerKeyCertChainPathStream(),\r\n+                        sslConfig.getServerPrivateKeyPathStream());\r\n+            }\r\n+\r\n+            if (sslConfig.getServerTrustCertCollectionPathStream() != null) {\r\n+                sslClientContextBuilder.trustManager(sslConfig.getServerTrustCertCollectionPathStream());\r\n+                sslClientContextBuilder.clientAuth(ClientAuth.REQUIRE);\r\n+            }\r\n+        } catch (Exception e) {\r\n+            throw new IllegalArgumentException(\"Could not find certificate file or the certificate is invalid.\", e);\r\n+        }\r\n+        try {\r\n+            return sslClientContextBuilder.sslProvider(findSslProvider()).build();\r\n+        } catch (SSLException e) {\r\n+            throw new IllegalStateException(\"Build SslSession failed.\", e);\r\n+        }\r\n+    }\r\n+\r\n+    public static SslContext buildClientSslContext(URL url) {\r\n+        ConfigManager globalConfigManager = ApplicationModel.getConfigManager();\r\n+        SslConfig sslConfig = globalConfigManager.getSsl().orElseThrow(() -> new IllegalStateException(\"Ssl enabled, but no ssl cert information provided!\"));\r\n+\r\n+        SslContextBuilder builder = SslContextBuilder.forClient();\r\n+        try {\r\n+            if (sslConfig.getClientTrustCertCollectionPathStream() != null) {\r\n+                builder.trustManager(sslConfig.getClientTrustCertCollectionPathStream());\r\n+            }\r\n+\r\n+            InputStream clientCertChainFilePath = sslConfig.getClientKeyCertChainPathStream();\r\n+            InputStream clientPrivateKeyFilePath = sslConfig.getClientPrivateKeyPathStream();\r\n+            if (clientCertChainFilePath != null && clientPrivateKeyFilePath != null) {\r\n+                String password = sslConfig.getClientKeyPassword();\r\n+                if (password != null) {\r\n+                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath, password);\r\n+                } else {\r\n+                    builder.keyManager(clientCertChainFilePath, clientPrivateKeyFilePath);\r\n+                }\r\n+            }\r\n+        } catch (Exception e) {\r\n+            throw new IllegalArgumentException(\"Could not find certificate file or find invalid certificate.\", e);\r\n+        }\r\n+        try {\r\n+            return builder.sslProvider(findSslProvider()).build();\r\n+        } catch (SSLException e) {\r\n+            throw new IllegalStateException(\"Build SslSession failed.\", e);\r\n+        }\r\n+    }\r\n+\r\n+    /**\r\n+     * Returns OpenSSL if available, otherwise returns the JDK provider.\r\n+     */\r\n+    private static SslProvider findSslProvider() {\r\n+        if (OpenSsl.isAvailable()) {\r\n+            logger.info(\"Using OPENSSL provider.\");\r\n+            return SslProvider.OPENSSL;\r\n+        } else if (checkJdkProvider()) {\r\n+            logger.info(\"Using JDK provider.\");\r\n+            return SslProvider.JDK;\r\n+        }\r\n+        throw new IllegalStateException(\r\n+                \"Could not find any valid TLS provider, please check your dependency or deployment environment, \" +\r\n+                        \"usually netty-tcnative, Conscrypt, or Jetty NPN/ALPN is needed.\");\r\n+    }\r\n+\r\n+    private static boolean checkJdkProvider() {\r\n+        Provider[] jdkProviders = Security.getProviders(\"SSLContext.TLS\");\r\n+        return (jdkProviders != null && jdkProviders.length > 0);\r\n+    }\r\n+\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java", "source2": "org/apache/dubbo/remoting/transport/netty4/SslHandlerInitializer.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,141 +1,141 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4;\n-\n-import org.apache.dubbo.common.URL;\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-\n-import io.netty.channel.ChannelHandlerContext;\n-import io.netty.channel.ChannelInboundHandler;\n-import io.netty.channel.ChannelInboundHandlerAdapter;\n-import io.netty.handler.ssl.SslContext;\n-import io.netty.handler.ssl.SslHandler;\n-import io.netty.handler.ssl.SslHandshakeCompletionEvent;\n-\n-import javax.net.ssl.SSLEngine;\n-import javax.net.ssl.SSLSession;\n-\n-/**\n- * Handshake, SSl and Protocol\n- */\n-public class SslHandlerInitializer {\n-\n-    private static final Logger logger = LoggerFactory.getLogger(SslHandlerInitializer.class);\n-\n-    public static ChannelInboundHandler sslServerHandler(URL url, NettyServerHandler serverHandler) {\n-        // Decorate if necessary\n-        return new SslServerTlsHandler(url, serverHandler);\n-    }\n-\n-    public static ChannelInboundHandler sslClientHandler(URL url, NettyClientHandler clientHandler) {\n-        return new SslClientTlsHandler(url, clientHandler);\n-    }\n-\n-    public static class SslServerTlsHandler extends ChannelInboundHandlerAdapter {\n-\n-        private final SslContext sslContext;\n-        private final NettyServerHandler serverHandler;\n-\n-        SslServerTlsHandler(URL url, NettyServerHandler serverHandler) {\n-            this.sslContext = SslContexts.buildServerSslContext(url);\n-            this.serverHandler = serverHandler;\n-        }\n-\n-        @Override\n-        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {\n-            super.handlerAdded(ctx);\n-\n-            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\n-            ctx.pipeline().addFirst(new SslHandler(sslEngine, false));\n-        }\n-\n-        @Override\n-        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {\n-            logger.error(\"TLS negotiation failed when trying to accept new connection.\", cause);\n-        }\n-\n-        @Override\n-        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-            if (evt instanceof SslHandshakeCompletionEvent) {\n-                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\n-                if (handshakeEvent.isSuccess()) {\n-                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\n-                    logger.info(\"TLS negotiation succeed with session: \" + session);\n-                    serverHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\n-                    // Remove after handshake success.\n-                    ctx.pipeline().remove(this);\n-                } else {\n-                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\n-                    ctx.close();\n-                }\n-            }\n-            super.userEventTriggered(ctx, evt);\n-        }\n-    }\n-\n-    public static class SslClientTlsHandler extends ChannelInboundHandlerAdapter {\n-\n-        private final SslContext sslContext;\n-        private final NettyClientHandler clientHandler;\n-\n-        public SslClientTlsHandler(URL url, NettyClientHandler clientHandler) {\n-            this.sslContext = SslContexts.buildClientSslContext(url);\n-            this.clientHandler = clientHandler;\n-        }\n-\n-        @Override\n-        public void handlerAdded(ChannelHandlerContext ctx) {\n-            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\n-            ctx.pipeline().addBefore(ctx.name(), null, new SslHandler(sslEngine, false));\n-        }\n-\n-        @Override\n-        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\n-            if (evt instanceof SslHandshakeCompletionEvent) {\n-                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\n-                if (handshakeEvent.isSuccess()) {\n-                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\n-                    logger.info(\"TLS negotiation succeed with session: \" + session);\n-                    clientHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\n-                    ctx.pipeline().remove(this);\n-                } else {\n-                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\n-                    ctx.fireExceptionCaught(handshakeEvent.cause());\n-                }\n-            }\n-        }\n-    }\n-\n-    public static class HandshakeCompletionEvent {\n-        private final SSLSession sslSession;\n-        private final ChannelHandlerContext ctx;\n-\n-        public HandshakeCompletionEvent(SSLSession sslSession, ChannelHandlerContext ctx) {\n-            this.sslSession = sslSession;\n-            this.ctx = ctx;\n-        }\n-\n-        public SSLSession getSslSession() {\n-            return sslSession;\n-        }\n-\n-        public ChannelHandlerContext getCtx() {\n-            return ctx;\n-        }\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4;\r\n+\r\n+import org.apache.dubbo.common.URL;\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+\r\n+import io.netty.channel.ChannelHandlerContext;\r\n+import io.netty.channel.ChannelInboundHandler;\r\n+import io.netty.channel.ChannelInboundHandlerAdapter;\r\n+import io.netty.handler.ssl.SslContext;\r\n+import io.netty.handler.ssl.SslHandler;\r\n+import io.netty.handler.ssl.SslHandshakeCompletionEvent;\r\n+\r\n+import javax.net.ssl.SSLEngine;\r\n+import javax.net.ssl.SSLSession;\r\n+\r\n+/**\r\n+ * Handshake, SSl and Protocol\r\n+ */\r\n+public class SslHandlerInitializer {\r\n+\r\n+    private static final Logger logger = LoggerFactory.getLogger(SslHandlerInitializer.class);\r\n+\r\n+    public static ChannelInboundHandler sslServerHandler(URL url, NettyServerHandler serverHandler) {\r\n+        // Decorate if necessary\r\n+        return new SslServerTlsHandler(url, serverHandler);\r\n+    }\r\n+\r\n+    public static ChannelInboundHandler sslClientHandler(URL url, NettyClientHandler clientHandler) {\r\n+        return new SslClientTlsHandler(url, clientHandler);\r\n+    }\r\n+\r\n+    public static class SslServerTlsHandler extends ChannelInboundHandlerAdapter {\r\n+\r\n+        private final SslContext sslContext;\r\n+        private final NettyServerHandler serverHandler;\r\n+\r\n+        SslServerTlsHandler(URL url, NettyServerHandler serverHandler) {\r\n+            this.sslContext = SslContexts.buildServerSslContext(url);\r\n+            this.serverHandler = serverHandler;\r\n+        }\r\n+\r\n+        @Override\r\n+        public void handlerAdded(ChannelHandlerContext ctx) throws Exception {\r\n+            super.handlerAdded(ctx);\r\n+\r\n+            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\r\n+            ctx.pipeline().addFirst(new SslHandler(sslEngine, false));\r\n+        }\r\n+\r\n+        @Override\r\n+        public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {\r\n+            logger.error(\"TLS negotiation failed when trying to accept new connection.\", cause);\r\n+        }\r\n+\r\n+        @Override\r\n+        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+            if (evt instanceof SslHandshakeCompletionEvent) {\r\n+                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\r\n+                if (handshakeEvent.isSuccess()) {\r\n+                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\r\n+                    logger.info(\"TLS negotiation succeed with session: \" + session);\r\n+                    serverHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\r\n+                    // Remove after handshake success.\r\n+                    ctx.pipeline().remove(this);\r\n+                } else {\r\n+                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\r\n+                    ctx.close();\r\n+                }\r\n+            }\r\n+            super.userEventTriggered(ctx, evt);\r\n+        }\r\n+    }\r\n+\r\n+    public static class SslClientTlsHandler extends ChannelInboundHandlerAdapter {\r\n+\r\n+        private final SslContext sslContext;\r\n+        private final NettyClientHandler clientHandler;\r\n+\r\n+        public SslClientTlsHandler(URL url, NettyClientHandler clientHandler) {\r\n+            this.sslContext = SslContexts.buildClientSslContext(url);\r\n+            this.clientHandler = clientHandler;\r\n+        }\r\n+\r\n+        @Override\r\n+        public void handlerAdded(ChannelHandlerContext ctx) {\r\n+            SSLEngine sslEngine = sslContext.newEngine(ctx.alloc());\r\n+            ctx.pipeline().addBefore(ctx.name(), null, new SslHandler(sslEngine, false));\r\n+        }\r\n+\r\n+        @Override\r\n+        public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {\r\n+            if (evt instanceof SslHandshakeCompletionEvent) {\r\n+                SslHandshakeCompletionEvent handshakeEvent = (SslHandshakeCompletionEvent) evt;\r\n+                if (handshakeEvent.isSuccess()) {\r\n+                    SSLSession session = ctx.pipeline().get(SslHandler.class).engine().getSession();\r\n+                    logger.info(\"TLS negotiation succeed with session: \" + session);\r\n+                    clientHandler.handshakeCompleted(new HandshakeCompletionEvent(session, ctx));\r\n+                    ctx.pipeline().remove(this);\r\n+                } else {\r\n+                    logger.error(\"TLS negotiation failed when trying to accept new connection.\", handshakeEvent.cause());\r\n+                    ctx.fireExceptionCaught(handshakeEvent.cause());\r\n+                }\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    public static class HandshakeCompletionEvent {\r\n+        private final SSLSession sslSession;\r\n+        private final ChannelHandlerContext ctx;\r\n+\r\n+        public HandshakeCompletionEvent(SSLSession sslSession, ChannelHandlerContext ctx) {\r\n+            this.sslSession = sslSession;\r\n+            this.ctx = ctx;\r\n+        }\r\n+\r\n+        public SSLSession getSslSession() {\r\n+            return sslSession;\r\n+        }\r\n+\r\n+        public ChannelHandlerContext getCtx() {\r\n+            return ctx;\r\n+        }\r\n+    }\r\n+}\r\n"}, {"source1": "org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java", "source2": "org/apache/dubbo/remoting/transport/netty4/logging/MessageFormatter.java", "comments": ["Line-ending differences only"], "unified_diff": "@@ -1,410 +1,410 @@\n-/*\n- * Licensed to the Apache Software Foundation (ASF) under one or more\n- * contributor license agreements.  See the NOTICE file distributed with\n- * this work for additional information regarding copyright ownership.\n- * The ASF licenses this file to You under the Apache License, Version 2.0\n- * (the \"License\"); you may not use this file except in compliance with\n- * the License.  You may obtain a copy of the License at\n- *\n- *     http://www.apache.org/licenses/LICENSE-2.0\n- *\n- * Unless required by applicable law or agreed to in writing, software\n- * distributed under the License is distributed on an \"AS IS\" BASIS,\n- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n- * See the License for the specific language governing permissions and\n- * limitations under the License.\n- */\n-package org.apache.dubbo.remoting.transport.netty4.logging;\n-\n-import org.apache.dubbo.common.logger.Logger;\n-import org.apache.dubbo.common.logger.LoggerFactory;\n-import org.apache.dubbo.common.utils.ArrayUtils;\n-\n-import java.text.MessageFormat;\n-import java.util.HashMap;\n-import java.util.Map;\n-\n-// contributors: lizongbo: proposed special treatment of array parameter values\n-// Joern Huxhorn: pointed out double[] omission, suggested deep array copy\n-\n-/**\n- * Formats messages according to very simple substitution rules. Substitutions\n- * can be made 1, 2 or more arguments.\n- * <p/>\n- * <p/>\n- * For example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)\n- * </pre>\n- * <p/>\n- * will return the string \"Hi there.\".\n- * <p/>\n- * The {} pair is called the <em>formatting anchor</em>. It serves to designate\n- * the location where arguments need to be substituted within the message\n- * pattern.\n- * <p/>\n- * In case your message contains the '{' or the '}' character, you do not have\n- * to do anything special unless the '}' character immediately follows '{'. For\n- * example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"Set {1,2,3} is not equal to 1,2.\".\n- * <p/>\n- * <p/>\n- * If for whatever reason you need to place the string \"{}\" in the message\n- * without its <em>formatting anchor</em> meaning, then you need to escape the\n- * '{' character with '\\', that is the backslash character. Only the '{'\n- * character should be escaped. There is no need to escape the '}' character.\n- * For example,\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;Set \\\\{} is not equal to {}.&quot;, &quot;1,2&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"Set {} is not equal to 1,2.\".\n- * <p/>\n- * <p/>\n- * The escaping behavior just described can be overridden by escaping the escape\n- * character '\\'. Calling\n- * <p/>\n- * <pre>\n- * MessageFormatter.format(&quot;File name is C:\\\\\\\\{}.&quot;, &quot;file.zip&quot;);\n- * </pre>\n- * <p/>\n- * will return the string \"File name is C:\\file.zip\".\n- * <p/>\n- * <p/>\n- * The formatting conventions are different than those of {@link MessageFormat}\n- * which ships with the Java platform. This is justified by the fact that\n- * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.\n- * This local performance difference is both measurable and significant in the\n- * larger context of the complete logging processing chain.\n- * <p/>\n- * <p/>\n- * See also {@link #format(String, Object)},\n- * {@link #format(String, Object, Object)} and\n- * {@link #arrayFormat(String, Object[])} methods for more details.\n- */\n-final class MessageFormatter {\n-    private static final Logger logger = LoggerFactory.getLogger(MessageFormatter.class);\n-    static final char DELIM_START = '{';\n-    static final char DELIM_STOP = '}';\n-    static final String DELIM_STR = \"{}\";\n-    private static final char ESCAPE_CHAR = '\\\\';\n-\n-    /**\n-     * Performs single argument substitution for the 'messagePattern' passed as\n-     * parameter.\n-     * <p/>\n-     * For example,\n-     * <p/>\n-     * <pre>\n-     * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);\n-     * </pre>\n-     * <p/>\n-     * will return the string \"Hi there.\".\n-     * <p/>\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param arg            The argument to be substituted in place of the formatting anchor\n-     * @return The formatted message\n-     */\n-    static FormattingTuple format(String messagePattern, Object arg) {\n-        return arrayFormat(messagePattern, new Object[]{arg});\n-    }\n-\n-    /**\n-     * Performs a two argument substitution for the 'messagePattern' passed as\n-     * parameter.\n-     * <p/>\n-     * For example,\n-     * <p/>\n-     * <pre>\n-     * MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);\n-     * </pre>\n-     * <p/>\n-     * will return the string \"Hi Alice. My name is Bob.\".\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param argA           The argument to be substituted in place of the first formatting\n-     *                       anchor\n-     * @param argB           The argument to be substituted in place of the second formatting\n-     *                       anchor\n-     * @return The formatted message\n-     */\n-    static FormattingTuple format(final String messagePattern,\n-                                  Object argA, Object argB) {\n-        return arrayFormat(messagePattern, new Object[]{argA, argB});\n-    }\n-\n-    static Throwable getThrowableCandidate(Object[] argArray) {\n-        if (ArrayUtils.isEmpty(argArray)) {\n-            return null;\n-        }\n-\n-        final Object lastEntry = argArray[argArray.length - 1];\n-        if (lastEntry instanceof Throwable) {\n-            return (Throwable) lastEntry;\n-        }\n-        return null;\n-    }\n-\n-    /**\n-     * Same principle as the {@link #format(String, Object)} and\n-     * {@link #format(String, Object, Object)} methods except that any number of\n-     * arguments can be passed in an array.\n-     *\n-     * @param messagePattern The message pattern which will be parsed and formatted\n-     * @param argArray       An array of arguments to be substituted in place of formatting\n-     *                       anchors\n-     * @return The formatted message\n-     */\n-    static FormattingTuple arrayFormat(final String messagePattern,\n-                                       final Object[] argArray) {\n-\n-        Throwable throwableCandidate = getThrowableCandidate(argArray);\n-\n-        if (messagePattern == null) {\n-            return new FormattingTuple(null, argArray, throwableCandidate);\n-        }\n-\n-        if (argArray == null) {\n-            return new FormattingTuple(messagePattern);\n-        }\n-\n-        int i = 0;\n-        int j;\n-        StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);\n-\n-        int l;\n-        for (l = 0; l < argArray.length; l++) {\n-\n-            j = messagePattern.indexOf(DELIM_STR, i);\n-\n-            if (j == -1) {\n-                // no more variables\n-                if (i == 0) { // this is a simple string\n-                    return new FormattingTuple(messagePattern, argArray,\n-                            throwableCandidate);\n-                } else { // add the tail string which contains no variables and return\n-                    // the result.\n-                    sbuf.append(messagePattern.substring(i));\n-                    return new FormattingTuple(sbuf.toString(), argArray,\n-                            throwableCandidate);\n-                }\n-            } else {\n-                if (isEscapedDelimiter(messagePattern, j)) {\n-                    if (!isDoubleEscaped(messagePattern, j)) {\n-                        l--; // DELIM_START was escaped, thus should not be incremented\n-                        sbuf.append(messagePattern, i, j - 1);\n-                        sbuf.append(DELIM_START);\n-                        i = j + 1;\n-                    } else {\n-                        // The escape character preceding the delimiter start is\n-                        // itself escaped: \"abc x:\\\\{}\"\n-                        // we have to consume one backward slash\n-                        sbuf.append(messagePattern, i, j - 1);\n-                        deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\n-                        i = j + 2;\n-                    }\n-                } else {\n-                    // normal case\n-                    sbuf.append(messagePattern, i, j);\n-                    deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\n-                    i = j + 2;\n-                }\n-            }\n-        }\n-        // append the characters following the last {} pair.\n-        sbuf.append(messagePattern.substring(i));\n-        if (l < argArray.length - 1) {\n-            return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);\n-        } else {\n-            return new FormattingTuple(sbuf.toString(), argArray, null);\n-        }\n-    }\n-\n-    static boolean isEscapedDelimiter(String messagePattern,\n-                                      int delimiterStartIndex) {\n-\n-        if (delimiterStartIndex == 0) {\n-            return false;\n-        }\n-        return messagePattern.charAt(delimiterStartIndex - 1) == ESCAPE_CHAR;\n-    }\n-\n-    static boolean isDoubleEscaped(String messagePattern,\n-                                   int delimiterStartIndex) {\n-        return delimiterStartIndex >= 2 && messagePattern.charAt(delimiterStartIndex - 2) == ESCAPE_CHAR;\n-    }\n-\n-    // special treatment of array values was suggested by 'lizongbo'\n-    private static void deeplyAppendParameter(StringBuffer sbuf, Object o,\n-                                              Map<Object[], Void> seenMap) {\n-        if (o == null) {\n-            sbuf.append(\"null\");\n-            return;\n-        }\n-        if (!o.getClass().isArray()) {\n-            safeObjectAppend(sbuf, o);\n-        } else {\n-            // check for primitive array types because they\n-            // unfortunately cannot be cast to Object[]\n-            if (o instanceof boolean[]) {\n-                booleanArrayAppend(sbuf, (boolean[]) o);\n-            } else if (o instanceof byte[]) {\n-                byteArrayAppend(sbuf, (byte[]) o);\n-            } else if (o instanceof char[]) {\n-                charArrayAppend(sbuf, (char[]) o);\n-            } else if (o instanceof short[]) {\n-                shortArrayAppend(sbuf, (short[]) o);\n-            } else if (o instanceof int[]) {\n-                intArrayAppend(sbuf, (int[]) o);\n-            } else if (o instanceof long[]) {\n-                longArrayAppend(sbuf, (long[]) o);\n-            } else if (o instanceof float[]) {\n-                floatArrayAppend(sbuf, (float[]) o);\n-            } else if (o instanceof double[]) {\n-                doubleArrayAppend(sbuf, (double[]) o);\n-            } else {\n-                objectArrayAppend(sbuf, (Object[]) o, seenMap);\n-            }\n-        }\n-    }\n-\n-    private static void safeObjectAppend(StringBuffer sbuf, Object o) {\n-        try {\n-            String oAsString = o.toString();\n-            sbuf.append(oAsString);\n-        } catch (Throwable t) {\n-            System.err\n-                    .println(\"SLF4J: Failed toString() invocation on an object of type [\"\n-                            + o.getClass().getName() + ']');\n-            logger.error(t.getMessage(), t);\n-            sbuf.append(\"[FAILED toString()]\");\n-        }\n-    }\n-\n-    private static void objectArrayAppend(StringBuffer sbuf, Object[] a,\n-                                          Map<Object[], Void> seenMap) {\n-        sbuf.append('[');\n-        if (!seenMap.containsKey(a)) {\n-            seenMap.put(a, null);\n-            final int len = a.length;\n-            for (int i = 0; i < len; i++) {\n-                deeplyAppendParameter(sbuf, a[i], seenMap);\n-                if (i != len - 1) {\n-                    sbuf.append(\", \");\n-                }\n-            }\n-            // allow repeats in siblings\n-            seenMap.remove(a);\n-        } else {\n-            sbuf.append(\"...\");\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void byteArrayAppend(StringBuffer sbuf, byte[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void charArrayAppend(StringBuffer sbuf, char[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void shortArrayAppend(StringBuffer sbuf, short[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void intArrayAppend(StringBuffer sbuf, int[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void longArrayAppend(StringBuffer sbuf, long[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void floatArrayAppend(StringBuffer sbuf, float[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private static void doubleArrayAppend(StringBuffer sbuf, double[] a) {\n-        sbuf.append('[');\n-        final int len = a.length;\n-        for (int i = 0; i < len; i++) {\n-            sbuf.append(a[i]);\n-            if (i != len - 1) {\n-                sbuf.append(\", \");\n-            }\n-        }\n-        sbuf.append(']');\n-    }\n-\n-    private MessageFormatter() {\n-    }\n-}\n+/*\r\n+ * Licensed to the Apache Software Foundation (ASF) under one or more\r\n+ * contributor license agreements.  See the NOTICE file distributed with\r\n+ * this work for additional information regarding copyright ownership.\r\n+ * The ASF licenses this file to You under the Apache License, Version 2.0\r\n+ * (the \"License\"); you may not use this file except in compliance with\r\n+ * the License.  You may obtain a copy of the License at\r\n+ *\r\n+ *     http://www.apache.org/licenses/LICENSE-2.0\r\n+ *\r\n+ * Unless required by applicable law or agreed to in writing, software\r\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+ * See the License for the specific language governing permissions and\r\n+ * limitations under the License.\r\n+ */\r\n+package org.apache.dubbo.remoting.transport.netty4.logging;\r\n+\r\n+import org.apache.dubbo.common.logger.Logger;\r\n+import org.apache.dubbo.common.logger.LoggerFactory;\r\n+import org.apache.dubbo.common.utils.ArrayUtils;\r\n+\r\n+import java.text.MessageFormat;\r\n+import java.util.HashMap;\r\n+import java.util.Map;\r\n+\r\n+// contributors: lizongbo: proposed special treatment of array parameter values\r\n+// Joern Huxhorn: pointed out double[] omission, suggested deep array copy\r\n+\r\n+/**\r\n+ * Formats messages according to very simple substitution rules. Substitutions\r\n+ * can be made 1, 2 or more arguments.\r\n+ * <p/>\r\n+ * <p/>\r\n+ * For example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Hi there.\".\r\n+ * <p/>\r\n+ * The {} pair is called the <em>formatting anchor</em>. It serves to designate\r\n+ * the location where arguments need to be substituted within the message\r\n+ * pattern.\r\n+ * <p/>\r\n+ * In case your message contains the '{' or the '}' character, you do not have\r\n+ * to do anything special unless the '}' character immediately follows '{'. For\r\n+ * example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Set {1,2,3} is not equal to 1,2.\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * If for whatever reason you need to place the string \"{}\" in the message\r\n+ * without its <em>formatting anchor</em> meaning, then you need to escape the\r\n+ * '{' character with '\\', that is the backslash character. Only the '{'\r\n+ * character should be escaped. There is no need to escape the '}' character.\r\n+ * For example,\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;Set \\\\{} is not equal to {}.&quot;, &quot;1,2&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"Set {} is not equal to 1,2.\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * The escaping behavior just described can be overridden by escaping the escape\r\n+ * character '\\'. Calling\r\n+ * <p/>\r\n+ * <pre>\r\n+ * MessageFormatter.format(&quot;File name is C:\\\\\\\\{}.&quot;, &quot;file.zip&quot;);\r\n+ * </pre>\r\n+ * <p/>\r\n+ * will return the string \"File name is C:\\file.zip\".\r\n+ * <p/>\r\n+ * <p/>\r\n+ * The formatting conventions are different than those of {@link MessageFormat}\r\n+ * which ships with the Java platform. This is justified by the fact that\r\n+ * SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.\r\n+ * This local performance difference is both measurable and significant in the\r\n+ * larger context of the complete logging processing chain.\r\n+ * <p/>\r\n+ * <p/>\r\n+ * See also {@link #format(String, Object)},\r\n+ * {@link #format(String, Object, Object)} and\r\n+ * {@link #arrayFormat(String, Object[])} methods for more details.\r\n+ */\r\n+final class MessageFormatter {\r\n+    private static final Logger logger = LoggerFactory.getLogger(MessageFormatter.class);\r\n+    static final char DELIM_START = '{';\r\n+    static final char DELIM_STOP = '}';\r\n+    static final String DELIM_STR = \"{}\";\r\n+    private static final char ESCAPE_CHAR = '\\\\';\r\n+\r\n+    /**\r\n+     * Performs single argument substitution for the 'messagePattern' passed as\r\n+     * parameter.\r\n+     * <p/>\r\n+     * For example,\r\n+     * <p/>\r\n+     * <pre>\r\n+     * MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);\r\n+     * </pre>\r\n+     * <p/>\r\n+     * will return the string \"Hi there.\".\r\n+     * <p/>\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param arg            The argument to be substituted in place of the formatting anchor\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple format(String messagePattern, Object arg) {\r\n+        return arrayFormat(messagePattern, new Object[]{arg});\r\n+    }\r\n+\r\n+    /**\r\n+     * Performs a two argument substitution for the 'messagePattern' passed as\r\n+     * parameter.\r\n+     * <p/>\r\n+     * For example,\r\n+     * <p/>\r\n+     * <pre>\r\n+     * MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);\r\n+     * </pre>\r\n+     * <p/>\r\n+     * will return the string \"Hi Alice. My name is Bob.\".\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param argA           The argument to be substituted in place of the first formatting\r\n+     *                       anchor\r\n+     * @param argB           The argument to be substituted in place of the second formatting\r\n+     *                       anchor\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple format(final String messagePattern,\r\n+                                  Object argA, Object argB) {\r\n+        return arrayFormat(messagePattern, new Object[]{argA, argB});\r\n+    }\r\n+\r\n+    static Throwable getThrowableCandidate(Object[] argArray) {\r\n+        if (ArrayUtils.isEmpty(argArray)) {\r\n+            return null;\r\n+        }\r\n+\r\n+        final Object lastEntry = argArray[argArray.length - 1];\r\n+        if (lastEntry instanceof Throwable) {\r\n+            return (Throwable) lastEntry;\r\n+        }\r\n+        return null;\r\n+    }\r\n+\r\n+    /**\r\n+     * Same principle as the {@link #format(String, Object)} and\r\n+     * {@link #format(String, Object, Object)} methods except that any number of\r\n+     * arguments can be passed in an array.\r\n+     *\r\n+     * @param messagePattern The message pattern which will be parsed and formatted\r\n+     * @param argArray       An array of arguments to be substituted in place of formatting\r\n+     *                       anchors\r\n+     * @return The formatted message\r\n+     */\r\n+    static FormattingTuple arrayFormat(final String messagePattern,\r\n+                                       final Object[] argArray) {\r\n+\r\n+        Throwable throwableCandidate = getThrowableCandidate(argArray);\r\n+\r\n+        if (messagePattern == null) {\r\n+            return new FormattingTuple(null, argArray, throwableCandidate);\r\n+        }\r\n+\r\n+        if (argArray == null) {\r\n+            return new FormattingTuple(messagePattern);\r\n+        }\r\n+\r\n+        int i = 0;\r\n+        int j;\r\n+        StringBuffer sbuf = new StringBuffer(messagePattern.length() + 50);\r\n+\r\n+        int l;\r\n+        for (l = 0; l < argArray.length; l++) {\r\n+\r\n+            j = messagePattern.indexOf(DELIM_STR, i);\r\n+\r\n+            if (j == -1) {\r\n+                // no more variables\r\n+                if (i == 0) { // this is a simple string\r\n+                    return new FormattingTuple(messagePattern, argArray,\r\n+                            throwableCandidate);\r\n+                } else { // add the tail string which contains no variables and return\r\n+                    // the result.\r\n+                    sbuf.append(messagePattern.substring(i));\r\n+                    return new FormattingTuple(sbuf.toString(), argArray,\r\n+                            throwableCandidate);\r\n+                }\r\n+            } else {\r\n+                if (isEscapedDelimiter(messagePattern, j)) {\r\n+                    if (!isDoubleEscaped(messagePattern, j)) {\r\n+                        l--; // DELIM_START was escaped, thus should not be incremented\r\n+                        sbuf.append(messagePattern, i, j - 1);\r\n+                        sbuf.append(DELIM_START);\r\n+                        i = j + 1;\r\n+                    } else {\r\n+                        // The escape character preceding the delimiter start is\r\n+                        // itself escaped: \"abc x:\\\\{}\"\r\n+                        // we have to consume one backward slash\r\n+                        sbuf.append(messagePattern, i, j - 1);\r\n+                        deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\r\n+                        i = j + 2;\r\n+                    }\r\n+                } else {\r\n+                    // normal case\r\n+                    sbuf.append(messagePattern, i, j);\r\n+                    deeplyAppendParameter(sbuf, argArray[l], new HashMap<Object[], Void>());\r\n+                    i = j + 2;\r\n+                }\r\n+            }\r\n+        }\r\n+        // append the characters following the last {} pair.\r\n+        sbuf.append(messagePattern.substring(i));\r\n+        if (l < argArray.length - 1) {\r\n+            return new FormattingTuple(sbuf.toString(), argArray, throwableCandidate);\r\n+        } else {\r\n+            return new FormattingTuple(sbuf.toString(), argArray, null);\r\n+        }\r\n+    }\r\n+\r\n+    static boolean isEscapedDelimiter(String messagePattern,\r\n+                                      int delimiterStartIndex) {\r\n+\r\n+        if (delimiterStartIndex == 0) {\r\n+            return false;\r\n+        }\r\n+        return messagePattern.charAt(delimiterStartIndex - 1) == ESCAPE_CHAR;\r\n+    }\r\n+\r\n+    static boolean isDoubleEscaped(String messagePattern,\r\n+                                   int delimiterStartIndex) {\r\n+        return delimiterStartIndex >= 2 && messagePattern.charAt(delimiterStartIndex - 2) == ESCAPE_CHAR;\r\n+    }\r\n+\r\n+    // special treatment of array values was suggested by 'lizongbo'\r\n+    private static void deeplyAppendParameter(StringBuffer sbuf, Object o,\r\n+                                              Map<Object[], Void> seenMap) {\r\n+        if (o == null) {\r\n+            sbuf.append(\"null\");\r\n+            return;\r\n+        }\r\n+        if (!o.getClass().isArray()) {\r\n+            safeObjectAppend(sbuf, o);\r\n+        } else {\r\n+            // check for primitive array types because they\r\n+            // unfortunately cannot be cast to Object[]\r\n+            if (o instanceof boolean[]) {\r\n+                booleanArrayAppend(sbuf, (boolean[]) o);\r\n+            } else if (o instanceof byte[]) {\r\n+                byteArrayAppend(sbuf, (byte[]) o);\r\n+            } else if (o instanceof char[]) {\r\n+                charArrayAppend(sbuf, (char[]) o);\r\n+            } else if (o instanceof short[]) {\r\n+                shortArrayAppend(sbuf, (short[]) o);\r\n+            } else if (o instanceof int[]) {\r\n+                intArrayAppend(sbuf, (int[]) o);\r\n+            } else if (o instanceof long[]) {\r\n+                longArrayAppend(sbuf, (long[]) o);\r\n+            } else if (o instanceof float[]) {\r\n+                floatArrayAppend(sbuf, (float[]) o);\r\n+            } else if (o instanceof double[]) {\r\n+                doubleArrayAppend(sbuf, (double[]) o);\r\n+            } else {\r\n+                objectArrayAppend(sbuf, (Object[]) o, seenMap);\r\n+            }\r\n+        }\r\n+    }\r\n+\r\n+    private static void safeObjectAppend(StringBuffer sbuf, Object o) {\r\n+        try {\r\n+            String oAsString = o.toString();\r\n+            sbuf.append(oAsString);\r\n+        } catch (Throwable t) {\r\n+            System.err\r\n+                    .println(\"SLF4J: Failed toString() invocation on an object of type [\"\r\n+                            + o.getClass().getName() + ']');\r\n+            logger.error(t.getMessage(), t);\r\n+            sbuf.append(\"[FAILED toString()]\");\r\n+        }\r\n+    }\r\n+\r\n+    private static void objectArrayAppend(StringBuffer sbuf, Object[] a,\r\n+                                          Map<Object[], Void> seenMap) {\r\n+        sbuf.append('[');\r\n+        if (!seenMap.containsKey(a)) {\r\n+            seenMap.put(a, null);\r\n+            final int len = a.length;\r\n+            for (int i = 0; i < len; i++) {\r\n+                deeplyAppendParameter(sbuf, a[i], seenMap);\r\n+                if (i != len - 1) {\r\n+                    sbuf.append(\", \");\r\n+                }\r\n+            }\r\n+            // allow repeats in siblings\r\n+            seenMap.remove(a);\r\n+        } else {\r\n+            sbuf.append(\"...\");\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void booleanArrayAppend(StringBuffer sbuf, boolean[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void byteArrayAppend(StringBuffer sbuf, byte[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void charArrayAppend(StringBuffer sbuf, char[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void shortArrayAppend(StringBuffer sbuf, short[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void intArrayAppend(StringBuffer sbuf, int[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void longArrayAppend(StringBuffer sbuf, long[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void floatArrayAppend(StringBuffer sbuf, float[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private static void doubleArrayAppend(StringBuffer sbuf, double[] a) {\r\n+        sbuf.append('[');\r\n+        final int len = a.length;\r\n+        for (int i = 0; i < len; i++) {\r\n+            sbuf.append(a[i]);\r\n+            if (i != len - 1) {\r\n+                sbuf.append(\", \");\r\n+            }\r\n+        }\r\n+        sbuf.append(']');\r\n+    }\r\n+\r\n+    private MessageFormatter() {\r\n+    }\r\n+}\r\n"}]}
