- App.tsx: full navigation (Auth stack + Main tabs with 5 screens) - Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen - HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors - MapScreen: interactive map with layer toggles (6 layers) - MarketplaceScreen: categories (6), products (5), search - ChatScreen: AI chat with quick prompts (4), bot responses - ProfileScreen: user info, stats, menu (9 items), logout - AlertsScreen: alert list with severity, acknowledge - SensorsScreen: sensor list with type filters (6 types), search - ZonesScreen: zone cards with stats - SettingsScreen: language picker (FR/EN/ES/DE), privacy, about - Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n - Hooks: useSensors, useAlerts, useNotifications, useLocation - Components: Card, Button, LoadingSpinner, ErrorBoundary, Header - Services: iotService, notificationService (with axios API client) - Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN) - Theme: colors.ts with full design system (Blue Ocean palette) - Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
105 lines
2.2 KiB
JavaScript
105 lines
2.2 KiB
JavaScript
'use strict'
|
|
// Tar can encode large and negative numbers using a leading byte of
|
|
// 0xff for negative, and 0x80 for positive.
|
|
|
|
const encode = (num, buf) => {
|
|
if (!Number.isSafeInteger(num)) {
|
|
// The number is so large that javascript cannot represent it with integer
|
|
// precision.
|
|
throw Error('cannot encode number outside of javascript safe integer range')
|
|
} else if (num < 0) {
|
|
encodeNegative(num, buf)
|
|
} else {
|
|
encodePositive(num, buf)
|
|
}
|
|
return buf
|
|
}
|
|
|
|
const encodePositive = (num, buf) => {
|
|
buf[0] = 0x80
|
|
|
|
for (var i = buf.length; i > 1; i--) {
|
|
buf[i - 1] = num & 0xff
|
|
num = Math.floor(num / 0x100)
|
|
}
|
|
}
|
|
|
|
const encodeNegative = (num, buf) => {
|
|
buf[0] = 0xff
|
|
var flipped = false
|
|
num = num * -1
|
|
for (var i = buf.length; i > 1; i--) {
|
|
var byte = num & 0xff
|
|
num = Math.floor(num / 0x100)
|
|
if (flipped) {
|
|
buf[i - 1] = onesComp(byte)
|
|
} else if (byte === 0) {
|
|
buf[i - 1] = 0
|
|
} else {
|
|
flipped = true
|
|
buf[i - 1] = twosComp(byte)
|
|
}
|
|
}
|
|
}
|
|
|
|
const parse = (buf) => {
|
|
const pre = buf[0]
|
|
const value = pre === 0x80 ? pos(buf.slice(1, buf.length))
|
|
: pre === 0xff ? twos(buf)
|
|
: null
|
|
if (value === null) {
|
|
throw Error('invalid base256 encoding')
|
|
}
|
|
|
|
if (!Number.isSafeInteger(value)) {
|
|
// The number is so large that javascript cannot represent it with integer
|
|
// precision.
|
|
throw Error('parsed number outside of javascript safe integer range')
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
const twos = (buf) => {
|
|
var len = buf.length
|
|
var sum = 0
|
|
var flipped = false
|
|
for (var i = len - 1; i > -1; i--) {
|
|
var byte = buf[i]
|
|
var f
|
|
if (flipped) {
|
|
f = onesComp(byte)
|
|
} else if (byte === 0) {
|
|
f = byte
|
|
} else {
|
|
flipped = true
|
|
f = twosComp(byte)
|
|
}
|
|
if (f !== 0) {
|
|
sum -= f * Math.pow(256, len - i - 1)
|
|
}
|
|
}
|
|
return sum
|
|
}
|
|
|
|
const pos = (buf) => {
|
|
var len = buf.length
|
|
var sum = 0
|
|
for (var i = len - 1; i > -1; i--) {
|
|
var byte = buf[i]
|
|
if (byte !== 0) {
|
|
sum += byte * Math.pow(256, len - i - 1)
|
|
}
|
|
}
|
|
return sum
|
|
}
|
|
|
|
const onesComp = byte => (0xff ^ byte) & 0xff
|
|
|
|
const twosComp = byte => ((0xff ^ byte) + 1) & 0xff
|
|
|
|
module.exports = {
|
|
encode,
|
|
parse,
|
|
}
|