✨ 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
144 lines
3.5 KiB
JavaScript
144 lines
3.5 KiB
JavaScript
'use strict'
|
|
|
|
const ANY = Symbol('SemVer ANY')
|
|
// hoisted class for cyclic dependency
|
|
class Comparator {
|
|
static get ANY () {
|
|
return ANY
|
|
}
|
|
|
|
constructor (comp, options) {
|
|
options = parseOptions(options)
|
|
|
|
if (comp instanceof Comparator) {
|
|
if (comp.loose === !!options.loose) {
|
|
return comp
|
|
} else {
|
|
comp = comp.value
|
|
}
|
|
}
|
|
|
|
comp = comp.trim().split(/\s+/).join(' ')
|
|
debug('comparator', comp, options)
|
|
this.options = options
|
|
this.loose = !!options.loose
|
|
this.parse(comp)
|
|
|
|
if (this.semver === ANY) {
|
|
this.value = ''
|
|
} else {
|
|
this.value = this.operator + this.semver.version
|
|
}
|
|
|
|
debug('comp', this)
|
|
}
|
|
|
|
parse (comp) {
|
|
const r = this.options.loose ? re[t.COMPARATORLOOSE] : re[t.COMPARATOR]
|
|
const m = comp.match(r)
|
|
|
|
if (!m) {
|
|
throw new TypeError(`Invalid comparator: ${comp}`)
|
|
}
|
|
|
|
this.operator = m[1] !== undefined ? m[1] : ''
|
|
if (this.operator === '=') {
|
|
this.operator = ''
|
|
}
|
|
|
|
// if it literally is just '>' or '' then allow anything.
|
|
if (!m[2]) {
|
|
this.semver = ANY
|
|
} else {
|
|
this.semver = new SemVer(m[2], this.options.loose)
|
|
}
|
|
}
|
|
|
|
toString () {
|
|
return this.value
|
|
}
|
|
|
|
test (version) {
|
|
debug('Comparator.test', version, this.options.loose)
|
|
|
|
if (this.semver === ANY || version === ANY) {
|
|
return true
|
|
}
|
|
|
|
if (typeof version === 'string') {
|
|
try {
|
|
version = new SemVer(version, this.options)
|
|
} catch (er) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return cmp(version, this.operator, this.semver, this.options)
|
|
}
|
|
|
|
intersects (comp, options) {
|
|
if (!(comp instanceof Comparator)) {
|
|
throw new TypeError('a Comparator is required')
|
|
}
|
|
|
|
if (this.operator === '') {
|
|
if (this.value === '') {
|
|
return true
|
|
}
|
|
return new Range(comp.value, options).test(this.value)
|
|
} else if (comp.operator === '') {
|
|
if (comp.value === '') {
|
|
return true
|
|
}
|
|
return new Range(this.value, options).test(comp.semver)
|
|
}
|
|
|
|
options = parseOptions(options)
|
|
|
|
// Special cases where nothing can possibly be lower
|
|
if (options.includePrerelease &&
|
|
(this.value === '<0.0.0-0' || comp.value === '<0.0.0-0')) {
|
|
return false
|
|
}
|
|
if (!options.includePrerelease &&
|
|
(this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0'))) {
|
|
return false
|
|
}
|
|
|
|
// Same direction increasing (> or >=)
|
|
if (this.operator.startsWith('>') && comp.operator.startsWith('>')) {
|
|
return true
|
|
}
|
|
// Same direction decreasing (< or <=)
|
|
if (this.operator.startsWith('<') && comp.operator.startsWith('<')) {
|
|
return true
|
|
}
|
|
// same SemVer and both sides are inclusive (<= or >=)
|
|
if (
|
|
(this.semver.version === comp.semver.version) &&
|
|
this.operator.includes('=') && comp.operator.includes('=')) {
|
|
return true
|
|
}
|
|
// opposite directions less than
|
|
if (cmp(this.semver, '<', comp.semver, options) &&
|
|
this.operator.startsWith('>') && comp.operator.startsWith('<')) {
|
|
return true
|
|
}
|
|
// opposite directions greater than
|
|
if (cmp(this.semver, '>', comp.semver, options) &&
|
|
this.operator.startsWith('<') && comp.operator.startsWith('>')) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
module.exports = Comparator
|
|
|
|
const parseOptions = require('../internal/parse-options')
|
|
const { safeRe: re, t } = require('../internal/re')
|
|
const cmp = require('../functions/cmp')
|
|
const debug = require('../internal/debug')
|
|
const SemVer = require('./semver')
|
|
const Range = require('./range')
|