From 78a3b38829710bde490c52a4c95ce6dc90852145 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 14 Dec 2024 16:55:41 +0100 Subject: [PATCH 1/9] Fix duplicate response headers #834 --- src/sys/svc/hasp_http.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 06af58d8..99f3c981 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -264,18 +264,18 @@ static void webSendFooter() #endif } -static void http_send_cache_header(int size, int age = 3600) +static void http_send_cache_header(int age = 3600) { - webServer.sendHeader("Content-Length", (String)(size)); webServer.sendHeader("Cache-Control", (String)(F("public, max-age=")) + (String)(age)); } static int http_send_cached(int statuscode, const char* contenttype, const char* data, size_t size, int age = 3600) { - http_send_cache_header(size, age); + http_send_cache_header(age); #if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) webServer.send_P(statuscode, contenttype, data, size); #else + webServer.sendHeader("Content-Length", (String)(size)); webServer.send(statuscode, contenttype, data); #endif return statuscode; From e815e31a5a808c49da6f8f6af26d4f1ef6b42189 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 14 Dec 2024 21:58:22 +0100 Subject: [PATCH 2/9] Remove default SPI_FREQUENCY if not set #153 --- src/drv/tft/tft_defines.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drv/tft/tft_defines.h b/src/drv/tft/tft_defines.h index 66904dfd..87b02294 100644 --- a/src/drv/tft/tft_defines.h +++ b/src/drv/tft/tft_defines.h @@ -49,9 +49,9 @@ #define TFT_RST -1 #endif -#ifndef SPI_FREQUENCY -#define SPI_FREQUENCY 40000000 -#endif +// #ifndef SPI_FREQUENCY +// #define SPI_FREQUENCY -1 // 40000000 +// #endif #ifndef TFT_D0 #define TFT_D0 -1 From 154a8ff63890814130041c0c993b82e305f82551 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 14 Dec 2024 22:02:22 +0100 Subject: [PATCH 3/9] Check if SPI_FREQUENCY is defined #153 --- src/drv/tft/tft_driver_arduinogfx.cpp | 58 ++++++++++++++------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp index 2e377c39..cbe8794d 100644 --- a/src/drv/tft/tft_driver_arduinogfx.cpp +++ b/src/drv/tft/tft_driver_arduinogfx.cpp @@ -25,33 +25,30 @@ void ArduinoGfx::init(int w, int h) { LOG_TRACE(TAG_TFT, F(D_SERVICE_STARTING)); -#if(TFT_WIDTH == 170) && (TFT_HEIGHT == 320) - Arduino_DataBus *bus = new Arduino_ESP32PAR8( - TFT_DC, TFT_CS, TFT_WR, TFT_RD, - TFT_D0, TFT_D1, TFT_D2, TFT_D3, TFT_D4, TFT_D5, TFT_D6, TFT_D7); - tft = new Arduino_ST7789(bus, - TFT_RST /* RST */, TFT_ROTATION /* rotation */, true /* IPS */, - TFT_WIDTH /* width */, TFT_HEIGHT /* height */, - 35 /* col offset 1 */, 0 /* row offset 1 */, - 35 /* col offset 2 */, 0 /* row offset 2 */ +#if(TFT_WIDTH == 170) && (TFT_HEIGHT == 320) + Arduino_DataBus* bus = new Arduino_ESP32PAR8(TFT_DC, TFT_CS, TFT_WR, TFT_RD, TFT_D0, TFT_D1, TFT_D2, TFT_D3, TFT_D4, + TFT_D5, TFT_D6, TFT_D7); + tft = new Arduino_ST7789(bus, TFT_RST /* RST */, TFT_ROTATION /* rotation */, true /* IPS */, TFT_WIDTH /* width */, + TFT_HEIGHT /* height */, 35 /* col offset 1 */, 0 /* row offset 1 */, + 35 /* col offset 2 */, 0 /* row offset 2 */ ); #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_PANEL) Wire.begin(17, 18); - Arduino_DataBus* bus = new Arduino_XL9535SWSPI(17 /* SDA */, 18 /* SCL */, -1 /* XL PWD */, 17 /* XL CS */, - 15 /* XL SCK */, 16 /* XL MOSI */,&Wire); - Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel( - -1 /* DE */, TFT_VSYNC /* VSYNC */, TFT_HSYNC /* HSYNC */, TFT_PCLK /* PCLK */, - TFT_B0 /* B0 */, TFT_B1 /* B1 */, TFT_B2 /* B2 */, TFT_B3 /* B3 */, TFT_B4 /* B4 */, - TFT_G0 /* G0 */, TFT_G1 /* G1 */, TFT_G2 /* G2 */, TFT_G3 /* G3 */, TFT_G4 /* G4 */, TFT_G5 /* G5 */, - TFT_R0 /* R0 */, TFT_R1 /* R1 */, TFT_R2 /* R2 */, TFT_R3 /* R3 */, TFT_R4 /* R4 */, - 1 /* hsync_polarity */, 20 /* hsync_front_porch */, 2 /* hsync_pulse_width */, 0 /* hsync_back_porch */, - 1 /* vsync_polarity */, 30 /* vsync_front_porch */, 8 /* vsync_pulse_width */, 1 /* vsync_back_porch */, - 10 /* pclk_active_neg */, 6000000L /* prefer_speed */, false /* useBigEndian */, - 0 /* de_idle_high*/, 0 /* pclk_idle_high */); + Arduino_DataBus* bus = new Arduino_XL9535SWSPI(17 /* SDA */, 18 /* SCL */, -1 /* XL PWD */, 17 /* XL CS */, + 15 /* XL SCK */, 16 /* XL MOSI */, &Wire); + Arduino_ESP32RGBPanel* rgbpanel = new Arduino_ESP32RGBPanel( + -1 /* DE */, TFT_VSYNC /* VSYNC */, TFT_HSYNC /* HSYNC */, TFT_PCLK /* PCLK */, TFT_B0 /* B0 */, + TFT_B1 /* B1 */, TFT_B2 /* B2 */, TFT_B3 /* B3 */, TFT_B4 /* B4 */, TFT_G0 /* G0 */, TFT_G1 /* G1 */, + TFT_G2 /* G2 */, TFT_G3 /* G3 */, TFT_G4 /* G4 */, TFT_G5 /* G5 */, TFT_R0 /* R0 */, TFT_R1 /* R1 */, + TFT_R2 /* R2 */, TFT_R3 /* R3 */, TFT_R4 /* R4 */, 1 /* hsync_polarity */, 20 /* hsync_front_porch */, + 2 /* hsync_pulse_width */, 0 /* hsync_back_porch */, 1 /* vsync_polarity */, 30 /* vsync_front_porch */, + 8 /* vsync_pulse_width */, 1 /* vsync_back_porch */, 10 /* pclk_active_neg */, 6000000L /* prefer_speed */, + false /* useBigEndian */, 0 /* de_idle_high*/, 0 /* pclk_idle_high */); - tft = new Arduino_RGB_Display(TFT_WIDTH /* width */, TFT_HEIGHT /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */, - bus, -1 /* RST */, st7701_t_panel_init_operations, sizeof(st7701_t_panel_init_operations)); + tft = new Arduino_RGB_Display(TFT_WIDTH /* width */, TFT_HEIGHT /* height */, rgbpanel, 0 /* rotation */, + true /* auto_flush */, bus, -1 /* RST */, st7701_t_panel_init_operations, + sizeof(st7701_t_panel_init_operations)); #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB) Wire.begin(8 /* SDA */, 48 /* SCL */, 800000L /* speed */); @@ -63,7 +60,7 @@ void ArduinoGfx::init(int w, int h) 6 /* B1 */, 5 /* B2 */, 3 /* B3 */, 2 /* B4 */, 1 /* hsync_polarity */, 50 /* hsync_front_porch */, 1 /* hsync_pulse_width */, 30 /* hsync_back_porch */, 1 /* vsync_polarity */, 20 /* vsync_front_porch */, 1 /* vsync_pulse_width */, 30 /* vsync_back_porch */, 1 /* pclk_active_neg */); - tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, + tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, st7701_type4_init_operations, sizeof(st7701_type4_init_operations)); #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(SENSECAP_INDICATOR_D1) @@ -72,14 +69,15 @@ void ArduinoGfx::init(int w, int h) pinMode(TFT_MOSI, OUTPUT); pinMode(TFT_MISO, OUTPUT); Arduino_DataBus* bus = new Arduino_PCA9535SWSPI(TOUCH_SDA, TOUCH_SCL, 5 /* XL PWD */, 4 /* XL CS */, - TFT_SCLK /* XL SCK */, TFT_MOSI /* XL MOSI */, &Wire); + TFT_SCLK /* XL SCK */, TFT_MOSI /* XL MOSI */, &Wire); Arduino_ESP32RGBPanel* rgbpanel = new Arduino_ESP32RGBPanel( TFT_DE, TFT_VSYNC, TFT_HSYNC, TFT_PCLK, TFT_R0, TFT_R1, TFT_R2, TFT_R3, TFT_R4, TFT_G0, TFT_G1, TFT_G2, TFT_G3, TFT_G4, TFT_G5, TFT_B0, TFT_B1, TFT_B2, TFT_B3, TFT_B4, TFT_HSYNC_POLARITY, TFT_HSYNC_FRONT_PORCH, TFT_HSYNC_PULSE_WIDTH, TFT_HSYNC_BACK_PORCH, TFT_VSYNC_POLARITY, TFT_VSYNC_FRONT_PORCH, TFT_VSYNC_PULSE_WIDTH, TFT_VSYNC_BACK_PORCH); tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, - st7701_sensecap_indicator_init_operations, sizeof(st7701_sensecap_indicator_init_operations)); + st7701_sensecap_indicator_init_operations, + sizeof(st7701_sensecap_indicator_init_operations)); #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(GC9503V_DRIVER) Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); @@ -115,8 +113,8 @@ void ArduinoGfx::init(int w, int h) st7701_type1_init_operations, sizeof(st7701_type1_init_operations)); #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 272) && defined(NV3041A_DRIVER) Arduino_DataBus* bus = new Arduino_ESP32QSPI(TFT_CS, TFT_SCK, TFT_D0, TFT_D1, TFT_D2, TFT_D3); - Arduino_GFX* g = new Arduino_NV3041A(bus, TFT_RST, TFT_ROTATION, TFT_IPS); - tft = g; + Arduino_GFX* g = new Arduino_NV3041A(bus, TFT_RST, TFT_ROTATION, TFT_IPS); + tft = g; #elif 1 /* Reset is not implemented in the panel */ if(TFT_RST != GFX_NOT_DEFINED) { @@ -142,7 +140,11 @@ void ArduinoGfx::init(int w, int h) /* TFT init */ LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); - tft->begin(SPI_FREQUENCY); +#if defined(SPI_FREQUENCY) + tft->begin(SPI_FREQUENCY); // Used for SPI displays +#else + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays +#endif LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); // tft.setSwapBytes(true); /* set endianness */ LOG_INFO(TAG_TFT, F(D_SERVICE_STARTED)); From de60c0af49fe9a955082cafd1da60195d66eb8ac Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 14 Dec 2024 22:21:39 +0100 Subject: [PATCH 4/9] Add missing SPI_FREQUENCY #836 --- user_setups/esp32s3/crowpanel-hmi.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/user_setups/esp32s3/crowpanel-hmi.ini b/user_setups/esp32s3/crowpanel-hmi.ini index 74ebc05c..0651e80b 100644 --- a/user_setups/esp32s3/crowpanel-hmi.ini +++ b/user_setups/esp32s3/crowpanel-hmi.ini @@ -74,7 +74,8 @@ build_flags = -D TFT_DE=41 -D TFT_VSYNC=40 -D TFT_HSYNC=39 - -D TFT_PCLK=0 + -D TFT_PCLK=0 + -D SPI_FREQUENCY=40000000 [env:elecrow-s3-8048c070_4MB] extends = elecrow-esp32-s3-tft, flash_4mb From 7e5762d2ef8b7052367a35a6bb510b851ad7d728 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Sat, 14 Dec 2024 22:47:49 +0100 Subject: [PATCH 5/9] Better solution for #830 and #836 --- src/drv/tft/tft_defines.h | 6 +++--- src/drv/tft/tft_driver_arduinogfx.cpp | 26 ++++++++++++++------------ user_setups/esp32s3/crowpanel-hmi.ini | 1 - 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/drv/tft/tft_defines.h b/src/drv/tft/tft_defines.h index 87b02294..66904dfd 100644 --- a/src/drv/tft/tft_defines.h +++ b/src/drv/tft/tft_defines.h @@ -49,9 +49,9 @@ #define TFT_RST -1 #endif -// #ifndef SPI_FREQUENCY -// #define SPI_FREQUENCY -1 // 40000000 -// #endif +#ifndef SPI_FREQUENCY +#define SPI_FREQUENCY 40000000 +#endif #ifndef TFT_D0 #define TFT_D0 -1 diff --git a/src/drv/tft/tft_driver_arduinogfx.cpp b/src/drv/tft/tft_driver_arduinogfx.cpp index cbe8794d..7170464e 100644 --- a/src/drv/tft/tft_driver_arduinogfx.cpp +++ b/src/drv/tft/tft_driver_arduinogfx.cpp @@ -32,6 +32,7 @@ void ArduinoGfx::init(int w, int h) TFT_HEIGHT /* height */, 35 /* col offset 1 */, 0 /* row offset 1 */, 35 /* col offset 2 */, 0 /* row offset 2 */ ); + tft->begin(SPI_FREQUENCY); // Used for SPI displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_PANEL) Wire.begin(17, 18); @@ -49,6 +50,7 @@ void ArduinoGfx::init(int w, int h) tft = new Arduino_RGB_Display(TFT_WIDTH /* width */, TFT_HEIGHT /* height */, rgbpanel, 0 /* rotation */, true /* auto_flush */, bus, -1 /* RST */, st7701_t_panel_init_operations, sizeof(st7701_t_panel_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(LILYGO_T_RGB) Wire.begin(8 /* SDA */, 48 /* SCL */, 800000L /* speed */); @@ -62,6 +64,7 @@ void ArduinoGfx::init(int w, int h) 1 /* vsync_pulse_width */, 30 /* vsync_back_porch */, 1 /* pclk_active_neg */); tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, st7701_type4_init_operations, sizeof(st7701_type4_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(SENSECAP_INDICATOR_D1) Wire.begin(TOUCH_SDA, TOUCH_SCL, I2C_TOUCH_FREQUENCY); @@ -78,6 +81,7 @@ void ArduinoGfx::init(int w, int h) tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, st7701_sensecap_indicator_init_operations, sizeof(st7701_sensecap_indicator_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(GC9503V_DRIVER) Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); @@ -88,6 +92,7 @@ void ArduinoGfx::init(int w, int h) TFT_VSYNC_BACK_PORCH); tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, gc9503v_type1_init_operations, sizeof(gc9503v_type1_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) && defined(ST7701_4848S040) Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); @@ -99,6 +104,8 @@ void ArduinoGfx::init(int w, int h) tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, st7701_4848S040_init_operations, sizeof(st7701_4848S040_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays + #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 480) && defined(ST7701_DRIVER) /* More data bus class: https://github.com/moononournation/Arduino_GFX/wiki/Data-Bus-Class */ Arduino_DataBus* bus = new Arduino_SWSPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO); @@ -111,10 +118,13 @@ void ArduinoGfx::init(int w, int h) /* More display class: https://github.com/moononournation/Arduino_GFX/wiki/Display-Class */ tft = new Arduino_RGB_Display(w, h, rgbpanel, 0 /* rotation */, TFT_AUTO_FLUSH, bus, TFT_RST, st7701_type1_init_operations, sizeof(st7701_type1_init_operations)); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays + #elif(TFT_WIDTH == 480) && (TFT_HEIGHT == 272) && defined(NV3041A_DRIVER) Arduino_DataBus* bus = new Arduino_ESP32QSPI(TFT_CS, TFT_SCK, TFT_D0, TFT_D1, TFT_D2, TFT_D3); - Arduino_GFX* g = new Arduino_NV3041A(bus, TFT_RST, TFT_ROTATION, TFT_IPS); - tft = g; + tft = new Arduino_NV3041A(bus, TFT_RST, TFT_ROTATION, TFT_IPS); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays + #elif 1 /* Reset is not implemented in the panel */ if(TFT_RST != GFX_NOT_DEFINED) { @@ -133,19 +143,11 @@ void ArduinoGfx::init(int w, int h) TFT_HSYNC_PULSE_WIDTH, TFT_HSYNC_BACK_PORCH, TFT_VSYNC_POLARITY, TFT_VSYNC_FRONT_PORCH, TFT_VSYNC_PULSE_WIDTH, TFT_VSYNC_BACK_PORCH, TFT_PCLK_ACTIVE_NEG, TFT_PREFER_SPEED); - Arduino_RGB_Display_Mod* gfx = new Arduino_RGB_Display_Mod(TFT_WIDTH, TFT_HEIGHT, bus); - tft = gfx; + tft = new Arduino_RGB_Display_Mod(TFT_WIDTH, TFT_HEIGHT, bus); + tft->begin(GFX_NOT_DEFINED); // Used for RFB displays // fb = ((Arduino_RGBPanel_Mod*)tft)->getFramebuffer(); #endif - /* TFT init */ - LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); -#if defined(SPI_FREQUENCY) - tft->begin(SPI_FREQUENCY); // Used for SPI displays -#else - tft->begin(GFX_NOT_DEFINED); // Used for RFB displays -#endif - LOG_DEBUG(TAG_TFT, F("%s - %d"), __FILE__, __LINE__); // tft.setSwapBytes(true); /* set endianness */ LOG_INFO(TAG_TFT, F(D_SERVICE_STARTED)); } diff --git a/user_setups/esp32s3/crowpanel-hmi.ini b/user_setups/esp32s3/crowpanel-hmi.ini index 0651e80b..76923a7b 100644 --- a/user_setups/esp32s3/crowpanel-hmi.ini +++ b/user_setups/esp32s3/crowpanel-hmi.ini @@ -75,7 +75,6 @@ build_flags = -D TFT_VSYNC=40 -D TFT_HSYNC=39 -D TFT_PCLK=0 - -D SPI_FREQUENCY=40000000 [env:elecrow-s3-8048c070_4MB] extends = elecrow-esp32-s3-tft, flash_4mb From 1340ce19bbf478f3b13212d8ae7342b744145465 Mon Sep 17 00:00:00 2001 From: fvanroie Date: Tue, 17 Dec 2024 21:51:41 +0100 Subject: [PATCH 6/9] Update ace.js to 1.37.0 --- data/edit.htm | 2 +- data/script.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/edit.htm b/data/edit.htm index e5bf05aa..02b6ad2a 100644 --- a/data/edit.htm +++ b/data/edit.htm @@ -1 +1 @@ -openHASP File Editor
L:
  • New File
  • Upload Files
  • Edit
  • Preview
  • Download
  • Delete
