adust pcb to new 3.3 software improvements
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "board": {
 | 
					  "board": {
 | 
				
			||||||
    "active_layer": 1,
 | 
					    "active_layer": 0,
 | 
				
			||||||
    "active_layer_preset": "",
 | 
					    "active_layer_preset": "",
 | 
				
			||||||
    "auto_track_width": false,
 | 
					    "auto_track_width": false,
 | 
				
			||||||
    "hidden_netclasses": [],
 | 
					    "hidden_netclasses": [],
 | 
				
			||||||
@@ -68,7 +68,7 @@
 | 
				
			|||||||
      39,
 | 
					      39,
 | 
				
			||||||
      40
 | 
					      40
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
    "visible_layers": "ffc7fff_ffffffff",
 | 
					    "visible_layers": "ffc35ba_ffffffff",
 | 
				
			||||||
    "zone_display_mode": 1
 | 
					    "zone_display_mode": 1
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "git": {
 | 
					  "git": {
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -10,11 +10,7 @@ use chrono_tz::{Europe::Berlin, Tz};
 | 
				
			|||||||
use config::Mode;
 | 
					use config::Mode;
 | 
				
			||||||
use esp_idf_hal::delay::Delay;
 | 
					use esp_idf_hal::delay::Delay;
 | 
				
			||||||
use esp_idf_sys::{
 | 
					use esp_idf_sys::{
 | 
				
			||||||
    esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition,
 | 
					    esp_deep_sleep, esp_ota_get_app_partition_count, esp_ota_get_running_partition, esp_ota_get_state_partition, esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED, esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW, esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED, esp_ota_img_states_t_ESP_OTA_IMG_VALID, esp_restart, esp_sleep_enable_ext1_wakeup, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW, vTaskDelay, CONFIG_FREERTOS_HZ
 | 
				
			||||||
    esp_ota_get_state_partition, esp_ota_img_states_t, esp_ota_img_states_t_ESP_OTA_IMG_ABORTED,
 | 
					 | 
				
			||||||
    esp_ota_img_states_t_ESP_OTA_IMG_INVALID, esp_ota_img_states_t_ESP_OTA_IMG_NEW,
 | 
					 | 
				
			||||||
    esp_ota_img_states_t_ESP_OTA_IMG_PENDING_VERIFY, esp_ota_img_states_t_ESP_OTA_IMG_UNDEFINED,
 | 
					 | 
				
			||||||
    esp_ota_img_states_t_ESP_OTA_IMG_VALID, esp_restart, vTaskDelay, CONFIG_FREERTOS_HZ,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use log::error;
 | 
					use log::error;
 | 
				
			||||||
use once_cell::sync::Lazy;
 | 
					use once_cell::sync::Lazy;
 | 
				
			||||||
@@ -126,16 +122,6 @@ struct PlantStateMQTT<'a> {
 | 
				
			|||||||
    last_pump: &'a str,
 | 
					    last_pump: &'a str,
 | 
				
			||||||
    next_pump: &'a str,
 | 
					    next_pump: &'a str,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#[derive(Serialize)]
 | 
					 | 
				
			||||||
struct BatteryState<'a> {
 | 
					 | 
				
			||||||
    voltage_milli_volt: &'a str,
 | 
					 | 
				
			||||||
    current_milli_ampere: &'a str,
 | 
					 | 
				
			||||||
    cycle_count: &'a str,
 | 
					 | 
				
			||||||
    design_milli_ampere: &'a str,
 | 
					 | 
				
			||||||
    remaining_milli_ampere: &'a str,
 | 
					 | 
				
			||||||
    state_of_charge: &'a str,
 | 
					 | 
				
			||||||
    state_of_health: &'a str,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn safe_main() -> anyhow::Result<()> {
 | 
					fn safe_main() -> anyhow::Result<()> {
 | 
				
			||||||
    // It is necessary to call this function once. Otherwise some patches to the runtime
 | 
					    // It is necessary to call this function once. Otherwise some patches to the runtime
 | 
				
			||||||
@@ -155,11 +141,12 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    log::info!("Startup Rust");
 | 
					    log::info!("Startup Rust");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let git_hash = env!("VERGEN_GIT_DESCRIBE");
 | 
					    let mut to_config = false;
 | 
				
			||||||
    let build_timestamp = env!("VERGEN_BUILD_TIMESTAMP");
 | 
					
 | 
				
			||||||
 | 
					    let version = get_version();
 | 
				
			||||||
    println!(
 | 
					    println!(
 | 
				
			||||||
        "Version useing git has {} build on {}",
 | 
					        "Version useing git has {} build on {}",
 | 
				
			||||||
        git_hash, build_timestamp
 | 
					        version.git_hash, version.build_time
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let count = unsafe { esp_ota_get_app_partition_count() };
 | 
					    let count = unsafe { esp_ota_get_app_partition_count() };
 | 
				
			||||||
@@ -192,6 +179,7 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
    println!("Board hal init");
 | 
					    println!("Board hal init");
 | 
				
			||||||
    let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
 | 
					    let mut board: std::sync::MutexGuard<'_, PlantCtrlBoard<'_>> = BOARD_ACCESS.lock().unwrap();
 | 
				
			||||||
    board.general_fault(false);
 | 
					    board.general_fault(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    println!("Mounting filesystem");
 | 
					    println!("Mounting filesystem");
 | 
				
			||||||
    board.mount_file_system()?;
 | 
					    board.mount_file_system()?;
 | 
				
			||||||
    let free_space = board.file_system_size()?;
 | 
					    let free_space = board.file_system_size()?;
 | 
				
			||||||
@@ -232,8 +220,18 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    println!("cur is {}", cur);
 | 
					    println!("cur is {}", cur);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut to_config = false;
 | 
					    if board.get_restart_to_conf() {
 | 
				
			||||||
    if board.is_mode_override() {
 | 
					        println!("config mode software override");
 | 
				
			||||||
 | 
					        for _i in 0..2 {
 | 
				
			||||||
 | 
					            board.general_fault(true);
 | 
				
			||||||
 | 
					            Delay::new_default().delay_ms(100);
 | 
				
			||||||
 | 
					            board.general_fault(false);
 | 
				
			||||||
 | 
					            Delay::new_default().delay_ms(100);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        to_config = true;
 | 
				
			||||||
 | 
					        board.general_fault(true);
 | 
				
			||||||
 | 
					        board.set_restart_to_conf(false);
 | 
				
			||||||
 | 
					    } else if board.is_mode_override() {
 | 
				
			||||||
        board.general_fault(true);
 | 
					        board.general_fault(true);
 | 
				
			||||||
        println!("config mode override is pressed, waiting 5s");
 | 
					        println!("config mode override is pressed, waiting 5s");
 | 
				
			||||||
        for _i in 0..5 {
 | 
					        for _i in 0..5 {
 | 
				
			||||||
@@ -244,12 +242,16 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if board.is_mode_override() {
 | 
					        if board.is_mode_override() {
 | 
				
			||||||
 | 
					            board.general_fault(true);
 | 
				
			||||||
            to_config = true;
 | 
					            to_config = true;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            board.general_fault(false);
 | 
					            board.general_fault(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        println!("No config override start detected");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let config: PlantControllerConfig;
 | 
					    let config: PlantControllerConfig;
 | 
				
			||||||
    match board.get_config() {
 | 
					    match board.get_config() {
 | 
				
			||||||
        Ok(valid) => {
 | 
					        Ok(valid) => {
 | 
				
			||||||
@@ -293,7 +295,7 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
                        board.general_fault(true);
 | 
					                        board.general_fault(true);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if (config.network.mqtt_url.is_some()) {
 | 
					                if config.network.mqtt_url.is_some() {
 | 
				
			||||||
                    match board.mqtt(&config) {
 | 
					                    match board.mqtt(&config) {
 | 
				
			||||||
                        Ok(_) => {
 | 
					                        Ok(_) => {
 | 
				
			||||||
                            println!("Mqtt connection ready");
 | 
					                            println!("Mqtt connection ready");
 | 
				
			||||||
@@ -338,8 +340,12 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
    if mqtt {
 | 
					    if mqtt {
 | 
				
			||||||
        let ip_string = ip_address.unwrap_or("N/A".to_owned());
 | 
					        let ip_string = ip_address.unwrap_or("N/A".to_owned());
 | 
				
			||||||
        let _ = board.mqtt_publish(&config, "/firmware/address", ip_string.as_bytes());
 | 
					        let _ = board.mqtt_publish(&config, "/firmware/address", ip_string.as_bytes());
 | 
				
			||||||
        let _ = board.mqtt_publish(&config, "/firmware/githash", git_hash.as_bytes());
 | 
					        let _ = board.mqtt_publish(&config, "/firmware/githash", version.git_hash.as_bytes());
 | 
				
			||||||
        let _ = board.mqtt_publish(&config, "/firmware/buildtime", build_timestamp.as_bytes());
 | 
					        let _ = board.mqtt_publish(
 | 
				
			||||||
 | 
					            &config,
 | 
				
			||||||
 | 
					            "/firmware/buildtime",
 | 
				
			||||||
 | 
					            version.build_time.as_bytes(),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
        let _ = board.mqtt_publish(
 | 
					        let _ = board.mqtt_publish(
 | 
				
			||||||
            &config,
 | 
					            &config,
 | 
				
			||||||
            "/firmware/last_online",
 | 
					            "/firmware/last_online",
 | 
				
			||||||
@@ -425,6 +431,7 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed);
 | 
					    let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let stay_alive = stay_alive_mqtt;
 | 
					    let stay_alive = stay_alive_mqtt;
 | 
				
			||||||
    println!("Check stay alive, current state is {}", stay_alive);
 | 
					    println!("Check stay alive, current state is {}", stay_alive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -550,23 +557,17 @@ fn safe_main() -> anyhow::Result<()> {
 | 
				
			|||||||
        let _webserver = httpd(reboot_now.clone());
 | 
					        let _webserver = httpd(reboot_now.clone());
 | 
				
			||||||
        wait_infinity(WaitType::MqttConfig, reboot_now.clone());
 | 
					        wait_infinity(WaitType::MqttConfig, reboot_now.clone());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    unsafe { 
 | 
				
			||||||
    unsafe { esp_deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64) };
 | 
					        esp_sleep_enable_ext1_wakeup(0b10u64, esp_sleep_ext1_wakeup_mode_t_ESP_EXT1_WAKEUP_ANY_LOW);
 | 
				
			||||||
 | 
					        esp_deep_sleep(1000 * 1000 * 60 * deep_sleep_duration_minutes as u64) 
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn publish_battery_state(
 | 
					fn publish_battery_state(
 | 
				
			||||||
    board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
 | 
					    board: &mut std::sync::MutexGuard<'_, PlantCtrlBoard<'_>>,
 | 
				
			||||||
    config: &PlantControllerConfig,
 | 
					    config: &PlantControllerConfig,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let bat = BatteryState {
 | 
					    let bat = board.get_battery_state();
 | 
				
			||||||
        voltage_milli_volt: &to_string(&board.voltage_milli_volt()),
 | 
					 | 
				
			||||||
        current_milli_ampere: &to_string(&board.average_current_milli_ampere()),
 | 
					 | 
				
			||||||
        cycle_count: &to_string(&board.cycle_count()),
 | 
					 | 
				
			||||||
        design_milli_ampere: &to_string(&board.design_milli_ampere_hour()),
 | 
					 | 
				
			||||||
        remaining_milli_ampere: &to_string(&board.remaining_milli_ampere_hour()),
 | 
					 | 
				
			||||||
        state_of_charge: &to_string(&board.state_charge_percent()),
 | 
					 | 
				
			||||||
        state_of_health: &to_string(&board.state_health_percent()),
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    match serde_json::to_string(&bat) {
 | 
					    match serde_json::to_string(&bat) {
 | 
				
			||||||
        Ok(state) => {
 | 
					        Ok(state) => {
 | 
				
			||||||
            let _ = board.mqtt_publish(&config, "/battery", state.as_bytes());
 | 
					            let _ = board.mqtt_publish(&config, "/battery", state.as_bytes());
 | 
				
			||||||
@@ -1005,7 +1006,7 @@ fn sensor_to_string(value: &Option<u8>, error: &Option<SensorError>, enabled: bo
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn to_string<T: Display>(value: &Result<T>) -> String {
 | 
					fn to_string<T: Display>(value: Result<T>) -> String {
 | 
				
			||||||
    return match value {
 | 
					    return match value {
 | 
				
			||||||
        Ok(v) => v.to_string(),
 | 
					        Ok(v) => v.to_string(),
 | 
				
			||||||
        Err(err) => {
 | 
					        Err(err) => {
 | 
				
			||||||
@@ -1054,3 +1055,19 @@ fn in_time_range(cur: &DateTime<Tz>, start: u8, end: u8) -> bool {
 | 
				
			|||||||
        return curhour > start || curhour < end;
 | 
					        return curhour > start || curhour < end;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn get_version() -> VersionInfo {
 | 
				
			||||||
 | 
					    let branch = env!("VERGEN_GIT_BRANCH").to_owned();
 | 
				
			||||||
 | 
					    let hash = &env!("VERGEN_GIT_SHA")[0..8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return VersionInfo {
 | 
				
			||||||
 | 
					        git_hash: (branch + "@" + hash),
 | 
				
			||||||
 | 
					        build_time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize, Debug)]
 | 
				
			||||||
 | 
					struct VersionInfo {
 | 
				
			||||||
 | 
					    git_hash: String,
 | 
				
			||||||
 | 
					    build_time: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,7 +53,7 @@ use esp_idf_sys::{esp, esp_spiffs_check, gpio_hold_dis, gpio_hold_en, vTaskDelay
 | 
				
			|||||||
use one_wire_bus::OneWire;
 | 
					use one_wire_bus::OneWire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::config::{self, PlantControllerConfig};
 | 
					use crate::config::{self, PlantControllerConfig};
 | 
				
			||||||
use crate::{plant_hal, STAY_ALIVE};
 | 
					use crate::{plant_hal, to_string, STAY_ALIVE};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//Only support for 8 right now!
 | 
					//Only support for 8 right now!
 | 
				
			||||||
pub const PLANT_COUNT: usize = 8;
 | 
					pub const PLANT_COUNT: usize = 8;
 | 
				
			||||||
@@ -117,6 +117,9 @@ static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT];
 | 
				
			|||||||
#[link_section = ".rtc.data"]
 | 
					#[link_section = ".rtc.data"]
 | 
				
			||||||
static mut LOW_VOLTAGE_DETECTED: bool = false;
 | 
					static mut LOW_VOLTAGE_DETECTED: bool = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[link_section = ".rtc.data"]
 | 
				
			||||||
 | 
					static mut RESTART_TO_CONF: bool = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct FileSystemSizeInfo {
 | 
					pub struct FileSystemSizeInfo {
 | 
				
			||||||
    pub total_size: usize,
 | 
					    pub total_size: usize,
 | 
				
			||||||
    pub used_size: usize,
 | 
					    pub used_size: usize,
 | 
				
			||||||
@@ -180,7 +183,33 @@ pub struct FileList {
 | 
				
			|||||||
    iter_error: Option<String>,
 | 
					    iter_error: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize)]
 | 
				
			||||||
 | 
					pub struct BatteryState {
 | 
				
			||||||
 | 
					    voltage_milli_volt: String,
 | 
				
			||||||
 | 
					    current_milli_ampere: String,
 | 
				
			||||||
 | 
					    cycle_count: String,
 | 
				
			||||||
 | 
					    design_milli_ampere: String,
 | 
				
			||||||
 | 
					    remaining_milli_ampere: String,
 | 
				
			||||||
 | 
					    state_of_charge: String,
 | 
				
			||||||
 | 
					    state_of_health: String,
 | 
				
			||||||
 | 
					    temperature: String,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl PlantCtrlBoard<'_> {
 | 
					impl PlantCtrlBoard<'_> {
 | 
				
			||||||
 | 
					    pub fn get_battery_state(&mut self) -> BatteryState {
 | 
				
			||||||
 | 
					        let bat = BatteryState {
 | 
				
			||||||
 | 
					            voltage_milli_volt: to_string(self.voltage_milli_volt()),
 | 
				
			||||||
 | 
					            current_milli_ampere: to_string(self.average_current_milli_ampere()),
 | 
				
			||||||
 | 
					            cycle_count: to_string(self.cycle_count()),
 | 
				
			||||||
 | 
					            design_milli_ampere: to_string(self.design_milli_ampere_hour()),
 | 
				
			||||||
 | 
					            remaining_milli_ampere: to_string(self.remaining_milli_ampere_hour()),
 | 
				
			||||||
 | 
					            state_of_charge: to_string(self.state_charge_percent()),
 | 
				
			||||||
 | 
					            state_of_health: to_string(self.state_health_percent()),
 | 
				
			||||||
 | 
					            temperature: to_string(self.bat_temperature()),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        return bat;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn list_files(&self, filename: &str) -> FileList {
 | 
					    pub fn list_files(&self, filename: &str) -> FileList {
 | 
				
			||||||
        let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
 | 
					        let storage = CString::new(SPIFFS_PARTITION_NAME).unwrap();
 | 
				
			||||||
        let error = unsafe {
 | 
					        let error = unsafe {
 | 
				
			||||||
@@ -956,6 +985,16 @@ impl PlantCtrlBoard<'_> {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_restart_to_conf(&mut self) -> bool {
 | 
				
			||||||
 | 
					        return unsafe { RESTART_TO_CONF };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    pub fn set_restart_to_conf(&mut self, to_conf: bool) {
 | 
				
			||||||
 | 
					        unsafe {
 | 
				
			||||||
 | 
					            RESTART_TO_CONF = to_conf;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn state_charge_percent(&mut self) -> Result<u8> {
 | 
					    pub fn state_charge_percent(&mut self) -> Result<u8> {
 | 
				
			||||||
        match self.battery_driver.state_of_charge() {
 | 
					        match self.battery_driver.state_of_charge() {
 | 
				
			||||||
            OkStd(r) => Ok(r),
 | 
					            OkStd(r) => Ok(r),
 | 
				
			||||||
@@ -1012,6 +1051,13 @@ impl PlantCtrlBoard<'_> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn bat_temperature(&mut self) -> Result<u16> {
 | 
				
			||||||
 | 
					        match self.battery_driver.temperature() {
 | 
				
			||||||
 | 
					            OkStd(r) => Ok(r as u16),
 | 
				
			||||||
 | 
					            Err(err) => bail!("Error reading Temperature {:?}", err),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()> {
 | 
					    pub fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()> {
 | 
				
			||||||
        match self.battery_driver.write_flash_stream_i2c(line, dryrun) {
 | 
					        match self.battery_driver.write_flash_stream_i2c(line, dryrun) {
 | 
				
			||||||
            OkStd(r) => Ok(r),
 | 
					            OkStd(r) => Ok(r),
 | 
				
			||||||
@@ -1193,32 +1239,60 @@ impl PlantHal {
 | 
				
			|||||||
        ms4.set_high()?;
 | 
					        ms4.set_high()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //init,reset rtc memory depending on cause
 | 
					        //init,reset rtc memory depending on cause
 | 
				
			||||||
 | 
					        let mut init_rtc_store: bool = false;
 | 
				
			||||||
 | 
					        let mut to_config_mode: bool = false;
 | 
				
			||||||
        let reasons = ResetReason::get();
 | 
					        let reasons = ResetReason::get();
 | 
				
			||||||
        let reset_store = match reasons {
 | 
					        match reasons {
 | 
				
			||||||
            ResetReason::Software => false,
 | 
					            ResetReason::Software => {},
 | 
				
			||||||
            ResetReason::ExternalPin => false,
 | 
					            ResetReason::ExternalPin => {},
 | 
				
			||||||
            ResetReason::Watchdog => true,
 | 
					            ResetReason::Watchdog => {
 | 
				
			||||||
            ResetReason::Sdio => true,
 | 
					                init_rtc_store = true;
 | 
				
			||||||
            ResetReason::Panic => true,
 | 
					            },
 | 
				
			||||||
            ResetReason::InterruptWatchdog => true,
 | 
					            ResetReason::Sdio => {
 | 
				
			||||||
            ResetReason::PowerOn => true,
 | 
					                init_rtc_store = true
 | 
				
			||||||
            ResetReason::Unknown => true,
 | 
					            },
 | 
				
			||||||
            ResetReason::Brownout => true,
 | 
					            ResetReason::Panic => {
 | 
				
			||||||
            ResetReason::TaskWatchdog => true,
 | 
					                init_rtc_store = true
 | 
				
			||||||
            ResetReason::DeepSleep => false,
 | 
					            },
 | 
				
			||||||
            ResetReason::USBPeripheral => true,
 | 
					            ResetReason::InterruptWatchdog => {
 | 
				
			||||||
            ResetReason::JTAG => true,
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::PowerOn => {
 | 
				
			||||||
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::Unknown => {
 | 
				
			||||||
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::Brownout => {
 | 
				
			||||||
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::TaskWatchdog => {
 | 
				
			||||||
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::DeepSleep => {},
 | 
				
			||||||
 | 
					            ResetReason::USBPeripheral => {
 | 
				
			||||||
 | 
					                init_rtc_store = true;
 | 
				
			||||||
 | 
					                to_config_mode = true;
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            ResetReason::JTAG => {
 | 
				
			||||||
 | 
					                init_rtc_store = true
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        if reset_store {
 | 
					        println!("Reset due to {:?} requires rtc clear {} and force config mode {}", reasons, init_rtc_store, to_config_mode);
 | 
				
			||||||
            println!("Clear and reinit RTC store");
 | 
					        if init_rtc_store {
 | 
				
			||||||
            unsafe {
 | 
					            unsafe {
 | 
				
			||||||
                LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
 | 
					                LAST_WATERING_TIMESTAMP = [0; PLANT_COUNT];
 | 
				
			||||||
                CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
 | 
					                CONSECUTIVE_WATERING_PLANT = [0; PLANT_COUNT];
 | 
				
			||||||
                LOW_VOLTAGE_DETECTED = false;
 | 
					                LOW_VOLTAGE_DETECTED = false;
 | 
				
			||||||
 | 
					                RESTART_TO_CONF = to_config_mode;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            println!("Keeping RTC store");
 | 
					 | 
				
			||||||
            unsafe {
 | 
					            unsafe {
 | 
				
			||||||
 | 
					                if to_config_mode{
 | 
				
			||||||
 | 
					                    RESTART_TO_CONF = true; 
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                println!("Current restart to conf mode{:?}", RESTART_TO_CONF);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
                println!(
 | 
					                println!(
 | 
				
			||||||
                    "Current low voltage detection is {:?}",
 | 
					                    "Current low voltage detection is {:?}",
 | 
				
			||||||
                    LOW_VOLTAGE_DETECTED
 | 
					                    LOW_VOLTAGE_DETECTED
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2050
									
								
								rust/src/webserver/bootstrap-grid.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2050
									
								
								rust/src/webserver/bootstrap-grid.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -6,7 +6,9 @@ use std::{
 | 
				
			|||||||
    sync::{atomic::AtomicBool, Arc},
 | 
					    sync::{atomic::AtomicBool, Arc},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::{espota::OtaUpdate, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS};
 | 
					use crate::{
 | 
				
			||||||
 | 
					    espota::OtaUpdate, get_version, map_range_moisture, plant_hal::FileInfo, BOARD_ACCESS,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
use anyhow::bail;
 | 
					use anyhow::bail;
 | 
				
			||||||
use chrono::DateTime;
 | 
					use chrono::DateTime;
 | 
				
			||||||
use core::result::Result::Ok;
 | 
					use core::result::Result::Ok;
 | 
				
			||||||
@@ -29,12 +31,6 @@ struct FileList {
 | 
				
			|||||||
    file: Vec<FileInfo>,
 | 
					    file: Vec<FileInfo>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Debug)]
 | 
					 | 
				
			||||||
struct VersionInfo<'a> {
 | 
					 | 
				
			||||||
    git_hash: &'a str,
 | 
					 | 
				
			||||||
    build_time: &'a str,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[derive(Serialize, Debug)]
 | 
					#[derive(Serialize, Debug)]
 | 
				
			||||||
struct LoadData<'a> {
 | 
					struct LoadData<'a> {
 | 
				
			||||||
    rtc: &'a str,
 | 
					    rtc: &'a str,
 | 
				
			||||||
@@ -158,17 +154,19 @@ fn set_config(
 | 
				
			|||||||
    anyhow::Ok(Some("saved".to_owned()))
 | 
					    anyhow::Ok(Some("saved".to_owned()))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn get_version(
 | 
					fn get_battery_state(
 | 
				
			||||||
    _request: &mut Request<&mut EspHttpConnection>,
 | 
					    _request: &mut Request<&mut EspHttpConnection>,
 | 
				
			||||||
) -> Result<Option<std::string::String>, anyhow::Error> {
 | 
					) -> Result<Option<std::string::String>, anyhow::Error> {
 | 
				
			||||||
    let branch = env!("VERGEN_GIT_BRANCH").to_owned();
 | 
					    let mut board = BOARD_ACCESS.lock().unwrap();
 | 
				
			||||||
    let hash = &env!("VERGEN_GIT_SHA")[0..8];
 | 
					    let battery_state = board.get_battery_state();
 | 
				
			||||||
 | 
					    let battery_json = serde_json::to_string(&battery_state)?;
 | 
				
			||||||
 | 
					    anyhow::Ok(Some(battery_json))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let version_info: VersionInfo<'_> = VersionInfo {
 | 
					fn get_version_web(
 | 
				
			||||||
        git_hash: &(branch + "@" + hash),
 | 
					    _request: &mut Request<&mut EspHttpConnection>,
 | 
				
			||||||
        build_time: env!("VERGEN_BUILD_TIMESTAMP"),
 | 
					) -> Result<Option<std::string::String>, anyhow::Error> {
 | 
				
			||||||
    };
 | 
					    anyhow::Ok(Some(serde_json::to_string(&get_version())?))
 | 
				
			||||||
    anyhow::Ok(Some(serde_json::to_string(&version_info)?))
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn pump_test(
 | 
					fn pump_test(
 | 
				
			||||||
@@ -296,10 +294,14 @@ pub fn httpd(_reboot_now: Arc<AtomicBool>) -> Box<EspHttpServer<'static>> {
 | 
				
			|||||||
        Box::new(EspHttpServer::new(&server_config).unwrap());
 | 
					        Box::new(EspHttpServer::new(&server_config).unwrap());
 | 
				
			||||||
    server
 | 
					    server
 | 
				
			||||||
        .fn_handler("/version", Method::Get, |request| {
 | 
					        .fn_handler("/version", Method::Get, |request| {
 | 
				
			||||||
            handle_error_to500(request, get_version)
 | 
					            handle_error_to500(request, get_version_web)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					    server
 | 
				
			||||||
 | 
					        .fn_handler("/battery", Method::Get, |request| {
 | 
				
			||||||
 | 
					            handle_error_to500(request, get_battery_state)
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .unwrap();
 | 
					        .unwrap();
 | 
				
			||||||
 | 
					 | 
				
			||||||
    server
 | 
					    server
 | 
				
			||||||
        .fn_handler("/time", Method::Get, |request| {
 | 
					        .fn_handler("/time", Method::Get, |request| {
 | 
				
			||||||
            handle_error_to500(request, get_data)
 | 
					            handle_error_to500(request, get_data)
 | 
				
			||||||
@@ -522,7 +524,7 @@ fn cors_response(
 | 
				
			|||||||
) -> Result<(), anyhow::Error> {
 | 
					) -> Result<(), anyhow::Error> {
 | 
				
			||||||
    let headers = [
 | 
					    let headers = [
 | 
				
			||||||
        ("Access-Control-Allow-Origin", "*"),
 | 
					        ("Access-Control-Allow-Origin", "*"),
 | 
				
			||||||
        ("Access-Control-Allow-Headers", "*")
 | 
					        ("Access-Control-Allow-Headers", "*"),
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    let mut response = request.into_response(status, None, &headers)?;
 | 
					    let mut response = request.into_response(status, None, &headers)?;
 | 
				
			||||||
    response.write(body.as_bytes())?;
 | 
					    response.write(body.as_bytes())?;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										241
									
								
								rust/src_webpack/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										241
									
								
								rust/src_webpack/package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -5,11 +5,10 @@
 | 
				
			|||||||
  "packages": {
 | 
					  "packages": {
 | 
				
			||||||
    "": {
 | 
					    "": {
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "copy-webpack-plugin": "^12.0.2",
 | 
				
			||||||
        "source-map-loader": "^4.0.1"
 | 
					        "source-map-loader": "^4.0.1"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "devDependencies": {
 | 
					      "devDependencies": {
 | 
				
			||||||
        "copy-webpack-plugin": "^12.0.2",
 | 
					 | 
				
			||||||
        "css-loader": "^7.1.2",
 | 
					 | 
				
			||||||
        "html-webpack-harddisk-plugin": "^2.0.0",
 | 
					        "html-webpack-harddisk-plugin": "^2.0.0",
 | 
				
			||||||
        "html-webpack-plugin": "^5.6.3",
 | 
					        "html-webpack-plugin": "^5.6.3",
 | 
				
			||||||
        "raw-loader": "^4.0.2",
 | 
					        "raw-loader": "^4.0.2",
 | 
				
			||||||
@@ -155,7 +154,6 @@
 | 
				
			|||||||
      "version": "2.1.5",
 | 
					      "version": "2.1.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
 | 
				
			||||||
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
 | 
					      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@nodelib/fs.stat": "2.0.5",
 | 
					        "@nodelib/fs.stat": "2.0.5",
 | 
				
			||||||
@@ -169,7 +167,6 @@
 | 
				
			|||||||
      "version": "2.0.5",
 | 
					      "version": "2.0.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
 | 
				
			||||||
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
 | 
					      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">= 8"
 | 
					        "node": ">= 8"
 | 
				
			||||||
@@ -179,7 +176,6 @@
 | 
				
			|||||||
      "version": "1.2.8",
 | 
					      "version": "1.2.8",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
 | 
				
			||||||
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
 | 
					      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@nodelib/fs.scandir": "2.1.5",
 | 
					        "@nodelib/fs.scandir": "2.1.5",
 | 
				
			||||||
@@ -193,7 +189,6 @@
 | 
				
			|||||||
      "version": "2.3.0",
 | 
					      "version": "2.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
 | 
					      "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=18"
 | 
					        "node": ">=18"
 | 
				
			||||||
@@ -698,7 +693,6 @@
 | 
				
			|||||||
      "version": "2.1.1",
 | 
					      "version": "2.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
 | 
					      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "ajv": "^8.0.0"
 | 
					        "ajv": "^8.0.0"
 | 
				
			||||||
@@ -716,7 +710,6 @@
 | 
				
			|||||||
      "version": "8.17.1",
 | 
					      "version": "8.17.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
 | 
					      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "fast-deep-equal": "^3.1.3",
 | 
					        "fast-deep-equal": "^3.1.3",
 | 
				
			||||||
@@ -733,7 +726,6 @@
 | 
				
			|||||||
      "version": "1.0.0",
 | 
					      "version": "1.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
 | 
					      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/ajv-keywords": {
 | 
					    "node_modules/ajv-keywords": {
 | 
				
			||||||
@@ -894,7 +886,6 @@
 | 
				
			|||||||
      "version": "3.0.2",
 | 
					      "version": "3.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
 | 
					      "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "fill-range": "^7.0.1"
 | 
					        "fill-range": "^7.0.1"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -1222,7 +1213,6 @@
 | 
				
			|||||||
      "version": "12.0.2",
 | 
					      "version": "12.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==",
 | 
					      "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "fast-glob": "^3.3.2",
 | 
					        "fast-glob": "^3.3.2",
 | 
				
			||||||
@@ -1247,7 +1237,6 @@
 | 
				
			|||||||
      "version": "8.17.1",
 | 
					      "version": "8.17.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
 | 
					      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "fast-deep-equal": "^3.1.3",
 | 
					        "fast-deep-equal": "^3.1.3",
 | 
				
			||||||
@@ -1264,7 +1253,6 @@
 | 
				
			|||||||
      "version": "5.1.0",
 | 
					      "version": "5.1.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
 | 
					      "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "fast-deep-equal": "^3.1.3"
 | 
					        "fast-deep-equal": "^3.1.3"
 | 
				
			||||||
@@ -1277,7 +1265,6 @@
 | 
				
			|||||||
      "version": "6.0.2",
 | 
					      "version": "6.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
 | 
					      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					      "license": "ISC",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "is-glob": "^4.0.3"
 | 
					        "is-glob": "^4.0.3"
 | 
				
			||||||
@@ -1290,14 +1277,12 @@
 | 
				
			|||||||
      "version": "1.0.0",
 | 
					      "version": "1.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
 | 
					      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT"
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
 | 
					    "node_modules/copy-webpack-plugin/node_modules/schema-utils": {
 | 
				
			||||||
      "version": "4.2.0",
 | 
					      "version": "4.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
 | 
					      "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@types/json-schema": "^7.0.9",
 | 
					        "@types/json-schema": "^7.0.9",
 | 
				
			||||||
@@ -1306,7 +1291,7 @@
 | 
				
			|||||||
        "ajv-keywords": "^5.1.0"
 | 
					        "ajv-keywords": "^5.1.0"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">= 12.13.0"
 | 
					        "node": ">= 10.13.0"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "funding": {
 | 
					      "funding": {
 | 
				
			||||||
        "type": "opencollective",
 | 
					        "type": "opencollective",
 | 
				
			||||||
@@ -1334,42 +1319,6 @@
 | 
				
			|||||||
        "node": ">= 8"
 | 
					        "node": ">= 8"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/css-loader": {
 | 
					 | 
				
			||||||
      "version": "7.1.2",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "icss-utils": "^5.1.0",
 | 
					 | 
				
			||||||
        "postcss": "^8.4.33",
 | 
					 | 
				
			||||||
        "postcss-modules-extract-imports": "^3.1.0",
 | 
					 | 
				
			||||||
        "postcss-modules-local-by-default": "^4.0.5",
 | 
					 | 
				
			||||||
        "postcss-modules-scope": "^3.2.0",
 | 
					 | 
				
			||||||
        "postcss-modules-values": "^4.0.0",
 | 
					 | 
				
			||||||
        "postcss-value-parser": "^4.2.0",
 | 
					 | 
				
			||||||
        "semver": "^7.5.4"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">= 18.12.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "funding": {
 | 
					 | 
				
			||||||
        "type": "opencollective",
 | 
					 | 
				
			||||||
        "url": "https://opencollective.com/webpack"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "@rspack/core": "0.x || 1.x",
 | 
					 | 
				
			||||||
        "webpack": "^5.27.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependenciesMeta": {
 | 
					 | 
				
			||||||
        "@rspack/core": {
 | 
					 | 
				
			||||||
          "optional": true
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "webpack": {
 | 
					 | 
				
			||||||
          "optional": true
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/css-select": {
 | 
					    "node_modules/css-select": {
 | 
				
			||||||
      "version": "4.3.0",
 | 
					      "version": "4.3.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
 | 
				
			||||||
@@ -1400,19 +1349,6 @@
 | 
				
			|||||||
        "url": "https://github.com/sponsors/fb55"
 | 
					        "url": "https://github.com/sponsors/fb55"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/cssesc": {
 | 
					 | 
				
			||||||
      "version": "3.0.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "bin": {
 | 
					 | 
				
			||||||
        "cssesc": "bin/cssesc"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/debug": {
 | 
					    "node_modules/debug": {
 | 
				
			||||||
      "version": "2.6.9",
 | 
					      "version": "2.6.9",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
 | 
				
			||||||
@@ -1833,7 +1769,6 @@
 | 
				
			|||||||
      "version": "3.3.2",
 | 
					      "version": "3.3.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
 | 
					      "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@nodelib/fs.stat": "^2.0.2",
 | 
					        "@nodelib/fs.stat": "^2.0.2",
 | 
				
			||||||
@@ -1855,7 +1790,6 @@
 | 
				
			|||||||
      "version": "3.0.3",
 | 
					      "version": "3.0.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
 | 
					      "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "BSD-3-Clause"
 | 
					      "license": "BSD-3-Clause"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/fastest-levenshtein": {
 | 
					    "node_modules/fastest-levenshtein": {
 | 
				
			||||||
@@ -1871,7 +1805,6 @@
 | 
				
			|||||||
      "version": "1.17.1",
 | 
					      "version": "1.17.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
 | 
					      "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					      "license": "ISC",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "reusify": "^1.0.4"
 | 
					        "reusify": "^1.0.4"
 | 
				
			||||||
@@ -1894,7 +1827,6 @@
 | 
				
			|||||||
      "version": "7.0.1",
 | 
					      "version": "7.0.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
 | 
					      "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "to-regex-range": "^5.0.1"
 | 
					        "to-regex-range": "^5.0.1"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -2017,7 +1949,6 @@
 | 
				
			|||||||
      "version": "5.1.2",
 | 
					      "version": "5.1.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
 | 
					      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					      "license": "ISC",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "is-glob": "^4.0.1"
 | 
					        "is-glob": "^4.0.1"
 | 
				
			||||||
@@ -2036,7 +1967,6 @@
 | 
				
			|||||||
      "version": "14.0.2",
 | 
					      "version": "14.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
 | 
					      "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@sindresorhus/merge-streams": "^2.1.0",
 | 
					        "@sindresorhus/merge-streams": "^2.1.0",
 | 
				
			||||||
@@ -2404,24 +2334,10 @@
 | 
				
			|||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/icss-utils": {
 | 
					 | 
				
			||||||
      "version": "5.1.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >= 14"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "postcss": "^8.1.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/ignore": {
 | 
					    "node_modules/ignore": {
 | 
				
			||||||
      "version": "5.3.2",
 | 
					      "version": "5.3.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
 | 
					      "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">= 4"
 | 
					        "node": ">= 4"
 | 
				
			||||||
@@ -2517,7 +2433,6 @@
 | 
				
			|||||||
      "version": "2.1.1",
 | 
					      "version": "2.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 | 
					      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
@@ -2527,7 +2442,6 @@
 | 
				
			|||||||
      "version": "4.0.3",
 | 
					      "version": "4.0.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
 | 
					      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "is-extglob": "^2.1.1"
 | 
					        "is-extglob": "^2.1.1"
 | 
				
			||||||
@@ -2572,7 +2486,6 @@
 | 
				
			|||||||
      "version": "7.0.0",
 | 
					      "version": "7.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 | 
					      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=0.12.0"
 | 
					        "node": ">=0.12.0"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@@ -2814,7 +2727,6 @@
 | 
				
			|||||||
      "version": "1.4.1",
 | 
					      "version": "1.4.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
 | 
					      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">= 8"
 | 
					        "node": ">= 8"
 | 
				
			||||||
@@ -2834,7 +2746,6 @@
 | 
				
			|||||||
      "version": "4.0.5",
 | 
					      "version": "4.0.5",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
 | 
				
			||||||
      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
 | 
					      "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "braces": "^3.0.2",
 | 
					        "braces": "^3.0.2",
 | 
				
			||||||
        "picomatch": "^2.3.1"
 | 
					        "picomatch": "^2.3.1"
 | 
				
			||||||
@@ -2903,25 +2814,6 @@
 | 
				
			|||||||
        "multicast-dns": "cli.js"
 | 
					        "multicast-dns": "cli.js"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/nanoid": {
 | 
					 | 
				
			||||||
      "version": "3.3.8",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "funding": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "type": "github",
 | 
					 | 
				
			||||||
          "url": "https://github.com/sponsors/ai"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "bin": {
 | 
					 | 
				
			||||||
        "nanoid": "bin/nanoid.cjs"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/negotiator": {
 | 
					    "node_modules/negotiator": {
 | 
				
			||||||
      "version": "0.6.4",
 | 
					      "version": "0.6.4",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz",
 | 
				
			||||||
@@ -2968,7 +2860,6 @@
 | 
				
			|||||||
      "version": "3.0.0",
 | 
					      "version": "3.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
 | 
					      "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
@@ -3170,7 +3061,6 @@
 | 
				
			|||||||
      "version": "5.0.0",
 | 
					      "version": "5.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
 | 
					      "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=12"
 | 
					        "node": ">=12"
 | 
				
			||||||
@@ -3189,7 +3079,6 @@
 | 
				
			|||||||
      "version": "2.3.1",
 | 
					      "version": "2.3.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 | 
					      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=8.6"
 | 
					        "node": ">=8.6"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -3209,119 +3098,6 @@
 | 
				
			|||||||
        "node": ">=8"
 | 
					        "node": ">=8"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/postcss": {
 | 
					 | 
				
			||||||
      "version": "8.4.49",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "funding": [
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "type": "opencollective",
 | 
					 | 
				
			||||||
          "url": "https://opencollective.com/postcss/"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "type": "tidelift",
 | 
					 | 
				
			||||||
          "url": "https://tidelift.com/funding/github/npm/postcss"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          "type": "github",
 | 
					 | 
				
			||||||
          "url": "https://github.com/sponsors/ai"
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      ],
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "nanoid": "^3.3.7",
 | 
					 | 
				
			||||||
        "picocolors": "^1.1.1",
 | 
					 | 
				
			||||||
        "source-map-js": "^1.2.1"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >=14"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-modules-extract-imports": {
 | 
					 | 
				
			||||||
      "version": "3.1.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >= 14"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "postcss": "^8.1.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-modules-local-by-default": {
 | 
					 | 
				
			||||||
      "version": "4.2.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "icss-utils": "^5.0.0",
 | 
					 | 
				
			||||||
        "postcss-selector-parser": "^7.0.0",
 | 
					 | 
				
			||||||
        "postcss-value-parser": "^4.1.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >= 14"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "postcss": "^8.1.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-modules-scope": {
 | 
					 | 
				
			||||||
      "version": "3.2.1",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "postcss-selector-parser": "^7.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >= 14"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "postcss": "^8.1.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-modules-values": {
 | 
					 | 
				
			||||||
      "version": "4.0.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "ISC",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "icss-utils": "^5.0.0"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": "^10 || ^12 || >= 14"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "peerDependencies": {
 | 
					 | 
				
			||||||
        "postcss": "^8.1.0"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-selector-parser": {
 | 
					 | 
				
			||||||
      "version": "7.0.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.0.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					 | 
				
			||||||
        "cssesc": "^3.0.0",
 | 
					 | 
				
			||||||
        "util-deprecate": "^1.0.2"
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      "engines": {
 | 
					 | 
				
			||||||
        "node": ">=4"
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/postcss-value-parser": {
 | 
					 | 
				
			||||||
      "version": "4.2.0",
 | 
					 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
 | 
					 | 
				
			||||||
      "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
 | 
					 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "node_modules/pretty-error": {
 | 
					    "node_modules/pretty-error": {
 | 
				
			||||||
      "version": "4.0.0",
 | 
					      "version": "4.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz",
 | 
				
			||||||
@@ -3392,7 +3168,6 @@
 | 
				
			|||||||
      "version": "1.2.3",
 | 
					      "version": "1.2.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
 | 
				
			||||||
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
 | 
					      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "funding": [
 | 
					      "funding": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "type": "github",
 | 
					          "type": "github",
 | 
				
			||||||
@@ -3545,7 +3320,6 @@
 | 
				
			|||||||
      "version": "2.0.2",
 | 
					      "version": "2.0.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
 | 
				
			||||||
      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
 | 
					      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=0.10.0"
 | 
					        "node": ">=0.10.0"
 | 
				
			||||||
@@ -3610,7 +3384,6 @@
 | 
				
			|||||||
      "version": "1.0.4",
 | 
					      "version": "1.0.4",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
 | 
				
			||||||
      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
 | 
					      "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "iojs": ">=1.0.0",
 | 
					        "iojs": ">=1.0.0",
 | 
				
			||||||
@@ -3634,7 +3407,6 @@
 | 
				
			|||||||
      "version": "1.2.0",
 | 
					      "version": "1.2.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
 | 
					      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "funding": [
 | 
					      "funding": [
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          "type": "github",
 | 
					          "type": "github",
 | 
				
			||||||
@@ -3959,7 +3731,6 @@
 | 
				
			|||||||
      "version": "5.1.0",
 | 
					      "version": "5.1.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
 | 
					      "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=14.16"
 | 
					        "node": ">=14.16"
 | 
				
			||||||
@@ -4262,7 +4033,6 @@
 | 
				
			|||||||
      "version": "5.0.1",
 | 
					      "version": "5.0.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
 | 
					      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "is-number": "^7.0.0"
 | 
					        "is-number": "^7.0.0"
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@@ -4361,7 +4131,6 @@
 | 
				
			|||||||
      "version": "0.1.0",
 | 
					      "version": "0.1.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
 | 
					      "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "license": "MIT",
 | 
					      "license": "MIT",
 | 
				
			||||||
      "engines": {
 | 
					      "engines": {
 | 
				
			||||||
        "node": ">=18"
 | 
					        "node": ">=18"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@
 | 
				
			|||||||
    "webpack-dev-server": "^5.1.0"
 | 
					    "webpack-dev-server": "^5.1.0"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "copy-webpack-plugin": "^12.0.2",
 | 
				
			||||||
    "source-map-loader": "^4.0.1"
 | 
					    "source-map-loader": "^4.0.1"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -66,3 +66,14 @@ interface VersionInfo {
 | 
				
			|||||||
  git_hash: string,
 | 
					  git_hash: string,
 | 
				
			||||||
  build_time: string
 | 
					  build_time: string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface BatteryState {
 | 
				
			||||||
 | 
					  temperature: string
 | 
				
			||||||
 | 
					  voltage_milli_volt: string,
 | 
				
			||||||
 | 
					  current_milli_ampere: string,
 | 
				
			||||||
 | 
					  cycle_count: string,
 | 
				
			||||||
 | 
					  design_milli_ampere: string,
 | 
				
			||||||
 | 
					  remaining_milli_ampere: string,
 | 
				
			||||||
 | 
					  state_of_charge: string,
 | 
				
			||||||
 | 
					  state_of_health: string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										46
									
								
								rust/src_webpack/src/batteryview.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								rust/src_webpack/src/batteryview.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
				
			|||||||
 | 
					<div class="container col-sm-6 col-md-5" style="border-style: solid; border-width: 1px; padding: 8px; margin: 8px;" >
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-7">
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-7" style="text-align: center; font-weight: bold;">
 | 
				
			||||||
 | 
					            Time:
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div style="display: block; right: 8px; position: absolute;">
 | 
				
			||||||
 | 
					            <input id="battery_auto_refresh" type="checkbox">⟳
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">V:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_voltage_milli_volt"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">mA:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_current_milli_ampere"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">Cycles:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_cycle_count"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">design mA:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_design_milli_ampere"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">remaining mA:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_remaining_milli_ampere"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">charge %:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_state_of_charge"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">health %:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_state_of_health"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-7">Temp °C:</span>
 | 
				
			||||||
 | 
					        <div class="col-5" id="battery_temperature"  style="text-wrap: nowrap"></div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										69
									
								
								rust/src_webpack/src/batteryview.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								rust/src_webpack/src/batteryview.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					import { Controller } from "./main";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class BatteryView{
 | 
				
			||||||
 | 
					    voltage_milli_volt: HTMLSpanElement;
 | 
				
			||||||
 | 
					    current_milli_ampere: HTMLSpanElement;
 | 
				
			||||||
 | 
					    cycle_count: HTMLSpanElement;
 | 
				
			||||||
 | 
					    design_milli_ampere: HTMLSpanElement;
 | 
				
			||||||
 | 
					    remaining_milli_ampere: HTMLSpanElement;
 | 
				
			||||||
 | 
					    state_of_charge: HTMLSpanElement;
 | 
				
			||||||
 | 
					    state_of_health: HTMLSpanElement;
 | 
				
			||||||
 | 
					    temperature: HTMLSpanElement;
 | 
				
			||||||
 | 
					    auto_refresh: HTMLInputElement;
 | 
				
			||||||
 | 
					    timer: NodeJS.Timeout | undefined;
 | 
				
			||||||
 | 
					    controller: Controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor (controller:Controller) {
 | 
				
			||||||
 | 
					      (document.getElementById("batteryview") as HTMLElement).innerHTML = require("./batteryview.html")
 | 
				
			||||||
 | 
					        this.voltage_milli_volt = document.getElementById("battery_voltage_milli_volt") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.current_milli_ampere = document.getElementById("battery_current_milli_ampere") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.cycle_count = document.getElementById("battery_cycle_count") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.design_milli_ampere = document.getElementById("battery_design_milli_ampere") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.remaining_milli_ampere = document.getElementById("battery_remaining_milli_ampere") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.state_of_charge = document.getElementById("battery_state_of_charge") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.state_of_health = document.getElementById("battery_state_of_health") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.temperature = document.getElementById("battery_temperature") as HTMLSpanElement;
 | 
				
			||||||
 | 
					        this.auto_refresh = document.getElementById("battery_auto_refresh") as HTMLInputElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.controller = controller
 | 
				
			||||||
 | 
					        this.auto_refresh.onchange = () => {
 | 
				
			||||||
 | 
					            if(this.timer){
 | 
				
			||||||
 | 
					              clearTimeout(this.timer)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if(this.auto_refresh.checked){
 | 
				
			||||||
 | 
					              controller.updateBatteryData()
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    update(batterystate: BatteryState|null){
 | 
				
			||||||
 | 
					        if (batterystate == null) {
 | 
				
			||||||
 | 
					            this.voltage_milli_volt.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.current_milli_ampere.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.cycle_count.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.design_milli_ampere.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.remaining_milli_ampere.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.state_of_charge.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.state_of_health.innerText = "N/A"
 | 
				
			||||||
 | 
					            this.temperature.innerText = "N/A"
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            this.voltage_milli_volt.innerText = String(+batterystate.voltage_milli_volt/1000)
 | 
				
			||||||
 | 
					            this.current_milli_ampere.innerText = batterystate.current_milli_ampere
 | 
				
			||||||
 | 
					            this.cycle_count.innerText = batterystate.cycle_count
 | 
				
			||||||
 | 
					            this.design_milli_ampere.innerText = batterystate.design_milli_ampere
 | 
				
			||||||
 | 
					            this.remaining_milli_ampere.innerText = batterystate.remaining_milli_ampere
 | 
				
			||||||
 | 
					            this.state_of_charge.innerText = batterystate.state_of_charge
 | 
				
			||||||
 | 
					            this.state_of_health.innerText = batterystate.state_of_health
 | 
				
			||||||
 | 
					            this.temperature.innerText = String(+batterystate.temperature / 100)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(this.auto_refresh.checked){
 | 
				
			||||||
 | 
					            this.timer = setTimeout(this.controller.updateBatteryData, 1000);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            if(this.timer){
 | 
				
			||||||
 | 
					              clearTimeout(this.timer)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
<div class="container-xxl">
 | 
					 | 
				
			||||||
  <link rel="stylesheet" href="bootstrap-grid.css">
 | 
					  <link rel="stylesheet" href="bootstrap-grid.css">
 | 
				
			||||||
  <style>
 | 
					  <style>
 | 
				
			||||||
    .progressPane{
 | 
					    .progressPane{
 | 
				
			||||||
@@ -66,70 +65,30 @@
 | 
				
			|||||||
  </style>
 | 
					  </style>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div id="progressPane" class="progressPane">
 | 
					 | 
				
			||||||
    <div class="progressPaneCenter">
 | 
					 | 
				
			||||||
      <div id="progressPaneBar" class="progress" data-label="50% Complete">
 | 
					 | 
				
			||||||
        <span id="progressPaneSpan" class="value" style="width:100%;"></span>
 | 
					 | 
				
			||||||
      </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  </div>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="container-xxl">
 | 
				
			||||||
  <input type="button" id="test" value="Test">
 | 
					  <input type="button" id="test" value="Test">
 | 
				
			||||||
  <h2>Current Firmware</h2>
 | 
					  
 | 
				
			||||||
  <div>
 | 
					  <div id="firmwareview">
 | 
				
			||||||
    <div id="firmware_buildtime">Buildtime loading</div>
 | 
					
 | 
				
			||||||
    <div id="firmware_githash">Build githash loading</div>
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  <h2>firmeware OTA v3</h2>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <form id="upload_form" method="post">
 | 
					 | 
				
			||||||
    <input type="file" name="file1" id="firmware_file"><br>
 | 
					 | 
				
			||||||
    <progress id="firmware_progressBar" value="0" max="100" style="width:300px;"></progress>
 | 
					 | 
				
			||||||
    <h3 id="firmware_status"></h3>
 | 
					 | 
				
			||||||
    <h3 id="firmware_answer"></h3>
 | 
					 | 
				
			||||||
    <p id="firmware_loaded_n_total"></p>
 | 
					 | 
				
			||||||
  </form>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  <div id="timeview">
 | 
					  <div id="timeview">
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div id="network_view">
 | 
					  <div id="network_view">
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div id="tankview"></div>
 | 
				
			||||||
 | 
					  <div id="batteryview"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <h2>config</h2>
 | 
					  <h2>config</h2>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <div id="configform">
 | 
					  <div id="configform">
 | 
				
			||||||
      <h3>Tank:</h3>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="checkbox" id="tank_sensor_enabled">
 | 
					 | 
				
			||||||
      Enable Tank Sensor
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="checkbox" id="tank_allow_pumping_if_sensor_error">
 | 
					 | 
				
			||||||
      Allow Pumping if Sensor Error
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="number" min="2" max="500000" id="tank_useable_ml">
 | 
					 | 
				
			||||||
      Tank Size mL
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="number" min="1" max="500000" id="tank_warn_percent">
 | 
					 | 
				
			||||||
      Tank Warn Percent (mapped in relation to empty and full)
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="number" min="0" max="100" id="tank_empty_percent">
 | 
					 | 
				
			||||||
      Tank Empty Percent (% max move)
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div>
 | 
					 | 
				
			||||||
      <input type="number" min="0" max="100" id="tank_full_percent">
 | 
					 | 
				
			||||||
      Tank Full Percent (% max move)
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <h3>Light:</h3>
 | 
					    <h3>Light:</h3>
 | 
				
			||||||
    <input type="checkbox" id="night_lamp_enabled" checked="false"> Enable Nightlight
 | 
					    <input type="checkbox" id="night_lamp_enabled" checked="false"> Enable Nightlight
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
@@ -155,3 +114,11 @@
 | 
				
			|||||||
  <textarea id="json" cols=50 rows=10></textarea>
 | 
					  <textarea id="json" cols=50 rows=10></textarea>
 | 
				
			||||||
  <script src="bundle.js"></script>
 | 
					  <script src="bundle.js"></script>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div id="progressPane" class="progressPane">
 | 
				
			||||||
 | 
					  <div class="progressPaneCenter">
 | 
				
			||||||
 | 
					    <div id="progressPaneBar" class="progress" data-label="50% Complete">
 | 
				
			||||||
 | 
					      <span id="progressPaneSpan" class="value" style="width:100%;"></span>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -9,10 +9,11 @@ import { TimeView } from "./timeview";
 | 
				
			|||||||
import { PlantView, PlantViews } from "./plant";
 | 
					import { PlantView, PlantViews } from "./plant";
 | 
				
			||||||
import { NetworkConfigView } from "./network";
 | 
					import { NetworkConfigView } from "./network";
 | 
				
			||||||
import { NightLampView } from "./nightmode";
 | 
					import { NightLampView } from "./nightmode";
 | 
				
			||||||
import { TankConfigView } from "./tanks";
 | 
					import { TankConfigView } from "./tankview";
 | 
				
			||||||
import { SubmitView } from "./submitView";
 | 
					import { SubmitView } from "./submitView";
 | 
				
			||||||
import { ProgressView } from "./progress";
 | 
					import { ProgressView } from "./progress";
 | 
				
			||||||
import { OTAView } from "./ota";
 | 
					import { OTAView } from "./ota";
 | 
				
			||||||
 | 
					import { BatteryView } from "./batteryview";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class Controller {
 | 
					export class Controller {
 | 
				
			||||||
  updateRTCData() {
 | 
					  updateRTCData() {
 | 
				
			||||||
@@ -27,6 +28,18 @@ export class Controller {
 | 
				
			|||||||
          console.log(error);
 | 
					          console.log(error);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  updateBatteryData() {
 | 
				
			||||||
 | 
					    fetch(PUBLIC_URL + "/battery")
 | 
				
			||||||
 | 
					        .then(response => response.json())
 | 
				
			||||||
 | 
					        .then(json => json as BatteryState)
 | 
				
			||||||
 | 
					        .then(battery => {
 | 
				
			||||||
 | 
					          controller.batteryView.update(battery)
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch(error => {
 | 
				
			||||||
 | 
					          controller.batteryView.update(null)
 | 
				
			||||||
 | 
					          console.log(error);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  uploadNewFirmware(file: File) {
 | 
					  uploadNewFirmware(file: File) {
 | 
				
			||||||
    var current = 0;
 | 
					    var current = 0;
 | 
				
			||||||
    var max = 100;
 | 
					    var max = 100;
 | 
				
			||||||
@@ -226,11 +239,13 @@ export class Controller {
 | 
				
			|||||||
  readonly submitView: SubmitView;
 | 
					  readonly submitView: SubmitView;
 | 
				
			||||||
  readonly firmWareView : OTAView;
 | 
					  readonly firmWareView : OTAView;
 | 
				
			||||||
  readonly progressview: ProgressView;
 | 
					  readonly progressview: ProgressView;
 | 
				
			||||||
 | 
					  readonly batteryView: BatteryView;
 | 
				
			||||||
  constructor() {
 | 
					  constructor() {
 | 
				
			||||||
    this.timeView = new TimeView(this)
 | 
					    this.timeView = new TimeView(this)
 | 
				
			||||||
    this.plantViews = new PlantViews(this)
 | 
					    this.plantViews = new PlantViews(this)
 | 
				
			||||||
    this.networkView = new NetworkConfigView(this, PUBLIC_URL)
 | 
					    this.networkView = new NetworkConfigView(this, PUBLIC_URL)
 | 
				
			||||||
    this.tankView = new TankConfigView(this)
 | 
					    this.tankView = new TankConfigView(this)
 | 
				
			||||||
 | 
					    this.batteryView = new BatteryView(this)
 | 
				
			||||||
    this.nightLampView = new NightLampView(this)
 | 
					    this.nightLampView = new NightLampView(this)
 | 
				
			||||||
    this.submitView = new SubmitView(this)
 | 
					    this.submitView = new SubmitView(this)
 | 
				
			||||||
    this.firmWareView = new OTAView(this)
 | 
					    this.firmWareView = new OTAView(this)
 | 
				
			||||||
@@ -239,6 +254,8 @@ export class Controller {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
const controller = new Controller();
 | 
					const controller = new Controller();
 | 
				
			||||||
controller.updateRTCData();
 | 
					controller.updateRTCData();
 | 
				
			||||||
 | 
					controller.updateBatteryData();
 | 
				
			||||||
controller.downloadConfig();
 | 
					controller.downloadConfig();
 | 
				
			||||||
controller.measure_moisture();
 | 
					n controller.measure_moisture();
 | 
				
			||||||
controller.version();
 | 
					controller.version();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								rust/src_webpack/src/ota.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								rust/src_webpack/src/ota.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<div class="container col-12 col-sm-7 col-md-7" style="border-width: 1px; border-style: solid; padding: 8px; margin: 8px;">
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-12" style="text-align: center; font-weight: bold;">
 | 
				
			||||||
 | 
					            Current Firmware
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-6">
 | 
				
			||||||
 | 
					            <span>Buildtime:</span>
 | 
				
			||||||
 | 
					            <span id="firmware_buildtime" style="text-wrap: nowrap"></span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="col-md-6">
 | 
				
			||||||
 | 
					            <span>Buildhash:</span>
 | 
				
			||||||
 | 
					            <span id="firmware_githash"  style="text-wrap: nowrap"></span>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <form class="col-12" id="upload_form" method="post">
 | 
				
			||||||
 | 
					            <input type="file" name="file1" id="firmware_file"><br>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -6,6 +6,8 @@ export class OTAView {
 | 
				
			|||||||
    firmware_githash: HTMLDivElement;
 | 
					    firmware_githash: HTMLDivElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(controller: Controller) {
 | 
					    constructor(controller: Controller) {
 | 
				
			||||||
 | 
					        (document.getElementById("firmwareview") as HTMLElement).innerHTML = require("./ota.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.firmware_buildtime = document.getElementById("firmware_buildtime") as HTMLDivElement;
 | 
					        this.firmware_buildtime = document.getElementById("firmware_buildtime") as HTMLDivElement;
 | 
				
			||||||
        this.firmware_githash = document.getElementById("firmware_githash") as HTMLDivElement;
 | 
					        this.firmware_githash = document.getElementById("firmware_githash") as HTMLDivElement;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,35 +1,59 @@
 | 
				
			|||||||
<h4 id="plant_${plantId}_header">Plant ${plantId}</h4>
 | 
					<div class="container" style="border-style: solid; border-width: 1px; margin: 8px; padding: 8px;">
 | 
				
			||||||
<div>
 | 
					<span class="row col-12" style="font-weight: bold; display: block; text-align: center;" id="plant_${plantId}_header">Plant ${plantId}</span>
 | 
				
			||||||
    <button id="plant_${plantId}_test">Test</button>
 | 
					
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-1"></div>
 | 
				
			||||||
 | 
					    <button class="col-10" id="plant_${plantId}_test">Test</button>
 | 
				
			||||||
 | 
					    <div class="col-1"></div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
<div>
 | 
					<div class="row">
 | 
				
			||||||
    Current: 
 | 
					    <div class="col-12">Live:</div>
 | 
				
			||||||
    <br>
 | 
					 | 
				
			||||||
    Sensor A:<span id="plant_${plantId}_moisture_a">loading</span>
 | 
					 | 
				
			||||||
    <br>
 | 
					 | 
				
			||||||
    Sensor b:<span id="plant_${plantId}_moisture_b">loading</span>
 | 
					 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
Mode: <select id="plant_${plantId}_mode">
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-7">Sensor A:</div>
 | 
				
			||||||
 | 
					    <span class="col-4" id="plant_${plantId}_moisture_a">loading</span>
 | 
				
			||||||
 | 
					    <div class="col-7">Sensor B:</div>
 | 
				
			||||||
 | 
					    <span class="col-4" id="plant_${plantId}_moisture_b">loading</span>   
 | 
				
			||||||
 | 
					</div>    
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-7">
 | 
				
			||||||
 | 
					        Mode:
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <select class="col-4" id="plant_${plantId}_mode">
 | 
				
			||||||
        <option value="OFF">Off</option>
 | 
					        <option value="OFF">Off</option>
 | 
				
			||||||
    <option value="TargetMoisture">Target Moisture</option>
 | 
					        <option value="TargetMoisture">Target</option>
 | 
				
			||||||
    <option value="TimerOnly">Timer Only</option>
 | 
					        <option value="TimerOnly">Timer</option>
 | 
				
			||||||
    </select>
 | 
					    </select>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
<div>
 | 
					</div>
 | 
				
			||||||
    Target Moisture: <input id="plant_${plantId}_target_moisture" type="number" min="0" max="100" placeholder="0">
 | 
					    <div class="row">
 | 
				
			||||||
    <br>
 | 
					        <div class="col-7">Target Moisture:</div>
 | 
				
			||||||
    Pump Time (s): <input id="plant_${plantId}_pump_time_s" type="number" min="0" max="600" placeholder="30">
 | 
					        <input class="col-4" id="plant_${plantId}_target_moisture" type="number" min="0" max="100" placeholder="0">
 | 
				
			||||||
    <br>
 | 
					    </div>
 | 
				
			||||||
    Pump Cooldown (m): <input id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600" placeholder="30">
 | 
					    <div class="row">
 | 
				
			||||||
    <br>
 | 
					        <div class="col-7">Pump Time (s):</div>
 | 
				
			||||||
    "Pump Hour Start": <select id="plant_${plantId}_pump_hour_start">10</select>
 | 
					        <input class="col-4" id="plant_${plantId}_pump_time_s" type="number" min="0" max="600" placeholder="30">
 | 
				
			||||||
        <br>
 | 
					    </div>
 | 
				
			||||||
    "Pump Hour End": <select id="plant_${plantId}_pump_hour_end">19</select>
 | 
					 | 
				
			||||||
        <br>
 | 
					 | 
				
			||||||
    Sensor B installed: <input id="plant_${plantId}_sensor_b" type="checkbox">
 | 
					 | 
				
			||||||
    <br>
 | 
					 | 
				
			||||||
    Max Consecutive Pump Count: <input id="plant_${plantId}_max_consecutive_pump_count" type="number" min="1", max="50", placeholder="10">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-7">Pump Cooldown (m):</div>
 | 
				
			||||||
 | 
					     <input class="col-4" id="plant_${plantId}_pump_cooldown_min" type="number" min="0" max="600" placeholder="30">
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <div class="col-7">"Pump Hour Start":</div>
 | 
				
			||||||
 | 
					    <select class="col-4" id="plant_${plantId}_pump_hour_start">10</select>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-7">"Pump Hour End":</div>
 | 
				
			||||||
 | 
					     <select class="col-4" id="plant_${plantId}_pump_hour_end">19</select>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-7">Sensor B installed:</div>
 | 
				
			||||||
 | 
					     <input class="col-4" id="plant_${plantId}_sensor_b" type="checkbox">
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div class="row">
 | 
				
			||||||
 | 
					    <div class="col-7">Max Consecutive Pump Count:</div>
 | 
				
			||||||
 | 
					     <input class="col-4" id="plant_${plantId}_max_consecutive_pump_count" type="number" min="1", max="50", placeholder="10">
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
@@ -135,7 +135,6 @@ export class PlantView {
 | 
				
			|||||||
      this.maxConsecutivePumpCount.onchange = function(){
 | 
					      this.maxConsecutivePumpCount.onchange = function(){
 | 
				
			||||||
        controller.configChanged()
 | 
					        controller.configChanged()
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      console.log(this)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    update(a: number, b: number) {
 | 
					    update(a: number, b: number) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								rust/src_webpack/src/tankview.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								rust/src_webpack/src/tankview.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					<h3>Tank:</h3>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="checkbox" id="tank_sensor_enabled">
 | 
				
			||||||
 | 
					  Enable Tank Sensor
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="checkbox" id="tank_allow_pumping_if_sensor_error">
 | 
				
			||||||
 | 
					  Allow Pumping if Sensor Error
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="number" min="2" max="500000" id="tank_useable_ml">
 | 
				
			||||||
 | 
					  Tank Size mL
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="number" min="1" max="500000" id="tank_warn_percent">
 | 
				
			||||||
 | 
					  Tank Warn Percent (mapped in relation to empty and full)
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="number" min="0" max="100" id="tank_empty_percent">
 | 
				
			||||||
 | 
					  Tank Empty Percent (% max move)
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					<div>
 | 
				
			||||||
 | 
					  <input type="number" min="0" max="100" id="tank_full_percent">
 | 
				
			||||||
 | 
					  Tank Full Percent (% max move)
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -9,6 +9,9 @@ export class TankConfigView {
 | 
				
			|||||||
    private readonly tank_allow_pumping_if_sensor_error: HTMLInputElement;
 | 
					    private readonly tank_allow_pumping_if_sensor_error: HTMLInputElement;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
    constructor(controller:Controller){
 | 
					    constructor(controller:Controller){
 | 
				
			||||||
 | 
					      (document.getElementById("tankview") as HTMLElement).innerHTML = require("./tankview.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.tank_useable_ml = document.getElementById("tank_useable_ml") as HTMLInputElement;
 | 
					      this.tank_useable_ml = document.getElementById("tank_useable_ml") as HTMLInputElement;
 | 
				
			||||||
      this.tank_useable_ml.onchange = controller.configChanged
 | 
					      this.tank_useable_ml.onchange = controller.configChanged
 | 
				
			||||||
      this.tank_empty_percent = document.getElementById("tank_empty_percent") as HTMLInputElement;
 | 
					      this.tank_empty_percent = document.getElementById("tank_empty_percent") as HTMLInputElement;
 | 
				
			||||||
@@ -1,7 +1,28 @@
 | 
				
			|||||||
<h2>Time</h2>
 | 
					<div class="container col-sm-6 col-md-5" style="border-style: solid; border-width: 1px; padding: 8px; margin: 8px;" >
 | 
				
			||||||
AutoRefresh:<input id="timeview_auto_refresh" type="checkbox">
 | 
					    <div class="row">
 | 
				
			||||||
<div id="timeview_esp_time">Esp time</div>
 | 
					        <div class="col-4">
 | 
				
			||||||
<div id="timeview_rtc_time">Rtc time</div>
 | 
					        </div>
 | 
				
			||||||
<div id="timeview_browser_time">Rtc time</div>
 | 
					        <div class="col-4" style="text-align: center; font-weight: bold;">
 | 
				
			||||||
<div></div>
 | 
					            Time:
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div style="display: block; right: 8px; position: absolute;">
 | 
				
			||||||
 | 
					            <input id="timeview_auto_refresh" type="checkbox">⟳
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-2">MCU:</span>
 | 
				
			||||||
 | 
					        <div class="col-9" id="timeview_esp_time"  style="text-wrap: nowrap">Esp time</div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-2">RTC:</span>
 | 
				
			||||||
 | 
					        <div class="col-9" id="timeview_rtc_time"  style="text-wrap: nowrap">Rtc time</div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="row">
 | 
				
			||||||
 | 
					        <span class="col-2">Local:</span>
 | 
				
			||||||
 | 
					        <div class="col-9" id="timeview_browser_time"  style="text-wrap: nowrap">Local time</div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <button id="timeview_time_upload">Store Browser time into esp and rtc</button>
 | 
					    <button id="timeview_time_upload">Store Browser time into esp and rtc</button>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ const isDevServer = process.env.WEBPACK_SERVE;
 | 
				
			|||||||
console.log("Dev server is " + isDevServer);
 | 
					console.log("Dev server is " + isDevServer);
 | 
				
			||||||
var host;
 | 
					var host;
 | 
				
			||||||
if (isDevServer){
 | 
					if (isDevServer){
 | 
				
			||||||
  host = 'http://192.168.1.172';
 | 
					  host = 'http://192.168.0.103';
 | 
				
			||||||
} else {
 | 
					} else {
 | 
				
			||||||
  host = '';
 | 
					  host = '';
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user