✨ MAJOR FEATURES: • Auto-zoom intelligence với smart bounds fitting • Enhanced 3D GPS markers với pulsing effects • Professional route display với 6-layer rendering • Status-based parking icons với availability indicators • Production-ready build optimizations 🗺️ AUTO-ZOOM FEATURES: • Smart bounds fitting cho GPS + selected parking • Adaptive padding (50px) cho visual balance • Max zoom control (level 16) để tránh quá gần • Dynamic centering khi không có selection 🎨 ENHANCED VISUALS: • 3D GPS marker với multi-layer pulse effects • Advanced parking icons với status colors • Selection highlighting với animation • Dimming system cho non-selected items 🛣️ ROUTE SYSTEM: • OpenRouteService API integration • Multi-layer route rendering (glow, shadow, main, animated) • Real-time distance & duration calculation • Visual route info trong popup 📱 PRODUCTION READY: • SSR safe với dynamic imports • Build errors resolved • Global deployment via Vercel • Optimized performance 🌍 DEPLOYMENT: • Vercel: https://whatever-ctk2auuxr-phong12hexdockworks-projects.vercel.app • Bundle size: 22.8 kB optimized • Global CDN distribution • HTTPS enabled 💾 VERSION CONTROL: • MapView-v2.0.tsx backup created • MAPVIEW_VERSIONS.md documentation • Full version history tracking
119 lines
4.8 KiB
JavaScript
119 lines
4.8 KiB
JavaScript
/**
|
|
* Ref https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
|
|
*/
|
|
import { UINT16_LE, UINT32_LE } from "token-types";
|
|
export const Signature = {
|
|
LocalFileHeader: 0x04034b50,
|
|
DataDescriptor: 0x08074b50,
|
|
CentralFileHeader: 0x02014b50,
|
|
EndOfCentralDirectory: 0x06054b50
|
|
};
|
|
export const DataDescriptor = {
|
|
get(array) {
|
|
const flags = UINT16_LE.get(array, 6);
|
|
return {
|
|
signature: UINT32_LE.get(array, 0),
|
|
compressedSize: UINT32_LE.get(array, 8),
|
|
uncompressedSize: UINT32_LE.get(array, 12),
|
|
};
|
|
}, len: 16
|
|
};
|
|
/**
|
|
* First part of the ZIP Local File Header
|
|
* Offset | Bytes| Description
|
|
* -------|------+-------------------------------------------------------------------
|
|
* 0 | 4 | Signature (0x04034b50)
|
|
* 4 | 2 | Minimum version needed to extract
|
|
* 6 | 2 | Bit flag
|
|
* 8 | 2 | Compression method
|
|
* 10 | 2 | File last modification time (MS-DOS format)
|
|
* 12 | 2 | File last modification date (MS-DOS format)
|
|
* 14 | 4 | CRC-32 of uncompressed data
|
|
* 18 | 4 | Compressed size
|
|
* 22 | 4 | Uncompressed size
|
|
* 26 | 2 | File name length (n)
|
|
* 28 | 2 | Extra field length (m)
|
|
* 30 | n | File name
|
|
* 30 + n | m | Extra field
|
|
*/
|
|
export const LocalFileHeaderToken = {
|
|
get(array) {
|
|
const flags = UINT16_LE.get(array, 6);
|
|
return {
|
|
signature: UINT32_LE.get(array, 0),
|
|
minVersion: UINT16_LE.get(array, 4),
|
|
dataDescriptor: !!(flags & 0x0008),
|
|
compressedMethod: UINT16_LE.get(array, 8),
|
|
compressedSize: UINT32_LE.get(array, 18),
|
|
uncompressedSize: UINT32_LE.get(array, 22),
|
|
filenameLength: UINT16_LE.get(array, 26),
|
|
extraFieldLength: UINT16_LE.get(array, 28),
|
|
filename: null
|
|
};
|
|
}, len: 30
|
|
};
|
|
/**
|
|
* 4.3.16 End of central directory record:
|
|
* end of central dir signature (0x06064b50) 4 bytes
|
|
* number of this disk 2 bytes
|
|
* number of the disk with the start of the central directory 2 bytes
|
|
* total number of entries in the central directory on this disk 2 bytes
|
|
* total number of entries in the size of the central directory 2 bytes
|
|
* sizeOfTheCentralDirectory 4 bytes
|
|
* offset of start of central directory with respect to the starting disk number 4 bytes
|
|
* .ZIP file comment length 2 bytes
|
|
* .ZIP file comment (variable size)
|
|
*/
|
|
export const EndOfCentralDirectoryRecordToken = {
|
|
get(array) {
|
|
return {
|
|
signature: UINT32_LE.get(array, 0),
|
|
nrOfThisDisk: UINT16_LE.get(array, 4),
|
|
nrOfThisDiskWithTheStart: UINT16_LE.get(array, 6),
|
|
nrOfEntriesOnThisDisk: UINT16_LE.get(array, 8),
|
|
nrOfEntriesOfSize: UINT16_LE.get(array, 10),
|
|
sizeOfCd: UINT32_LE.get(array, 12),
|
|
offsetOfStartOfCd: UINT32_LE.get(array, 16),
|
|
zipFileCommentLength: UINT16_LE.get(array, 20),
|
|
};
|
|
}, len: 22
|
|
};
|
|
/**
|
|
* File header:
|
|
* central file header signature 4 bytes 0 (0x02014b50)
|
|
* version made by 2 bytes 4
|
|
* version needed to extract 2 bytes 6
|
|
* general purpose bit flag 2 bytes 8
|
|
* compression method 2 bytes 10
|
|
* last mod file time 2 bytes 12
|
|
* last mod file date 2 bytes 14
|
|
* crc-32 4 bytes 16
|
|
* compressed size 4 bytes 20
|
|
* uncompressed size 4 bytes 24
|
|
* file name length 2 bytes 28
|
|
* extra field length 2 bytes 30
|
|
* file comment length 2 bytes 32
|
|
* disk number start 2 bytes 34
|
|
* internal file attributes 2 bytes 36
|
|
* external file attributes 4 bytes 38
|
|
* relative offset of local header 4 bytes 42
|
|
*/
|
|
export const FileHeader = {
|
|
get(array) {
|
|
const flags = UINT16_LE.get(array, 8);
|
|
return {
|
|
signature: UINT32_LE.get(array, 0),
|
|
minVersion: UINT16_LE.get(array, 6),
|
|
dataDescriptor: !!(flags & 0x0008),
|
|
compressedMethod: UINT16_LE.get(array, 10),
|
|
compressedSize: UINT32_LE.get(array, 20),
|
|
uncompressedSize: UINT32_LE.get(array, 24),
|
|
filenameLength: UINT16_LE.get(array, 28),
|
|
extraFieldLength: UINT16_LE.get(array, 30),
|
|
fileCommentLength: UINT16_LE.get(array, 32),
|
|
relativeOffsetOfLocalHeader: UINT32_LE.get(array, 42),
|
|
filename: null
|
|
};
|
|
}, len: 46
|
|
};
|