\ No newline at end of file +openHASP File Editor
L:
  • New File
  • Upload Files
  • Edit
  • Preview
  • Download
  • Delete
\ No newline at end of file diff --git a/data/script.js b/data/script.js index 0644d3ea..f03b1a34 100644 --- a/data/script.js +++ b/data/script.js @@ -1 +1 @@ -var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.36.5")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`

\n ${e}\n

`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))})); \ No newline at end of file +var ctx_el;function _(e){return document.getElementById(e)}function hidectx(){_("ctx").style.display="none",ctx_el&&ctx_el.classList.remove("selitem"),ctx_el=void 0}function doesFontExist(e){var t=document.createElement("canvas"),n=t.getContext("2d"),o="abcdefghijklmnopqrstuvwxyz0123456789";n.font="72px monospace";var a=n.measureText(o).width;return n.font="72px '"+e+"', monospace",t=null,n.measureText(o).width!=a}function createEditor(e,t,n,o,a){function i(e){let t=/(?:\.([^.]+))?$/.exec(e)[1];if(void 0!==typeof t)switch(t){case"htm":case"html":return"html";case"js":return"javascript";case"cmd":case"json":case"jsonl":return"json";case"css":case"svg":case"xml":return t}return"plain_text"}void 0===n&&(n=i(t)),void 0===a&&(a="text/"+n);["basePath","modePath","themePath"].forEach((e=>{ace.config.set(e,"https://cdnjs.cloudflare.com/ajax/libs/ace/1.37.0")}));var c=ace.edit(e,{useWorker:!1,wrap:!0,indentedSoftWrap:!1,showPrintMargin:!1,highlightGutterLine:!0,useSoftTabs:0,tabSize:2});c.setFontSize(parseFloat(getComputedStyle(document.documentElement).fontSize)),c.setReadOnly(!0),c.getSession().setUndoManager(new ace.UndoManager),void 0===o&&(o=window.matchMedia&&window.matchMedia("(prefers-color-scheme: dark)").matches?"monokai":"textmate");var s=_("save"),l=_("undo"),r=_("redo"),d=_("cut"),m=_("copy"),u=_("paste"),p=_("font"),f=_("fontsize"),g="none"!==_(e).display;f.value=parseFloat(c.getFontSize()).toFixed(1),p.onchange=function(){c.setOption("fontFamily","'"+p.value+"',monospace")},f.onchange=function(){var e=parseFloat(f.value);!isNaN(e)&&e>=9&&e<=40&&c.setFontSize(e),f.value=parseFloat(c.getFontSize()).toFixed(1)};function h(){let e=!g||c.session.getSelection().isEmpty();d.disabled=e,m.disabled=e}function y(){let e=c.session.getUndoManager();s.disabled=!g||e.isClean(),l.disabled=!g||!e.hasUndo(),r.disabled=!g||!e.hasRedo()}function v(){if(void 0===t)return;const e=function(e){var t=e.getValue();try{var n=JSON.parse(t);return JSON.stringify(n)}catch(e){return t+""}}(c),n=new FormData;n.append("data",new Blob([e],{type:a}),t),fetch("/edit",{method:"POST",body:n}).then((e=>e.ok?e.text().then((e=>{console.log("Save OK /edit "+e)})):e.text().then((e=>{throw console.log("Save FAIL /edit"),new Error(e)})))).then((e=>{console.log(e),generateToast({message:"Saved "+t,background:"#ddd",color:"#000"})})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{y()}))}function x(){var e=c.getCopyText();if(window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",e);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){c.focus();try{return document.execCommand("copy")}catch(t){return console.warn("Copy to clipboard failed.",t),prompt("Copy to clipboard: Ctrl+C, Enter",e)}}}function w(e){_("name").innerHTML=e;fetch(e).then((t=>t.ok?(console.log("OK "+e),t.text()):t.text().then((e=>{throw console.log("ERROR "+url),new Error(e)})))).then((e=>{try{var t=JSON.parse(e);c.setValue(JSON.stringify(t,null,4)),console.log("parse json OK")}catch(t){c.setValue(e),console.log("parse json FAIL")}null!==_("editor")&&(_("editor").style.display="block"),null!==_("preview")&&(_("preview").style.display="none"),g=!0,c.setReadOnly(!1),c.focus(),y()})).catch((e=>{console.log(e),alert(e),c.setReadOnly(!0)})).finally((()=>{c.resize(!0),c.scrollToLine(1,!0,!0,(function(){})),c.gotoLine(1,0,!0),c.clearSelection(),c.session.getUndoManager().reset()}))}return["Courier New","Monaco","Lucida Console","Monospace","ui-monospace","Roboto Mono","Inconsolata","IBM Plex Mono","Space Mono","PT Mono","Ubuntu Mono","Nanum Gothic Coding","Cousine","Fira Mono","Share Tech Mono","Courier Prime","Anonymous Pro","Cutive Mono","Overpass Mono","Fira Code","VT323","DM Mono","Oxygen Mono","Nova Mono","B612 Mono","Spline Sans Mono","Noto Sans Mono","Major Mono Display","Azeret Mono","Red Hat Mono","Syne Mono","Xanh Mono"].sort().forEach((function(e,t){if(doesFontExist(e)){var n=document.createElement("option");n.text=e,p.add(n)}})),null!==s&&null!==l&&null!==r&&c.on("input",y),c.session.selection.on("changeCursor",h),s.onclick=v,l.onclick=e=>{c.undo()&&c.focus()},r.onclick=e=>{c.redo()&&c.focus()},d.onclick=e=>{x()&&c.execCommand("cut")},m.onclick=e=>{x()&&c.execCommand("copy")},u.onclick=function(){try{navigator.clipboard.readText().then((e=>{c.execCommand("paste",e)})).catch((e=>{u.disabled=!0}))}catch{u.disabled=!0}},c.loadUrl=(e,o)=>{n=i(t=e+o),a="text/"+n,"plain"!==n&&c.getSession().setMode("ace/mode/"+n),w(e+o)},c.hide=()=>{g=!1,y(),h(),_("editor").style.display="none"},"plain"!==n&&c.getSession().setMode("ace/mode/"+n),c.setTheme("ace/theme/"+o),c.$blockScrolling=1/0,c.commands.addCommand({name:"save",bindKey:{win:"Ctrl-S",mac:"Command-S"},exec:v,readOnly:!1}),c.commands.addCommand({name:"undo",bindKey:{win:"Ctrl-Z",mac:"Command-Z"},exec:function(){c.undo()}}),c.commands.addCommand({name:"redo",bindKey:{win:"Ctrl-Y",mac:"Command-Y"},exec:function(){c.redo()}}),void 0!==t&&w(t),c.resize(),c}function uploadFileAsync(e,t,n,o,a,i){fetchData("/edit","POST",e).then((e=>{generateToast({message:"Upload "+n+"/"+o+" "+t+" done.",background:"#ddd",color:"#000"}),n==o&&listFiles(a,i)}))}function doUpload(e,t){const n=_("upload"),o=n.files.length;if(0!==o)for(let a=0;a=0}function isText(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"txt":case"cmd":case"json":case"jsonl":case"htm":case"html":case"js":case"c":case"cpp":case"css":case"svg":case"xml":return!0}return!1}function isImage(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"bmp":case"png":case"jpg":case"gif":case"svg":return!0}return!1}function isAudio(e){if(isFolder(e))return!1;var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"wav":case"mp3":case"aac":case"m4a":case"wma":return!0}return!1}function icon(e){if(isFolder(e))return"dir";if(isImage(e))return"image";if(isAudio(e))return"audio";var t=/(?:\.([^.]+))?$/.exec(e.name)[1];if(void 0!==typeof t)switch(t){case"cmd":case"css":case"json":case"jsonl":case"ttf":return t;case"zip":case"gz":return"zip";case"html":case"htm":return"html"}return"file"}function preview(e,t){if(isImage(e)){let n=t+e.name;const o=_("preview");o.innerHTML='',o.style.display="block",ace.edit("editor").hide(),_("name").innerHTML=n}}function edit(e,t){isText(e)&&(ace.edit("editor").loadUrl(t,e.name),_("preview").style.display="none")}function url(e,t){console.log("click "+t+e.name),isImage(e)?preview(e,t):isText(e)&&edit(e,t)}async function fetchData(e,t,n,o){await fetch(e,{method:t,body:n}).then((n=>n.ok?(console.log(t+" OK "+e),n.text()):n.text().then((n=>{throw console.log(t+" FAIL "+e),new Error(n)})))).then((e=>{o&&o.remove(),console.log(e)})).catch((e=>{console.warn("AbortError"===e.name?"Promise Aborted":"Promise Rejected"),alert(e)})).finally((()=>{}))}function download(e,t){console.log("download "+t+e.name),document.getElementById("download-frame").src=t+e.name+"?download=true"}function remove(e,t,n){let o=t+e.name;isFolder(e)&&(o+="/"),console.log("remove "+o);const a=new FormData;a.append("path",o),fetchData("/edit","DELETE",a,n)}function create(e,t,n){var o=window.prompt("Create File in "+e,"");if(null==o||""==o||o.includes("/"))return;const a=new FormData;a.append("path",e+o),fetchData("/edit","PUT",a),fetch("/api/files/").then((e=>e.json())).then((o=>{t&&t.remove(),listFiles(n,e),console.log(o)}))}function upload(e,t){_("upload").onchange=()=>{doUpload(e,t)},_("upload").click()}function ctx(e,t,n,o){e.preventDefault(),ctx_el=o;let a,i=isFolder(t),c=_("ctx");c.style.display="block",a=c.getElementsByTagName("li")[0],a.onclick=i?function(){hidectx(),create(n+t.name+"/",o.children.item(1),o)}:function(){hidectx(),create(n,o.parentNode,o.parentNode.parentNode)},a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[1],i&&(a.onclick=function(){hidectx(),upload(o,n+t.name+"/")}),a.style.display=i?"block":"none",a=c.getElementsByTagName("li")[2],a.onclick=function(){edit(t,n),hidectx()},a.style.display=isText(t)?"block":"none",a=c.getElementsByTagName("li")[3],a.onclick=function(){preview(t,n),hidectx()},a.style.display=isImage(t)?"block":"none",a=c.getElementsByTagName("li")[4],a.onclick=function(){download(t,n),hidectx()},a.style.display=i?"none":"block",a=c.getElementsByTagName("li")[5],a.onclick=function(){remove(t,n,o),hidectx()},a.style.display=n?"block":"none";var s=document.body.scrollTop?document.body.scrollTop:document.documentElement.scrollTop,l=document.body.scrollLeft?document.body.scrollLeft:document.documentElement.scrollLeft,r=e.clientX+l+10,d=e.clientY+s-20,m=(c.offsetWidth,c.offsetHeight),u=document.documentElement.clientHeight;d+m>u&&(d=u-m-20),c.style.left=r+"px",c.style.top=d+"px",o&&o.classList.add("selitem")}function drag(e,t,n){let o=n+t.name;isFolder(t)&&(o+="/"),e.dataTransfer.setData("text",o),console.log("drag start "+o)}function drop(e,t){let n=e.dataTransfer.getData("text");n.startsWith(t)||(e.preventDefault(),console.log("Move "+n+" to "+t))}function listFiles(e,t){return console.log("listFiles"),fetch("/api/files/?dir="+t).then((e=>e.json())).then((n=>{if(0==n.length)return!1;let o=e.getElementsByTagName("div")[0];o&&(o.onclick=n=>{i.remove(),o.onclick=()=>{listFiles(e,t)},n.stopPropagation()});let a=e.getElementsByTagName("ul");for(let e=0;e{drag(event,e,t)},a.appendChild(s),s.innerHTML=''+o+"",isFolder(e)){let n=t+e.name+"/";s.classList.add("bold"),s.onclick=function(e){listFiles(a,n)},s.ondragover=e=>{e.preventDefault()},s.ondrop=e=>{drop(e,n)}}else(isText(e)||isImage(e)||isAudio(e))&&(s.onclick=function(n){url(e,t)});s.oncontextmenu=n=>{ctx(n,e,t,a)}}return e.scrollIntoView(),!0}))}function generateToast({message:e,background:t="#00214d",color:n="#fffffe",length:o="7000ms"}){_("toast").insertAdjacentHTML("afterbegin",`

