- 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
177 lines
4.1 KiB
JavaScript
Executable File
177 lines
4.1 KiB
JavaScript
Executable File
'use strict';
|
|
|
|
const Reach = require('./reach');
|
|
const Types = require('./types');
|
|
const Utils = require('./utils');
|
|
|
|
|
|
const internals = {
|
|
needsProtoHack: new Set([Types.set, Types.map, Types.weakSet, Types.weakMap])
|
|
};
|
|
|
|
|
|
module.exports = internals.clone = function (obj, options = {}, _seen = null) {
|
|
|
|
if (typeof obj !== 'object' ||
|
|
obj === null) {
|
|
|
|
return obj;
|
|
}
|
|
|
|
let clone = internals.clone;
|
|
let seen = _seen;
|
|
|
|
if (options.shallow) {
|
|
if (options.shallow !== true) {
|
|
return internals.cloneWithShallow(obj, options);
|
|
}
|
|
|
|
clone = (value) => value;
|
|
}
|
|
else if (seen) {
|
|
const lookup = seen.get(obj);
|
|
if (lookup) {
|
|
return lookup;
|
|
}
|
|
}
|
|
else {
|
|
seen = new Map();
|
|
}
|
|
|
|
// Built-in object types
|
|
|
|
const baseProto = Types.getInternalProto(obj);
|
|
if (baseProto === Types.buffer) {
|
|
return Buffer && Buffer.from(obj); // $lab:coverage:ignore$
|
|
}
|
|
|
|
if (baseProto === Types.date) {
|
|
return new Date(obj.getTime());
|
|
}
|
|
|
|
if (baseProto === Types.regex) {
|
|
return new RegExp(obj);
|
|
}
|
|
|
|
// Generic objects
|
|
|
|
const newObj = internals.base(obj, baseProto, options);
|
|
if (newObj === obj) {
|
|
return obj;
|
|
}
|
|
|
|
if (seen) {
|
|
seen.set(obj, newObj); // Set seen, since obj could recurse
|
|
}
|
|
|
|
if (baseProto === Types.set) {
|
|
for (const value of obj) {
|
|
newObj.add(clone(value, options, seen));
|
|
}
|
|
}
|
|
else if (baseProto === Types.map) {
|
|
for (const [key, value] of obj) {
|
|
newObj.set(key, clone(value, options, seen));
|
|
}
|
|
}
|
|
|
|
const keys = Utils.keys(obj, options);
|
|
for (const key of keys) {
|
|
if (key === '__proto__') {
|
|
continue;
|
|
}
|
|
|
|
if (baseProto === Types.array &&
|
|
key === 'length') {
|
|
|
|
newObj.length = obj.length;
|
|
continue;
|
|
}
|
|
|
|
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
if (descriptor) {
|
|
if (descriptor.get ||
|
|
descriptor.set) {
|
|
|
|
Object.defineProperty(newObj, key, descriptor);
|
|
}
|
|
else if (descriptor.enumerable) {
|
|
newObj[key] = clone(obj[key], options, seen);
|
|
}
|
|
else {
|
|
Object.defineProperty(newObj, key, { enumerable: false, writable: true, configurable: true, value: clone(obj[key], options, seen) });
|
|
}
|
|
}
|
|
else {
|
|
Object.defineProperty(newObj, key, {
|
|
enumerable: true,
|
|
writable: true,
|
|
configurable: true,
|
|
value: clone(obj[key], options, seen)
|
|
});
|
|
}
|
|
}
|
|
|
|
return newObj;
|
|
};
|
|
|
|
|
|
internals.cloneWithShallow = function (source, options) {
|
|
|
|
const keys = options.shallow;
|
|
options = Object.assign({}, options);
|
|
options.shallow = false;
|
|
|
|
const seen = new Map();
|
|
|
|
for (const key of keys) {
|
|
const ref = Reach(source, key);
|
|
if (typeof ref === 'object' ||
|
|
typeof ref === 'function') {
|
|
|
|
seen.set(ref, ref);
|
|
}
|
|
}
|
|
|
|
return internals.clone(source, options, seen);
|
|
};
|
|
|
|
|
|
internals.base = function (obj, baseProto, options) {
|
|
|
|
if (options.prototype === false) { // Defaults to true
|
|
if (internals.needsProtoHack.has(baseProto)) {
|
|
return new baseProto.constructor();
|
|
}
|
|
|
|
return baseProto === Types.array ? [] : {};
|
|
}
|
|
|
|
const proto = Object.getPrototypeOf(obj);
|
|
if (proto &&
|
|
proto.isImmutable) {
|
|
|
|
return obj;
|
|
}
|
|
|
|
if (baseProto === Types.array) {
|
|
const newObj = [];
|
|
if (proto !== baseProto) {
|
|
Object.setPrototypeOf(newObj, proto);
|
|
}
|
|
|
|
return newObj;
|
|
}
|
|
|
|
if (internals.needsProtoHack.has(baseProto)) {
|
|
const newObj = new proto.constructor();
|
|
if (proto !== baseProto) {
|
|
Object.setPrototypeOf(newObj, proto);
|
|
}
|
|
|
|
return newObj;
|
|
}
|
|
|
|
return Object.create(proto);
|
|
};
|