✨ 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
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
const keywords = require('./keywords');
|
|
const escapeHtml = require('./escapeHtml');
|
|
|
|
const DEFAULT_OPTIONS = {
|
|
html: false,
|
|
htmlEscaper: escapeHtml,
|
|
classPrefix: 'sql-hl-',
|
|
colors: {
|
|
keyword: '\x1b[35m',
|
|
function: '\x1b[31m',
|
|
number: '\x1b[32m',
|
|
string: '\x1b[32m',
|
|
identifier: '\x1b[0m',
|
|
special: '\x1b[33m',
|
|
bracket: '\x1b[33m',
|
|
comment: '\x1b[2m\x1b[90m',
|
|
clear: '\x1b[0m'
|
|
}
|
|
};
|
|
|
|
const highlighters = [
|
|
/(?<number>[+-]?(?:\d+\.\d+|\d+|\.\d+)(?:E[+-]?\d+)?)/,
|
|
|
|
// Note: Repeating string escapes like 'sql''server' will also work as they are just repeating strings
|
|
/(?<string>'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*")/,
|
|
|
|
/(?<comment>--[^\n\r]*|#[^\n\r]*|\/\*(?:[^*]|\*(?!\/))*\*\/)/,
|
|
|
|
// Future improvement: Comments should be allowed between the function name and the opening parenthesis
|
|
/\b(?<function>\w+)(?=\s*\()/,
|
|
|
|
/(?<bracket>[()])/,
|
|
|
|
/(?<identifier>\b\w+\b|`(?:[^`\\]|\\.)*`)/,
|
|
|
|
/(?<whitespace>\s+)/,
|
|
|
|
// Multi-character arithmetic, bitwise, comparison, and compound operators as listed in
|
|
// https://www.w3schools.com/sql/sql_operators.asp, https://www.tutorialspoint.com/sql/sql-operators.htm,
|
|
// https://data-flair.training/blogs/sql-operators/, plus any single character (in particular ,:;.) not matched by
|
|
// the above regexps.
|
|
/(?<special>\^-=|\|\*=|\+=|-=|\*=|\/=|%=|&=|>=|<=|<>|!=|!<|!>|>>|<<|.)/
|
|
];
|
|
|
|
// Regex of the shape /(?<token1>...)|(?<token2>...)|.../g
|
|
const tokenizer = new RegExp(
|
|
[
|
|
`\\b(?<keyword>${keywords.join('|')})\\b`,
|
|
...highlighters.map((regex) => regex.source)
|
|
].join('|'),
|
|
'gis'
|
|
);
|
|
|
|
function getSegments(sqlString) {
|
|
const segments = Array.from(sqlString.matchAll(tokenizer), (match) => ({
|
|
name: Object.keys(match.groups).find((key) => match.groups[key]),
|
|
content: match[0]
|
|
}));
|
|
return segments;
|
|
}
|
|
|
|
function highlight(sqlString, options) {
|
|
const fullOptions = Object.assign({}, DEFAULT_OPTIONS, options);
|
|
|
|
return getSegments(sqlString)
|
|
.map(({ name, content }) => {
|
|
if (fullOptions.html) {
|
|
const escapedContent = fullOptions.htmlEscaper(content);
|
|
return name === 'whitespace'
|
|
? escapedContent
|
|
: `<span class="${fullOptions.classPrefix}${name}">${escapedContent}</span>`;
|
|
}
|
|
if (fullOptions.colors[name]) {
|
|
return fullOptions.colors[name] + content + fullOptions.colors.clear;
|
|
}
|
|
return content;
|
|
})
|
|
.join('');
|
|
}
|
|
|
|
module.exports = {
|
|
getSegments,
|
|
highlight,
|
|
DEFAULT_OPTIONS
|
|
};
|