\n ${e}\n

`);const a=_("toast").firstElementChild;a.addEventListener("animationend",(()=>a.remove()))}document.addEventListener("blur",(function(){hidectx()})),document.addEventListener("DOMContentLoaded",(function(){createEditor("editor",void 0,void 0,void 0);listFiles(_("tree"),"/"),_("tree").getElementsByTagName("div")[0].oncontextmenu=e=>{ctx(e,{name:"",children:[]},"",_("tree"))},_("load").onclick=function(e){const t=new FormData;t.append("load",""),fetchData("/edit","PUT",t)},_("init").onclick=function(e){const t=new FormData;t.append("init",""),fetchData("/edit","PUT",t)},_("home").onclick=function(e){window.location.href="/"},_("page").onchange=function(e){const t=new FormData;t.append("page",_("page").value),fetchData("/edit","PUT",t)}})),document.addEventListener("DOMContentLoaded",(function(){const e=document.getElementById("dragMe"),t=e.previousElementSibling,n=e.nextElementSibling;let o=0,a=0,i=0;const c=function(a){const c=a.clientX-o,s=(a.clientY,100*(i+c)/e.parentNode.getBoundingClientRect().width);t.style.width=`${s}%`,t.style.right=t.style.width,e.style.cursor="col-resize",document.body.style.cursor="col-resize",t.style.userSelect="none",t.style.pointerEvents="none",n.style.userSelect="none",n.style.pointerEvents="none",ace.edit("editor").resize()},s=function(){e.style.removeProperty("cursor"),document.body.style.removeProperty("cursor"),t.style.removeProperty("user-select"),t.style.removeProperty("pointer-events"),n.style.removeProperty("user-select"),n.style.removeProperty("pointer-events"),document.removeEventListener("mousemove",c),document.removeEventListener("mouseup",s)};e.addEventListener("mousedown",(function(e){o=e.clientX,a=e.clientY,i=t.getBoundingClientRect().width,document.addEventListener("mousemove",c),document.addEventListener("mouseup",s)})),e.addEventListener("dblclick",(()=>{var e=t.style.visibility="hidden"===t.style.visibility;t.style.visibility=e?"unset":"hidden",t.style.position=e?"unset":"absolute",ace.edit("editor").resize()}))})); \ No newline at end of file From 1e85b3cd46e163d4c9090006c51d9efd79838e0e Mon Sep 17 00:00:00 2001 From: psyko_chewbacca Date: Sun, 22 Dec 2024 00:42:09 -0500 Subject: [PATCH 7/9] Initial support for Guiton ESP32-2432S022C --- src/drv/tft/tft_driver_lovyangfx.cpp | 67 +++++++++++++++++++++++++++ user_setups/esp32/esp32-2432s022c.ini | 64 +++++++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 user_setups/esp32/esp32-2432s022c.ini diff --git a/src/drv/tft/tft_driver_lovyangfx.cpp b/src/drv/tft/tft_driver_lovyangfx.cpp index bc3854f9..371c7718 100644 --- a/src/drv/tft/tft_driver_lovyangfx.cpp +++ b/src/drv/tft/tft_driver_lovyangfx.cpp @@ -805,6 +805,73 @@ void LovyanGfx::init(int w, int h) cfg.pin_mosi = TOUCH_MOSI; cfg.pin_miso = TOUCH_MISO; cfg.pin_cs = TOUCH_CS; + _touch_instance->config(cfg); + _panel_instance->setTouch(_touch_instance); + } +#elif defined(ESP32_2432S022C) + //pinMode(PWR_EN, OUTPUT); + //digitalWrite(PWR_EN, HIGH); + + auto _panel_instance = new lgfx::Panel_ST7789(); + auto _bus_instance = new lgfx::Bus_Parallel8(); + auto _touch_instance = new lgfx::Touch_CST816S(); + { + auto cfg = _bus_instance->config(); + cfg.freq_write = 16000000; + cfg.pin_wr = TFT_WR; + cfg.pin_rd = TFT_RD; + cfg.pin_rs = TFT_DC; // D/C + cfg.pin_d0 = TFT_D0; + cfg.pin_d1 = TFT_D1; + cfg.pin_d2 = TFT_D2; + cfg.pin_d3 = TFT_D3; + cfg.pin_d4 = TFT_D4; + cfg.pin_d5 = TFT_D5; + cfg.pin_d6 = TFT_D6; + cfg.pin_d7 = TFT_D7; + _bus_instance->config(cfg); + _panel_instance->setBus(_bus_instance); + } + + { + auto cfg = _panel_instance->config(); + cfg.pin_cs = TFT_CS; + cfg.pin_rst = TFT_RST; + cfg.pin_busy = TFT_BUSY; + cfg.memory_width = TFT_WIDTH; + cfg.memory_height = TFT_HEIGHT; + cfg.panel_width = TFT_WIDTH; + cfg.panel_height = TFT_HEIGHT; + cfg.offset_x = 0; + cfg.offset_y = 0; + cfg.offset_rotation = TFT_ROTATION; + cfg.dummy_read_pixel = 8; + cfg.dummy_read_bits = 1; + cfg.readable = true; + cfg.invert = false; + cfg.rgb_order = false; + cfg.dlen_16bit = false; + cfg.bus_shared = false; + _panel_instance->config(cfg); + } + + { + auto cfg = _touch_instance->config(); + + cfg.x_min = 0; + cfg.x_max = TFT_WIDTH; + cfg.y_min = 0; + cfg.y_max = TFT_HEIGHT; + cfg.pin_int = TOUCH_IRQ; + cfg.bus_shared = true; + cfg.offset_rotation = 0; + + cfg.i2c_port = I2C_TOUCH_PORT; + cfg.i2c_addr = I2C_TOUCH_ADDRESS; + cfg.pin_sda = TOUCH_SDA; + cfg.pin_scl = TOUCH_SCL; + cfg.freq = I2C_TOUCH_FREQUENCY; + _touch_instance->config(cfg); _panel_instance->setTouch(_touch_instance); } diff --git a/user_setups/esp32/esp32-2432s022c.ini b/user_setups/esp32/esp32-2432s022c.ini new file mode 100644 index 00000000..f6bac492 --- /dev/null +++ b/user_setups/esp32/esp32-2432s022c.ini @@ -0,0 +1,64 @@ +[env:esp32-2432s022c] +extends = arduino_esp32_v2, flash_4mb +board = esp32dev +upload_speed = 921600 + +build_flags = + ${arduino_esp32_v2.build_flags} + ${esp32.no_ps_ram} + +;region -- TFT_eSPI build options ------------------------ + -D ESP32_2432S022C=1 + -D LGFX_USE_V1=1 +; -D USER_SETUP_LOADED=1 + -D ST7789_DRIVER=1 +; -D CGRAM_OFFSET=1 +; -DSUPPORT_TRANSACTIONS + -D TFT_INVERSION_OFF + -D TFT_PARALLEL_8_BIT + -D TFT_ROTATION=0 ; 0=0, 1=90, 2=180 or 3=270 degree + -D TFT_WIDTH=240 + -D TFT_HEIGHT=320 + -D TFT_CS=17 ; Chip select control pin=library pulls permanently low + -D TFT_DC=16 ; Data Command control pin + -D TFT_RST=-1 ; Reset pin, toggles on startup + -D TFT_WR=4 ; Write strobe control pin + -D TFT_RD=2 ; Read strobe control pin + -D TFT_D0=15 + -D TFT_D1=13 + -D TFT_D2=12 + -D TFT_D3=14 + -D TFT_D4=27 + -D TFT_D5=25 + -D TFT_D6=33 + -D TFT_D7=32 + -D TFT_BCKL=0 ; LED back-light + + ;CST816S driver + -D TOUCH_DRIVER=0x816 + -D HASP_USE_LGFX_TOUCH=1 + -D I2C_TOUCH_PORT=I2C_NUM_0 + -D TOUCH_SDA=21 + -D TOUCH_SCL=22 + -D TOUCH_IRQ=-1 + -D TOUCH_RST=-1 + -D I2C_TOUCH_FREQUENCY=400000 + -D I2C_TOUCH_ADDRESS=0x15 + + + -D SD_MISO=19 + -D SD_MOSI=23 + -D SD_SCLK=18 + -D SD_CS=5 + + ; sound output is on IO26, through an SC8002B IC + +; -- Debugging options ----------------------------- +; -D CORE_DEBUG_LEVEL=ARDUHAL_LOG_LEVEL_DEBUG +;endregion + +lib_deps = + ${arduino_esp32_v2.lib_deps} + ${lovyangfx.lib_deps} + ;${tft_espi.lib_deps} + From bddbc3cb395aa5b637c5f8e16311f0dd9c984e7d Mon Sep 17 00:00:00 2001 From: fvanroie Date: Mon, 23 Dec 2024 15:21:22 +0100 Subject: [PATCH 8/9] Add esp32-2432s022c_4MB --- .github/workflows/build.yaml | 2 +- user_setups/esp32/esp32-2432s022c.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index cbb5c4e9..6dbd3fe6 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -52,7 +52,7 @@ jobs: - out: seeed-studios env: "sensecap-indicator-d1_8MB" - out: sunton - env: "esp32-2432s028r_4MB -e esp32-2432s028r-ili9342_4MB -e esp32-2432s028r_v2_4MB -e esp32-2432s032c_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB" + env: "esp32-2432s022c_4MB -e esp32-2432s028r_4MB -e esp32-2432s028r-ili9342_4MB -e esp32-2432s028r_v2_4MB -e esp32-2432s032c_4MB -e esp32-3248s035c_4MB -e esp32-3248s035r_4MB -e sunton-4827s043c_16MB -e sunton-8048s043c_16MB -e sunton-8048s050c_16MB -e sunton-8048s070c_16MB" - out: waveshare env: "esp32-one_ili9486 -e esp32-one_st7796 -e ws_esp32_s3_touch_lcd_4p3" - out: wireless-tag diff --git a/user_setups/esp32/esp32-2432s022c.ini b/user_setups/esp32/esp32-2432s022c.ini index f6bac492..aaecc02e 100644 --- a/user_setups/esp32/esp32-2432s022c.ini +++ b/user_setups/esp32/esp32-2432s022c.ini @@ -1,4 +1,4 @@ -[env:esp32-2432s022c] +[env:esp32-2432s022c_4MB] extends = arduino_esp32_v2, flash_4mb board = esp32dev upload_speed = 921600 From 3eda5a4225e933d65ecd4044759b9b4b504bb72d Mon Sep 17 00:00:00 2001 From: fvanroie Date: Mon, 23 Dec 2024 17:13:27 +0100 Subject: [PATCH 9/9] Fix for #839 --- src/hasp/hasp.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hasp/hasp.cpp b/src/hasp/hasp.cpp index 4e0f4eef..c0206764 100644 --- a/src/hasp/hasp.cpp +++ b/src/hasp/hasp.cpp @@ -111,7 +111,8 @@ lv_font_t* hasp_get_font(uint8_t fontid) */ HASP_ATTRIBUTE_FAST_MEM void hasp_update_sleep_state() { - if(hasp_first_touch_state) return; // don't update sleep when first touch is still active + // Don't fast exit, see issue #839 + // if(hasp_first_touch_state) return; // don't update sleep when first touch is still active uint32_t idle = lv_disp_get_inactive_time(lv_disp_get_default()) / 1000; idle += sleepTimeOffset; // To force a specific state