src/main.cpp:52:        Serial.print(".");
src/main.cpp:57:        Serial.println();
src/main.cpp:151:        Serial.print(".");
src/main.cpp:294:    Serial.println(F("─────────────────"));
src/main.cpp:317:    Serial.begin(115200);
src/main.cpp:320:    Serial.println(F("\n"));
src/main.cpp:321:    Serial.println(F("╔══════════════════════════════════════════╗"));
src/main.cpp:322:    Serial.println(F("║  🏥 五劳无感康养监测系统 v1.0.0       ║"));
src/main.cpp:324:    Serial.println(F("║  MQTT 协议 V0.08                        ║"));
src/main.cpp:325:    Serial.println(F("╚══════════════════════════════════════════╝"));
src/main.cpp:370:    Serial.println(F("[Setup] ✅ 系统就绪"));
src/main.cpp:371:    Serial.println(F("══════════════════════════════════════════\n"));
src/mqtt_manager.cpp:44:    Serial.printf("  GateID: %s\n", _gateid);
src/mqtt_manager.cpp:45:    Serial.printf("  Broker: %s:%d\n", _server, _port);
src/mqtt_manager.cpp:392:    Serial.printf("[MQTT] 📩 [%s]\n", topic);
src/sensor_manager.cpp:46:    Serial.printf("  DHT11: T=%.1f°C H=%.1f%% 有效=%d\n",
src/wifi_manager.cpp:42:    Serial.println(F("\n========================================"));
src/wifi_manager.cpp:44:    Serial.println(F("========================================"));
src/wifi_manager.cpp:186:        Serial.printf("  SSID: %s\n", WiFi.SSID().c_str());
src/wifi_manager.cpp:187:        Serial.printf("  IP:   %s\n", WiFi.localIP().toString().c_str());


Remaining English in Serial output:
1. `[Setup]` → `[系统]` (main.cpp:370)
2. `GateID:` → `网关ID:` (mqtt_manager.cpp:44)
3. `Broker:` → `服务器:` (mqtt_manager.cpp:45)
4. `SSID:` → already universal term, but could change to `WiFi名称:`
5. `IP:` → universal, fine as-is
6. `MAC:` → universal
7. `DHT11:` → this is the sensor name, keeping is fine
8. `MQTT 协议 V0.08` - the "MQTT" is a protocol name, V0.08 is version - fine as-is

Let me fix the remaining ones.


The file d:\PlatformIO1\Projects\Healthv2.0\src\main.cpp has been updated successfully. (file state is current in your context — no need to Read it back)

-    Serial.println(F("[Setup] ✅ 系统就绪"));

Serial.println(F("══════════════════════════════════════════\n"));


Edit

    Serial.printf("  GateID: %s\n", _gateid);
    Serial.printf("  Broker: %s:%d\n", _server, _port);

    Serial.printf("  网关ID: %s\n", _gateid);
    Serial.printf("  服务器: %s:%d\n", _server, _port);


The file d:\PlatformIO1\Projects\Healthv2.0\src\mqtt_manager.cpp has been updated successfully. (file state is current in your context — no need to Read it back)

    Serial.printf("  GateID: %s\n", _gateid);
    Serial.printf("  Broker: %s:%d\n", _server, _port);

    Serial.printf("  网关ID: %s\n", _gateid);
    Serial.printf("  服务器: %s:%d\n", _server, _port);

strncpy(_gateid, gateid, sizeof(_gateid) - 1);

Serial.println(F("[MQTT] 初始化 (协议 V0.08)"));

-    Serial.printf("  GateID: %s\n", _gateid);

-    Serial.printf("  Broker: %s:%d\n", _server, _port);

+    Serial.printf("  网关ID: %s\n", _gateid);

+    Serial.printf("  服务器: %s:%d\n", _server, _port);


TodoWrite

所有源文件串口日志和注释汉化


Todos have been modified successfully. Ensure that you continue to use the todo list to track your progress. Please proceed with the current tasks if applicable

所有源文件串口日志和注释汉化


全部完成。以下是所有修改的汇总：

---

### 修改汇总（6 个文件，约 40 处改动）

| 原英文 | 改为中文 | 涉及文件 |
|---|---|---|
| `[NTP]` | `[时间]` | main.cpp |
| `[Provision]` | `[配网]` | main.cpp |
| `[Control]` | `[控制]` | main.cpp |
| `[Task]` | `[任务]` | main.cpp |
| `[Setup]` | `[系统]` | main.cpp |
| `[Alarm]` | `[告警]` | alarm_manager.cpp |
| `[Sensor]` | `[传感器]` | sensor_manager.cpp |
| `[Radar]` | `[雷达]` | radar_manager.cpp |
| `level=%s, buzzer=%d` | `等级=%s, 蜂鸣器=%d` | alarm_manager.cpp |
| `Alarm JSON` | `告警指令 JSON` | mqtt_manager.cpp |
| `Control JSON` | `控制指令 JSON` | mqtt_manager.cpp |
| `Provision JSON` | `配网指令 JSON` | mqtt_manager.cpp |
| `GateID` / `Broker` | `网关ID` / `服务器` | mqtt_manager.cpp |
| `(DHT:%d)` | `(温湿度:%d)` | main.cpp |
| `(Radar:%d)` | `(雷达:%d)` | main.cpp |
| `(Vital:%d)` | `(体征:%d)` | main.cpp |
| `(Rain:%d)` | `(水浸有效:%d)` | main.cpp |
| `valid=%d` | `有效=%d` | sensor_manager.cpp |
| `Portal` / `Core 0/1` / `NTP` | `配网页面` / `核心0/1` / `时间` | wifi_manager.cpp, main.cpp (注释) |
| WiFiManager 配网页面标题 | `🏥 五劳无感康养监测 - 设备配网` | wifi_manager.cpp |

**保持不变的部分**（协议层面，不能改）：
- MQTT 主题路径 (`status/%s/provision` 等) — 与服务器协议绑定
- `SSID`、`IP`、`MAC`、`DHT11` — 通用技术术语


把所有的都换成中文，配网界限还有一些数据


<ide_opened_file>The user opened the file d:\PlatformIO1\Projects\Healthv2.0\data\index.html in the IDE. This may or may not be related to the current task.</ide_opened_file>

为啥还和之前一样，开始界面，连接wifi啥的字还是英文


The user is saying that the WiFiManager captive portal page (the web page that appears on the phone when connecting to the device's AP for provisioning) is still showing English text. They mention "开始界面" (start page) and "连接wifi" (connect WiFi) text is still in English.

This is the WiFiManager library's built-in captive portal HTML page. The WiFiManager library by tzapu has hardcoded English HTML templates. We already set `setTitle()` and `setCustomHeadElement()`, but those only change the page title and add CSS - they don't change the actual page content text.

The default WiFiManager portal page has text like:
- "Configure WiFi"
- "WiFi SSID"
- "WiFi Password"
- "Scan"
- "Save"
- "Reset"
- etc.

To fully localize the portal page, we need to look at what the WiFiManager v2.0.17 supports. Let me check if there's a way to override the HTML completely or if there are other customization options.

Looking at the WiFiManager library, the HTML is generated in the `WiFiManager.cpp` file. The library doesn't have a built-in i18n/localization feature. However, we can:

1. Use `setCustomMenuHTML()` to add custom menu items
2. The actual WiFi form page HTML is hardcoded

But wait - the user mentioned `data\index.html` in the IDE. Let me check if there's a custom web page in the project's data directory that might be served instead, or if the project has its own web server.

Actually, looking at the platformio.ini, this is an ESP32-S3 project. The `data/` directory typically contains SPIFFS/LittleFS web files. Let me check that file!


让我看看用户打开的文件和 WiFiManager 配网页面的情况。


1	<!DOCTYPE html>
2
3
4	    <meta charset="UTF-8">
5	    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
6	    <title>健康监测系统 - 配网设置</title>
7
249
250
251

252
253

254
🏥

255
健康监测系统

256
ESP32-S3 + 毫米波雷达 · 配网设置

257

258
259
260

261

262	                📶 WiFi 设置
263

264

265	                WiFi 名称 (SSID)
266	                <input type="text" id="wifi-ssid" placeholder="请输入 WiFi 名称" autocomplete="off">
267

268

269	                WiFi 密码
270	                <input type="password" id="wifi-pass" placeholder="请输入 WiFi 密码">
271

272

273
274
275

276

277	                ☁ MQTT 云平台设置
278

279

280	                MQTT 服务器地址
281	                <input type="text" id="mqtt-server" placeholder="例如: 192.168.1.100" value="192.168.1.100">
282

283

284	                MQTT 端口
285	                <input type="number" id="mqtt-port" placeholder="1883" value="1883">
286

287

288	                MQTT 用户名 (可选)
289	                <input type="text" id="mqtt-user" placeholder="用户名">
290

291

292	                MQTT 密码 (可选)
293	                <input type="password" id="mqtt-pass" placeholder="密码">
294

295

296
297
298

299

300	                🏠 环境备注
301

302

303	                设备位置 / 房间名称
304	                <input type="text" id="env-note" placeholder="例如: 主卧 / 客厅 / 老人房 / 婴儿房" value="主卧">
305

306

307	                💡 请备注此设备安装的环境位置，方便在云平台上区分不同房间的数据
308

309

310
311
312

313

314	                📱 设备设置
315

316

317	                设备名称 / ID
318	                <input type="text" id="device-id" placeholder="例如: health_001" value="health_001">
319

320

321
322
323	        <button class="btn-submit" onclick="submitConfig()">
324	            💾 保存配置并连接
325	        </button>
326	        <button class="btn-reset" onclick="resetConfig()">
327	            🔄 恢复出厂设置
328	        </button>
329
330
331

332	             等待配置...
333

334

335
336
337

338
339
460
461
462

<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>健康监测系统 - 配网设置</title>

🏥

健康监测系统

ESP32-S3 + 毫米波雷达 · 配网设置

                📶 WiFi 设置

                WiFi 名称 (SSID)
                <input type="text" id="wifi-ssid" placeholder="请输入 WiFi 名称" autocomplete="off">

                WiFi 密码
                <input type="password" id="wifi-pass" placeholder="请输入 WiFi 密码">

                ☁ MQTT 云平台设置

                MQTT 服务器地址
                <input type="text" id="mqtt-server" placeholder="例如: 192.168.1.100" value="192.168.1.100">

                MQTT 端口
                <input type="number" id="mqtt-port" placeholder="1883" value="1883">

                MQTT 用户名 (可选)
                <input type="text" id="mqtt-user" placeholder="用户名">

                MQTT 密码 (可选)
                <input type="password" id="mqtt-pass" placeholder="密码">

                🏠 环境备注

                设备位置 / 房间名称
                <input type="text" id="env-note" placeholder="例如: 主卧 / 客厅 / 老人房 / 婴儿房" value="主卧">

                💡 请备注此设备安装的环境位置，方便在云平台上区分不同房间的数据

                📱 设备设置

                设备名称 / ID
                <input type="text" id="device-id" placeholder="例如: health_001" value="health_001">

        <button class="btn-submit" onclick="submitConfig()">
            💾 保存配置并连接
        </button>
        <button class="btn-reset" onclick="resetConfig()">
            🔄 恢复出厂设置
        </button>

             等待配置...


为啥还和之前一样，开始界面，连接wifi啥的字还是英文


data\index.html


OK, now I see the situation. There are TWO different things:

1. **`data/index.html`** — This is a beautifully crafted Chinese-language custom web page that's stored in the LittleFS data directory. It's already fully in Chinese! But this page is NOT currently being served by anything — it's sitting in the `data/` directory but the WiFiManager library uses its own hardcoded HTML, not this custom page.

2. **WiFiManager's built-in captive portal** — When the user connects to the ESP32's AP ("HealthMonitor-Setup"), they see the default WiFiManager page which is in English. This is what the user is complaining about.

The project has a beautiful custom Chinese `index.html` in the `data/` directory but it's not being used! The WiFiManager library has its own hardcoded HTML that it serves.

To fix this, we need to:
1. Either serve the custom `index.html` through WiFiManager's web server somehow
2. Or start a separate web server when the WiFiManager AP mode is active
3. Or use WiFiManager's `setCustomMenuHTML()` to inject custom HTML

Actually, looking at this more carefully, WiFiManager v2.0.17 has limited ability to customize the main WiFi config page. The library serves its own built-in HTML for the WiFi form. While we can set title and custom head elements, the main form content (SSID field, password field, save button, etc.) is hardcoded in English.

The best approach would be to:
1. Run a separate AsyncWebServer on the ESP32 that serves this custom `index.html`
2. Or use the WiFiManager's web server and redirect to the custom page
3. Or use the WiFiManager API to submit WiFi credentials from the custom page

Wait, actually the simplest approach might be different. Looking at the WiFiManager library, it creates its own web server. The custom `index.html` in `data/` seems to be designed to work as a standalone page or with a custom server.

Let me think about the practical approach:

Option A: Use the custom `index.html` as WiFiManager's custom menu HTML via `setCustomMenuHTML()`. But this would only show as an extra menu item, not replace the main WiFi page.

Option B: Set up a separate web server on the ESP32 (like ESPAsyncWebServer) that serves the custom `index.html` from LittleFS, and have it handle the WiFi config submission by calling WiFiManager's WiFi saving functions.

Option C: Override WiFiManager's internal web server handling. This is complex and fragile.

Actually, looking at the WiFiManager library more carefully, in newer versions (2.0.x), when parameters are shown, they appear on a separate "Setup" page. But the initial "Configure WiFi" page with SSID/password fields is still the default English one.

The most practical approach is to use the ESP32's ability to run both WiFiManager and a separate web server. Or, better yet, to use WiFiManager in a way where we start the config portal but also serve our custom HTML.

Actually, wait. Let me re-read the situation. The user already has a `data/index.html` that's fully Chinese. This is clearly meant to be the captive portal page. But currently the project uses WiFiManager which has its own English HTML.

The solution: We need to either:
1. Serve this custom HTML through WiFiManager somehow
2. Or replace WiFiManager's web serving with our own

Looking at the WiFiManager API more carefully:
- `startConfigPortal()` starts the DNS server and web server
- The web server serves hardcoded HTML for the root page
- We can customize some parts but not replace the whole thing

The best approach for this project would be to:
1. Upload the `data/index.html` to LittleFS on the ESP32
2. Instead of using WiFiManager's built-in web server, start a custom web server (like ESPAsyncWebServer or even WiFiServer) that serves this HTML
3. When the user submits the form, call WiFiManager's API or directly call WiFi.begin() and save config

But this is a significant architectural change. Let me think of a simpler approach...

Actually, WiFiManager has a non-blocking mode. We could:
1. Start WiFiManager in non-blocking mode (or use `startConfigPortal()` which blocks)
2. While WiFiManager's portal is running, we can't easily serve our own pages because WiFiManager takes over the web server (port 80)

Wait, let me look at this differently. The WiFiManager library's captive portal is a feature - it handles DNS redirection and serves the config page. But the user wants a Chinese page.

One practical approach: The `data/index.html` file already exists and is fully Chinese. The issue is getting it served. We could:

1. Convert the project to NOT use WiFiManager's built-in web UI, and instead use a custom web server approach
2. Or, find a way to make WiFiManager serve our custom page

Actually, looking at the WiFiManager source code again, it creates a `WiFiServer` (or `WebServer` on ESP32). The page content is generated in the `handleRequest()` or similar function. There's no easy way to replace the page content.

But here's an idea: WiFiManager supports `setCustomHeadElement()` which injects HTML into the `<head>`. And it has `setCustomMenuHTML()` which adds a custom menu item/page. But these don't replace the main WiFi config page.

The cleanest solution I think is:
1. Keep using WiFiManager for its WiFi connection management, DNS captive portal, and parameter storage
2. BUT override the web serving with our own by using a separate AsyncWebServer

Actually, this is getting too complex. Let me check if there's a simpler way.

Actually, re-reading the WiFiManager docs more carefully, I see that `setConfigPortalBlocking(false)` allows non-blocking mode. And `process()` handles the DNS/web server loop. But we can't serve our own pages because WiFiManager takes over port 80.

Hmm, wait. Let me look at an alternative approach. The WiFiManager library on ESP32 uses the `WebServer` class (ESP32's built-in web server, not to be confused with ESP8266WebServer). Maybe we can modify how it works.

Actually, the most straightforward approach is:
1. Start the config portal with `_wm.startConfigPortal()` in blocking mode
2. The default WiFiManager page will be in English - BUT WiFiManager also accepts HTTP POST to `/save` or similar endpoints
3. So a user could theoretically load the custom HTML page from... hmm, but how?

Wait, I think I'm overcomplicating this. Let me check if WiFiManager's `startConfigPortal()` can be configured to use a custom HTML page.

Looking at the WiFiManager library code:
- The main page HTML is generated in `handleWifi()` and related methods
- There's no `setCustomIndexHTML()` or similar API

So the options are:
1. Fork/modify the WiFiManager library (bad idea)
2. Create a custom web server that runs alongside WiFiManager's DNS
3. Use WiFiManager's non-blocking mode and serve custom pages on a different port
4. Submit a PR to WiFiManager to support custom HTML (too slow)
5. Just accept the WiFiManager default page but supplement it with other methods

Actually, wait. Let me look at the system from the user's perspective again:

The user connects to "HealthMonitor-Setup" AP → phone shows captive portal → they see English WiFiManager page.

What if instead of WiFiManager's built-in portal, we:
1. Use the device as an AP with a known SSID
2. Serve the custom `index.html` using a simple `WiFiServer` + `WiFiClient` approach (or `WebServer` library)
3. Handle the form submission by saving to LittleFS and calling `WiFi.begin()`
4. Handle DNS redirection (captive portal detection) with a simple DNS server

This would give us full control over the HTML. But it's a significant amount of work and would duplicate WiFiManager's functionality.

Alternatively, a much simpler approach: modify the WiFiManager library's HTML in-place. Since it's in the `.pio/libdeps` directory, we could patch the WiFiManager source. But this would be overwritten when the library updates.

Actually, let me look at this from a completely different angle. The WiFiManager library (`tzapu/WiFiManager@^2.0.17`) generates HTML text in its `.cpp` file. We could copy the relevant HTML generation code from WiFiManager, modify it to Chinese, and... no, that's not practical.

OK here's what I think the right approach is:

1. The project already has a beautiful `data/index.html` that's fully Chinese
2. We should set up a proper web server that serves this page
3. Use WiFiManager primarily for its WiFi connection management (auto-connect, timeout, etc.) rather than its web UI
4. Or, use WiFiManager's non-blocking mode and run a custom web server on a different port for the actual config UI

But actually, for the simplest fix that the user is asking for: the WiFiManager default page is in English. Let me look if there are localization-related defines in WiFiManager's source that we could override.

Let me check the WiFiManager source for the English text strings that appear on the portal page.


明白了！问题在于 `data/index.html` 已经是完美的中文页面，但 WiFiManager 库自带的是英文内置页面，并没有使用这个自定义页面。

让我检查 WiFiManager 内置页面的英文文本和自定义选项。


Grep

Configure WiFi|WiFi SSID|WiFi Password|Scan|to configure|No networks|connect to|Save|Reset|Update|Info|Exit|Close|custom|setup


<persisted-output>
Output too large (29.5KB). Full output saved to: C:\Users\杨志佳\.claude\projects\d--PlatformIO1-Projects-Healthv2-0\49fba966-60be-4542-a6c1-b5b7e0e566bb\tool-results\call_00_NlqJltSAJ0kGBi5y69Br0619.txt

Preview (first 2KB):
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:31:WiFiManagerParameter::WiFiManagerParameter(const char *custom) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:37:  _customHTML     = custom;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:48:WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:49:  init(id, label, defaultValue, length, custom, WFM_LABEL_DEFAULT);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:52:WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:53:  init(id, label, defaultValue, length, custom, labelPlacement);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:56:void WiFiManagerParameter::init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:60:  _customHTML     = custom;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:124:const char* WiFiManagerParameter::getCustomHTML() const {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:125:  return _customHTML;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:159:    DEBUG_WM(WM_DEBUG_DEV,F("Updated _max_params:"),_max_params);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:220:  if(_debug && _debugLevel >= WM_DEBUG_DEV) debugPlatformInfo();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:254:  WiFi.persistent(false); // disable persistent so scannetworks and mode switching do not cause overwrites
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:283:  // bool wifiIsSaved = getWiFiIsSaved();
...
</persisted-output>

.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:31:WiFiManagerParameter::WiFiManagerParameter(const char *custom) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:37:  _customHTML     = custom;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:48:WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:49:  init(id, label, defaultValue, length, custom, WFM_LABEL_DEFAULT);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:52:WiFiManagerParameter::WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:53:  init(id, label, defaultValue, length, custom, labelPlacement);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:56:void WiFiManagerParameter::init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:60:  _customHTML     = custom;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:124:const char* WiFiManagerParameter::getCustomHTML() const {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:125:  return _customHTML;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:159:    DEBUG_WM(WM_DEBUG_DEV,F("Updated _max_params:"),_max_params);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:220:  if(_debug && _debugLevel >= WM_DEBUG_DEV) debugPlatformInfo();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:254:  WiFi.persistent(false); // disable persistent so scannetworks and mode switching do not cause overwrites
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:283:  // bool wifiIsSaved = getWiFiIsSaved();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:284:  bool wifiIsSaved = true; // workaround until I can check esp32 wifiisinit and has nvs
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:287:  setupHostname(true);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:302:  // check if wifi is saved, (has autoconnect) to speed up cp start
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:304:  if(wifiIsSaved){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:308:    // attempt to connect using saved settings, on fail fallback to AP config portal
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:320:    if(esp32persistent) WiFi.persistent(false); // disable persistent for esp32 after esp_wifi_start or else saves wont work
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:332:      setupHostname(true);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:338:    // @todo check if correct ssid == saved ssid when already connected
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:374:    DEBUG_WM(F("No Credentials are Saved, skipping connect"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:392:bool WiFiManager::setupHostname(bool restart){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:455:    // WiFi.reconnect(); // This does not reset dhcp
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:457:    delay(200); // do not remove, need a delay for disconnect to change status()
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:481:  // setup optional soft AP static ip config
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:484:    DEBUG_WM(F("Custom AP IP/GW/Subnet:"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:560:  setupConfigPortal();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:618:void WiFiManager::setupHTTPServer(){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:626:    DEBUG_WM(WM_DEBUG_VERBOSE,F("http server started with custom port: "),_httpPort); // @todo not showing ip
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:630:  server.reset(new WM_WebServer(_httpPort));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:631:  // This is not the safest way to reset the webserver, it can cause crashes on callbacks initilized before this and since its a shared pointer...
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:641:  /* Setup httpd callbacks, web pages: root, wifi config pages, SO captive portal detectors and not found. */
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:646:  server->on(WM_G(R_wifinoscan), std::bind(&WiFiManager::handleWifi, this, false));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:647:  server->on(WM_G(R_wifisave),   std::bind(&WiFiManager::handleWifiSave, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:648:  server->on(WM_G(R_info),       std::bind(&WiFiManager::handleInfo, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:650:  server->on(WM_G(R_paramsave),  std::bind(&WiFiManager::handleParamSave, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:651:  server->on(WM_G(R_restart),    std::bind(&WiFiManager::handleReset, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:652:  server->on(WM_G(R_exit),       std::bind(&WiFiManager::handleExit, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:653:  server->on(WM_G(R_close),      std::bind(&WiFiManager::handleClose, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:658:  server->on(WM_G(R_update), std::bind(&WiFiManager::handleUpdate, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:659:  server->on(WM_G(R_updatedone), HTTP_POST, std::bind(&WiFiManager::handleUpdateDone, this), std::bind(&WiFiManager::handleUpdating, this));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:667:void WiFiManager::setupDNSD(){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:668:  dnsServer.reset(new DNSServer());
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:670:  /* Setup the DNS server redirecting all the domains to the apIP */
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:679:void WiFiManager::setupConfigPortal() {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:680:  setupHTTPServer();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:681:  _lastscan = 0; // reset network scan cache
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:682:  if(_preloadwifiscan) WiFi_scanNetworks(true,true); // preload wifiscan , async
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:707:  //setup AP
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:719:  // HANDLE issues with STA connections, shutdown sta if not connected, or else this will hang channel scanning and softap will not respond
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:759:  DEBUG_WM(WM_DEBUG_DEV,F("setupConfigPortal"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:761:  setupConfigPortal();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:764:  DEBUG_WM(WM_DEBUG_DEV,F("setupDNSD"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:766:  setupDNSD();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:819:  DEBUG_WM(WM_DEBUG_NOTIFY,F("config portal exiting"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:832:    MDNS.update();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:837:      if(_allowExit && (configPortalHasTimeout() || abort)){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:861: * returns WL_IDLE_STATUS or WL_CONNECTED/WL_CONNECT_FAILED upon connect/save flag
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:874:    // Waiting for save...
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:878:      DEBUG_WM(WM_DEBUG_VERBOSE,F("processing save"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:880:      if(_enableCaptivePortal) delay(_cpclosedelay); // keeps the captiveportal from closing to fast.
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:885:        DEBUG_WM(WM_DEBUG_VERBOSE,F("No ssid, skipping wifi save"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:890:        uint8_t res = connectWifi(_ssid, _pass, _connectonsave) == WL_CONNECTED;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:891:        if (res || (!_connectonsave)) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:893:          if(!_connectonsave){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:894:            DEBUG_WM(F("SAVED with no connect to new AP"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:896:            DEBUG_WM(F("Connect to new AP [SUCCESS]"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:902:          if ( _savewificallback != NULL) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:904:            DEBUG_WM(WM_DEBUG_VERBOSE,F("[CB] _savewificallback calling"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:906:            _savewificallback(); // @CALLBACK
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:908:          if(!_connectonsave) return WL_IDLE_STATUS;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:913:        DEBUG_WM(WM_DEBUG_ERROR,F("[ERROR] Connect to new AP Failed"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:919:        // do save callback
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:920:        // @todo this is more of an exiting callback than a save, clarify when this should actually occur
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:921:        // confirm or verify data was saved to make this more accurate callback
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:922:        if ( _savewificallback != NULL) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:924:          DEBUG_WM(WM_DEBUG_VERBOSE,F("[CB] WiFi/Param save callback"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:926:          _savewificallback(); // @CALLBACK
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:932:        // clear save strings
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:975:  server.reset();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:977:  WiFi.scanDelete(); // free wifi scan results
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:982:  dnsServer.reset();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1010:  DEBUG_WM(WM_DEBUG_VERBOSE,F("configportal closed"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1028:  // make sure sta is on before `begin` so it does not call enablesta->mode while persistent is ON ( which would save WM AP state to eeprom !)
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1044:  // if ssid argument provided connect to that
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1048:    // @todo connect=false seems to disconnect sta in begin() so not sure if _connectonsave is useful at all
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1051:      if(_saveTimeout > 0){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1052:        connRes = waitForConnectResult(_saveTimeout); // use default save timeout for saves to prevent bugs in esp->waitforconnectresult loop
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1060:    // connect using saved ssid if there is one
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1067:      DEBUG_WM(F("No wifi saved, skipping"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1089:  if(connRes != WL_SCAN_COMPLETED){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1090:    updateConxResult(connRes);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1097: * connect to a new wifi ap
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1102: * @return connect only save if false
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1122: * connect to stored wifi
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1130:  DEBUG_WM(F("Connecting to SAVED AP:"),WiFi_SSID(true));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1164:      DEBUG_WM(WM_DEBUG_VERBOSE,F("Custom static IP/GW/Subnet/DNS"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1168:      DEBUG_WM(WM_DEBUG_VERBOSE,F("Custom static DNS"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1174:      DEBUG_WM(WM_DEBUG_VERBOSE,F("Custom STA IP/GW/Subnet"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1193:void WiFiManager::updateConxResult(uint8_t status){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1281:  page += _customHeadElement;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1336:  String str  = FPSTR(HTTP_ROOT_MAIN); // @todo custom title
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1346:  if(_preloadwifiscan) WiFi_scanNetworks(_scancachetime,true); // preload wifiscan throttled, async
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1355:void WiFiManager::handleWifi(boolean scan) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1361:  if (scan) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1365:    WiFi_scanNetworks(server->hasArg(F("refresh")),false); //wifiscan, force if arg refresh
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1366:    page += getScanItemOut();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1371:  pitem.replace(FPSTR(T_v), F("wifisave")); // set form action
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1396:  page += FPSTR(HTTP_SCAN_LINK);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1421:  pitem.replace(FPSTR(T_v), F("paramsave"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1443:    if((String)_menutokens[menuId] == "custom" && _customMenuHTML!=NULL){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1444:      page += _customMenuHTML;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1454:// // is it possible in softap mode to detect aps without scanning
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1455:// bool WiFiManager::WiFi_scanNetworksForAP(bool force){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1456://   WiFi_scanNetworks(force);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1459:void WiFiManager::WiFi_scanComplete(int networksFound){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1460:  _lastscan = millis();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1463:  DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan ASYNC completed"), "in "+(String)(_lastscan - _startscan)+" ms");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1464:  DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan ASYNC found:"),_numNetworks);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1468:bool WiFiManager::WiFi_scanNetworks(){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1469:  return WiFi_scanNetworks(false,false);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1472:bool WiFiManager::WiFi_scanNetworks(unsigned int cachetime,bool async){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1473:    return WiFi_scanNetworks(millis()-_lastscan > cachetime,async);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1475:bool WiFiManager::WiFi_scanNetworks(unsigned int cachetime){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1476:    return WiFi_scanNetworks(millis()-_lastscan > cachetime,false);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1478:bool WiFiManager::WiFi_scanNetworks(bool force,bool async){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1480:    // DEBUG_WM(WM_DEBUG_DEV,"scanNetworks async:",async == true);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1481:    // DEBUG_WM(WM_DEBUG_DEV,_numNetworks,(millis()-_lastscan ));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1482:    // DEBUG_WM(WM_DEBUG_DEV,"scanNetworks force:",force == true);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1485:    // if 0 networks, rescan @note this was a kludge, now disabling to test real cause ( maybe wifi not init etc)
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1487:    if(_numNetworks == 0 && _autoforcerescan){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1488:      DEBUG_WM(WM_DEBUG_DEV,"NO APs found forcing new scan");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1492:    // if scan is empty or stale (last scantime > _scancachetime), this avoids fast reloading wifi page and constant scan delayed page loads appearing to freeze.
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1493:    if(!_lastscan || (_lastscan>0 && (millis()-_lastscan > _scancachetime))){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1499:      _startscan = millis();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1500:      if(async && _asyncScan){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1504:          DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan ASYNC started"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1507:          WiFi.scanNetworksAsync(std::bind(&WiFiManager::WiFi_scanComplete,this,_1));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1509:          DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan SYNC started"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1510:          res = WiFi.scanNetworks();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1514:          DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan ASYNC started"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1516:          res = WiFi.scanNetworks(true);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1521:        DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan SYNC started"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1522:        res = WiFi.scanNetworks();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1524:      if(res == WIFI_SCAN_FAILED){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1526:        DEBUG_WM(WM_DEBUG_ERROR,F("[ERROR] scan failed"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1529:      else if(res == WIFI_SCAN_RUNNING){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1531:        DEBUG_WM(WM_DEBUG_ERROR,F("[ERROR] scan waiting"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1533:        while(WiFi.scanComplete() == WIFI_SCAN_RUNNING){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1539:        _numNetworks = WiFi.scanComplete();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1542:      _lastscan = millis();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1544:      DEBUG_WM(WM_DEBUG_VERBOSE,F("WiFi Scan completed"), "in "+(String)(_lastscan - _startscan)+" ms");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1550:      DEBUG_WM(WM_DEBUG_VERBOSE,F("Scan is cached"),(String)(millis()-_lastscan )+" ms ago");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1556:String WiFiManager::WiFiManager::getScanItemOut(){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1559:    if(!_numNetworks) WiFi_scanNetworks(); // scan in case this gets called before any scans
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1564:      DEBUG_WM(F("No networks found"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1617:      HTTP_ITEM_STR.replace("{h}",_scanDispOptions ? "" : "h");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1619:      HTTP_ITEM_STR.replace("{h}",_scanDispOptions ? "h" : "");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1697:    // @todo how can we get these accurate settings from memory , wifi_get_ip_info does not seem to reveal if struct ip_info is static or not
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1769:      // if no ID use customhtml for item, else generate from param string
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1779:        if(tok_c)pitem.replace(FPSTR(T_c), _params[i]->getCustomHTML()); // T_c meant for additional attributes, not html, but can stuff
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1781:        pitem = _params[i]->getCustomHTML();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1805: * HTTPD CALLBACK save form and redirect to WLAN config page again
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1807:void WiFiManager::handleWifiSave() {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1809:  DEBUG_WM(WM_DEBUG_VERBOSE,F("<- HTTP WiFi save "));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1814:  //SAVE/connect here
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1821:    DEBUG_WM(WM_DEBUG_VERBOSE,F("Detected WiFi password change"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1826:  String requestinfo = "SERVER_REQUEST\n----------------\n";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1827:  requestinfo += "URI: ";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1828:  requestinfo += server->uri();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1829:  requestinfo += "\nMethod: ";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1830:  requestinfo += (server->method() == HTTP_GET) ? "GET" : "POST";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1831:  requestinfo += "\nArguments: ";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1832:  requestinfo += server->args();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1833:  requestinfo += "\n";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1835:    requestinfo += " " + server->argName(i) + ": " + server->arg(i) + "\n";
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1838:  DEBUG_WM(WM_DEBUG_MAX,requestinfo);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1872:  if (_presavewificallback != NULL) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1873:    _presavewificallback();  // @CALLBACK
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1876:  if(_paramsInWifi) doParamSave();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1881:    page = getHTTPHead(FPSTR(S_titlewifisettings)); // @token titleparamsaved
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1882:    page += FPSTR(HTTP_PARAMSAVED);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1885:    page = getHTTPHead(FPSTR(S_titlewifisaved)); // @token titlewifisaved
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1886:    page += FPSTR(HTTP_SAVED);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1896:  DEBUG_WM(WM_DEBUG_DEV,F("Sent wifi save page"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1899:  connect = true; //signal ready to connect/reset process in processConfigPortal
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1902:void WiFiManager::handleParamSave() {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1905:  DEBUG_WM(WM_DEBUG_VERBOSE,F("<- HTTP Param save "));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1912:  doParamSave();
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1914:  String page = getHTTPHead(FPSTR(S_titleparamsaved)); // @token titleparamsaved
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1915:  page += FPSTR(HTTP_PARAMSAVED);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1922:  DEBUG_WM(WM_DEBUG_DEV,F("Sent param save page"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1926:void WiFiManager::doParamSave(){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1927:   // @todo use new callback for before paramsaves, is this really needed?
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1928:  if ( _presaveparamscallback != NULL) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1929:    _presaveparamscallback();  // @CALLBACK
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1966:   if ( _saveparamscallback != NULL) {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1967:    _saveparamscallback();  // @CALLBACK
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1973: * HTTPD CALLBACK info page
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1975:void WiFiManager::handleInfo() {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1977:  DEBUG_WM(WM_DEBUG_VERBOSE,F("<- HTTP Info"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1980:  String page = getHTTPHead(FPSTR(S_titleinfo)); // @token titleinfo
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1983:  uint16_t infos = 0;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1986:  //@todo wrap in build flag to remove all info code for memory saving
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1988:    infos = 28;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:1989:    String infoids[] = {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2002:      F("lastreset"),
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2021:    // add esp_chip_info ?
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2022:    infos = 27;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2023:    String infoids[] = {
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2034:      F("lastreset"),
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2055:  for(size_t i=0; i<infos;i++){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2056:    if(infoids[i] != NULL) page += getInfoData(infoids[i]);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2061:  page += getInfoData("aboutver");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2062:  page += getInfoData("aboutarduinover");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2063:  page += getInfoData("aboutidfver");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2064:  page += getInfoData("aboutdate");
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2067:  if(_showInfoUpdate){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2071:  if(_showInfoErase) page += FPSTR(HTTP_ERASEBTN);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2079:  DEBUG_WM(WM_DEBUG_DEV,F("Sent info page"));
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2083:String WiFiManager::getInfoData(String id){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2087:    p = FPSTR(HTTP_INFO_esphead);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2093:    p = FPSTR(HTTP_INFO_wifihead);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2098:    p = FPSTR(HTTP_INFO_uptime);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2103:    p = FPSTR(HTTP_INFO_chipid);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2108:      p = FPSTR(HTTP_INFO_chiprev);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2120:      p = FPSTR(HTTP_INFO_fchipid);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2125:    p = FPSTR(HTTP_INFO_idesize);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2130:      p = FPSTR(HTTP_INFO_flashsize);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2133:      p = FPSTR(HTTP_INFO_psrsize);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2139:      p = FPSTR(HTTP_INFO_corever);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2145:      p = FPSTR(HTTP_INFO_bootver);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2150:    p = FPSTR(HTTP_INFO_cpufreq);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2154:    p = FPSTR(HTTP_INFO_freeheap);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2158:    p = FPSTR(HTTP_INFO_memsketch);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2163:    p = FPSTR(HTTP_INFO_memsmeter);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2167:  else if(id==F("lastreset")){
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2169:      p = FPSTR(HTTP_INFO_lastreset);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2170:      p.replace(FPSTR(T_1),(String)ESP.getResetReason());
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2173:      p = FPSTR(HTTP_INFO_lastreset);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2175:        int reason = rtc_get_reset_reason(i);
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2180:          case 1  : p.replace(tok,F("Vbat power on reset"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2181:          case 3  : p.replace(tok,F("Software reset digital core"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2182:          case 4  : p.replace(tok,F("Legacy watch dog reset digital core"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2183:          case 5  : p.replace(tok,F("Deep Sleep reset digital core"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2184:          case 6  : p.replace(tok,F("Reset by SLC module, reset digital core"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2185:          case 7  : p.replace(tok,F("Timer Group0 Watch dog reset digital core"));break;
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.cpp:2186:          case 8  : p.replace(tok,F("Timer Group1 Watch dog reset digital core"));break;


l，password，那些都是、


The user is saying that the WiFiManager portal page still shows English words like "WiFi SSID", "Password", etc. They want these to be Chinese.

Looking at the situation:
1. There's a beautiful `data/index.html` that's already fully Chinese
2. But WiFiManager doesn't use it - it uses its own hardcoded HTML
3. The user wants the actual captive portal page (that appears when connecting to the ESP32's AP) to be in Chinese

The solution is to NOT rely on WiFiManager's built-in web UI, but instead serve the custom `index.html` from the `data/` directory. This requires:

1. Uploading `data/index.html` to LittleFS on the ESP32
2. When WiFiManager starts its config portal, we need to either:
   a. Replace WiFiManager's web serving with our own custom server
   b. Or find a way to make WiFiManager serve our custom HTML

Actually, let me look at this more carefully. WiFiManager creates a captive portal with DNS server and web server. The web server serves hardcoded HTML.

The most practical approach is to modify the WiFiManager HTML source code directly in the library. Since it's in `.pio/libdeps`, we can patch the WiFiManager.cpp file.

But wait, that's fragile. A better approach:

Since the user already has a custom `index.html`, the right architecture is to NOT use WiFiManager's built-in web server, but instead:
1. Start the ESP32 in AP mode manually
2. Set up a DNS server for captive portal
3. Serve the custom `index.html` from LittleFS using a basic WebServer
4. Handle form POST to save WiFi credentials

But this is a major rewrite of wifi_manager.cpp.

A simpler compromise: Patch the WiFiManager library's HTML strings to Chinese. The library is in `.pio/libdeps` and the HTML is generated in `WiFiManager.cpp`. We can edit those strings directly.

Let me look at the actual HTML strings in WiFiManager.cpp to see what needs to be changed.

Actually wait, let me think about this differently. The simplest and most effective approach is:

Since WiFiManager takes over the web server, but we want custom HTML, we should:
1. Keep WiFiManager's DNS captive portal functionality (which is the hard part)
2. But serve our own HTML page

Looking at WiFiManager's source, there might be a way to hook into the HTTP request handling. WiFiManager uses the ESP32 `WebServer` class. In non-blocking mode, we could potentially override routes.

But actually, the even simpler approach is to just patch the WiFiManager.cpp file in the .pio directory to change the English strings to Chinese. This is a direct fix that doesn't require architectural changes.

Let me find the exact HTML strings in WiFiManager.cpp.


明白了！WiFiManager 库的内置页面英文（SSID、Password、Save 等）没改。需要直接修改 WiFiManager 库源码中的 HTML 模板。


1243
1244	  while(millis() < timeoutmillis) {
1245	    status = WiFi.status();
1246	    // @todo detect additional states, connect happens, then dhcp then get ip, there is some delay here, make sure not to timeout if waiting on IP
1247	    if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) {
1248	      return status;
1249	    }
1250	    #ifdef WM_DEBUG_LEVEL
1251	    DEBUG_WM (WM_DEBUG_VERBOSE,F("."));
1252	    #endif
1253	    delay(100);
1254	  }
1255	  return status;
1256	}
1257
1258	// WPS enabled? https://github.com/esp8266/Arduino/pull/4889
1259	#ifdef NO_EXTRA_4K_HEAP
1260	void WiFiManager::startWPS() {
1261	  #ifdef WM_DEBUG_LEVEL
1262	  DEBUG_WM(F("START WPS"));
1263	  #endif
1264	  #ifdef ESP8266
1265	    WiFi.beginWPSConfig();
1266	  #else
1267	    // @todo
1268	  #endif
1269	  #ifdef WM_DEBUG_LEVEL
1270	  DEBUG_WM(F("END WPS"));
1271	  #endif
1272	}
1273	#endif
1274
1275	String WiFiManager::getHTTPHead(String title){
1276	  String page;
1277	  page += FPSTR(HTTP_HEAD_START);
1278	  page.replace(FPSTR(T_v), title);
1279	  page += FPSTR(HTTP_SCRIPT);
1280	  page += FPSTR(HTTP_STYLE);
1281	  page += _customHeadElement;
1282
1283	  if(_bodyClass != ""){
1284	    String p = FPSTR(HTTP_HEAD_END);
1285	    p.replace(FPSTR(T_c), _bodyClass); // add class str
1286	    page += p;
1287	  }
1288	  else {
1289	    page += FPSTR(HTTP_HEAD_END);
1290	  }
1291
1292	  return page;

  while(millis() < timeoutmillis) {
    status = WiFi.status();
    // @todo detect additional states, connect happens, then dhcp then get ip, there is some delay here, make sure not to timeout if waiting on IP
    if (status == WL_CONNECTED || status == WL_CONNECT_FAILED) {
      return status;
    }
    #ifdef WM_DEBUG_LEVEL
    DEBUG_WM (WM_DEBUG_VERBOSE,F("."));
    #endif
    delay(100);
  }
  return status;
}

// WPS enabled? https://github.com/esp8266/Arduino/pull/4889
#ifdef NO_EXTRA_4K_HEAP
void WiFiManager::startWPS() {
  #ifdef WM_DEBUG_LEVEL
  DEBUG_WM(F("START WPS"));
  #endif
  #ifdef ESP8266
    WiFi.beginWPSConfig();
  #else
    // @todo
  #endif
  #ifdef WM_DEBUG_LEVEL
  DEBUG_WM(F("END WPS"));
  #endif
}
#endif

String WiFiManager::getHTTPHead(String title){
  String page;
  page += FPSTR(HTTP_HEAD_START);
  page.replace(FPSTR(T_v), title);
  page += FPSTR(HTTP_SCRIPT);
  page += FPSTR(HTTP_STYLE);
  page += _customHeadElement;

  if(_bodyClass != ""){
    String p = FPSTR(HTTP_HEAD_END);
    p.replace(FPSTR(T_c), _bodyClass); // add class str
    page += p;
  }
  else {
    page += FPSTR(HTTP_HEAD_END);
  }

  return page;


I see that WiFiManager uses PROGMEM strings (`FPSTR`). Let me find where these strings are defined. They're likely in a header file with `HTTP_HEAD_START`, `HTTP_SCRIPT`, `HTTP_STYLE`, etc. defined as PROGMEM strings.

Let me search for these defines.


.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\wm_strings_en.h:25:const char HTTP_HEAD_START[]       PROGMEM = "<!DOCTYPE html>"
.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\wm_strings_en.h:32:const char HTTP_SCRIPT[]           PROGMEM = "


There it is! The WiFiManager library has a language strings file: `wm_strings_en.h`. This contains all the English text for the captive portal. I need to find this file and see what's in it. There might also be a `wm_strings.h` that includes the language file.

Let me look at the full `wm_strings_en.h` file.


找到了！WiFiManager 有一个语言文件。让我看看完整内容。


1	/**
2	 * wm_strings_en.h
3	 * engligh strings for
4	 * WiFiManager, a library for the ESP8266/Arduino platform
5	 * for configuration of WiFi credentials using a Captive Portal
6	 *
7	 * @author Creator tzapu
8	 * @author tablatronix
9	 * @version 0.0.0
10	 * @license MIT
11	 */
12
13	#ifndef _WM_STRINGS_EN_H_
14	#define _WM_STRINGS_EN_H_
15
16
17	#ifndef WIFI_MANAGER_OVERRIDE_STRINGS
18	// !!! ABOVE WILL NOT WORK if you define in your sketch, must be build flag, if anyone one knows how to order includes to be able to do this it would be neat.. I have seen it done..
19
20	// strings files must include a consts file!
21	#include "wm_consts_en.h" // include constants, tokens, routes
22
23	const char WM_LANGUAGE[] PROGMEM = "en-US"; // i18n lang code
24
25	const char HTTP_HEAD_START[]       PROGMEM = "<!DOCTYPE html>"
26	""
27	"<meta name='format-detection' content='telephone=no'>"
28	"<meta charset='UTF-8'>"
29	"<meta  name='viewport' content='width=device-width,initial-scale=1,user-scalable=no'/>"
30	"<title>{v}</title>";
31
32	const char HTTP_SCRIPT[]           PROGMEM = ""; // @todo add button states, disable on click , show ack , spinner etc
39
40	const char HTTP_HEAD_END[]         PROGMEM = "
"; // {c} = _bodyclass
41	// example of embedded logo, base64 encoded inline, No styling here
42	// const char HTTP_ROOT_MAIN[]        PROGMEM = "<img title=' alt=' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADQElEQVRoQ+2YjW0VQQyE7Q6gAkgFkAogFUAqgFQAVACpAKiAUAFQAaECQgWECggVGH1PPrRvn3dv9/YkFOksoUhhfzwz9ngvKrc89JbnLxuA/63gpsCmwCADWwkNEji8fVNgotDM7osI/x777x5l9F6JyB8R4eeVql4P0y8yNsjM7KGIPBORp558T04A+CwiH1UVUItiUQmZ2XMReSEiAFgjAPBeVS96D+sCYGaUx4cFbLfmhSpnqnrZuqEJgJnd8cQplVLciAgX//Cf0ToIeOB9wpmloLQAwpnVmAXgdf6pwjpJIz+XNoeZQQZlODV9vhc1Tuf6owrAk/8qIhFbJH7eI3eEzsvydQEICqBEkZwiALfF70HyHPpqScPV5HFjeFu476SkRA0AzOfy4hYwstj2ZkDgaphE7m6XqnoS7Q0BOPs/sw0kDROzjdXcCMFCNwzIy0EcRcOvBACfh4k0wgOmBX4xjfmk4DKTS31hgNWIKBCI8gdzogTgjYjQWFMw+o9LzJoZ63GUmjWm2wGDc7EvDDOj/1IVMIyD9SUAL0WEhpriRlXv5je5S+U1i2N88zdPuoVkeB+ls4SyxCoP3kVm9jsjpEsBLoOBNC5U9SwpGdakFkviuFP1keblATkTENTYcxkzgxTKOI3jyDxqLkQT87pMA++H3XvJBYtsNbBN6vuXq5S737WqHkW1VgMQNXJ0RshMqbbT33sJ5kpHWymzcJjNTeJIymJZtSQd9NHQHS1vodoFoTMkfbJzpRnLzB2vi6BZAJxWaCr+62BC+jzAxVJb3dmmiLzLwZhZNPE5e880Suo2AZgB8e8idxherqUPnT3brBDTlPxO3Z66rVwIwySXugdNd+5ejhqp/+NmgIwGX3Py3QBmlEi54KlwmjkOytQ+iJrLJj23S4GkOeecg8G091no737qvRRdzE+HLALQoMTBbJgBsCj5RSWUlUVJiZ4SOljb05eLFWgoJ5oY6yTyJp62D39jDANoKKcSocPJD5dQYzlFAFZJflUArgTPZKZwLXAnHmerfJquUkKZEgyzqOb5TuDt1P3nwxobqwPocZA11m4A1mBx5IxNgRH21ti7KbAGiyNn3HoF/gJ0w05A8xclpwAAAABJRU5ErkJggg==' />
{v}

WiFiManager
";
43	const char HTTP_ROOT_MAIN[]        PROGMEM = "
{t}

{v}
";
44
45	const char * const HTTP_PORTAL_MENU[] PROGMEM = {
46	"<form action='/wifi'    method='get'><button>Configure WiFi</button></form>
\n", // MENU_WIFI
47	"<form action='/0wifi'   method='get'><button>Configure WiFi (No scan)</button></form>
\n", // MENU_WIFINOSCAN
48	"<form action='/info'    method='get'><button>Info</button></form>
\n", // MENU_INFO
49	"<form action='/param'   method='get'><button>Setup</button></form>
\n",//MENU_PARAM
50	"<form action='/close'   method='get'><button>Close</button></form>
\n", // MENU_CLOSE
51	"<form action='/restart' method='get'><button>Restart</button></form>
\n",// MENU_RESTART
52	"<form action='/exit'    method='get'><button>Exit</button></form>
\n",  // MENU_EXIT
53	"<form action='/erase'   method='get'><button class='D'>Erase</button></form>
\n", // MENU_ERASE
54	"<form action='/update'  method='get'><button>Update</button></form>
\n",// MENU_UPDATE
55	"

" // MENU_SEP
56	};
57
58	// const char HTTP_PORTAL_OPTIONS[]   PROGMEM = strcat(HTTP_PORTAL_MENU[0] , HTTP_PORTAL_MENU[3] , HTTP_PORTAL_MENU[7]);
59	const char HTTP_PORTAL_OPTIONS[]   PROGMEM = "";
60	const char HTTP_ITEM_QI[]          PROGMEM = "

"; // rssi icons
61	const char HTTP_ITEM_QP[]          PROGMEM = "
{r}%
"; // rssi percentage {h} = hidden showperc pref
62	const char HTTP_ITEM[]             PROGMEM = "
{v}{qi}{qp}
"; // {q} = HTTP_ITEM_QI, {r} = HTTP_ITEM_QP
63	// const char HTTP_ITEM[]            PROGMEM = "
{v} {R} {r}% {q} {e}
"; // test all tokens
64
65	const char HTTP_FORM_START[]       PROGMEM = "<form method='POST' action='{v}'>";
66	const char HTTP_FORM_WIFI[]        PROGMEM = "SSID<input id='s' name='s' maxlength='32' autocorrect='off' autocapitalize='none' placeholder='{v}'>
Password<input id='p' name='p' maxlength='64' type='password' placeholder='{p}'><input type='checkbox' id='showpass' onclick='f()'> Show Password
";
67	const char HTTP_FORM_WIFI_END[]    PROGMEM = "";
68	const char HTTP_FORM_STATIC_HEAD[] PROGMEM = "

";
69	const char HTTP_FORM_END[]         PROGMEM = "

<button type='submit'>Save</button></form>";
70	const char HTTP_FORM_LABEL[]       PROGMEM = "{t}";
71	const char HTTP_FORM_PARAM_HEAD[]  PROGMEM = "

";
72	const char HTTP_FORM_PARAM[]       PROGMEM = "
<input id='{i}' name='{n}' maxlength='{l}' value='{v}' {c}>\n"; // do not remove newline!
73
74	const char HTTP_SCAN_LINK[]        PROGMEM = "
<form action='/wifi?refresh=1' method='POST'><button name='refresh' value='1'>Refresh</button></form>";
75	const char HTTP_SAVED[]            PROGMEM = "
Saving Credentials
Trying to connect ESP to network.
If it fails reconnect to AP to try again
";
76	const char HTTP_PARAMSAVED[]       PROGMEM = "
Saved

";
77	const char HTTP_END[]              PROGMEM = "
";
78	const char HTTP_ERASEBTN[]         PROGMEM = "
<form action='/erase' method='get'><button class='D'>Erase WiFi config</button></form>";
79	const char HTTP_UPDATEBTN[]        PROGMEM = "
<form action='/update' method='get'><button>Update</button></form>";
80	const char HTTP_BACKBTN[]          PROGMEM = "

<form action='/' method='get'><button>Back</button></form>";
81
82	const char HTTP_STATUS_ON[]        PROGMEM = "
Connected to {v}
with IP {i}
";
83	const char HTTP_STATUS_OFF[]       PROGMEM = "
Not connected to {v}{r}
"; // {c=class} {v=ssid} {r=status_off}
84	const char HTTP_STATUS_OFFPW[]     PROGMEM = "
Authentication failure"; // STATION_WRONG_PASSWORD,  no eps32
85	const char HTTP_STATUS_OFFNOAP[]   PROGMEM = "
AP not found";   // WL_NO_SSID_AVAIL
86	const char HTTP_STATUS_OFFFAIL[]   PROGMEM = "
Could not connect"; // WL_CONNECT_FAILED
87	const char HTTP_STATUS_NONE[]      PROGMEM = "
No AP set
";
88	const char HTTP_BR[]               PROGMEM = "
";
89
90	const char HTTP_STYLE[]            PROGMEM = "";
120
121	#ifndef WM_NOHELP
122	const char HTTP_HELP[]             PROGMEM =
123	 "

Available pages

"
124	 "
"
125	 "

Page	Function

"
126	 "
/	"
127	 "Menu page.
"
128	 "
/wifi	"
129	 "Show WiFi scan results and enter WiFi configuration.(/0wifi noscan)
"
130	 "
/wifisave	"
131	 "Save WiFi configuration information and configure device. Needs variables supplied.
"
132	 "
/param	"
133	 "Parameter page
"
134	 "
/info	"
135	 "Information page
"
136	 "
/u	"
137	 "OTA Update
"
138	 "
/close	"
139	 "Close the captiveportal popup, config portal will remain active
"
140	 "
/exit	"
141	 "Exit Config portal, config portal will close
"
142	 "
/restart	"
143	 "Reboot the device
"
144	 "
/erase	"
145	 "Erase WiFi configuration and reboot device. Device will not reconnect to a network until new WiFi configuration data is entered.
"
146	 "
"
147	 "
Github https://github.com/tzapu/WiFiManager.";
148	#else
149	const char HTTP_HELP[]             PROGMEM = "";
150	#endif
151
152	const char HTTP_UPDATE[] PROGMEM = "Upload new firmware
<form method='POST' action='u' enctype='multipart/form-data' onchange=\"(function(el){document.getElementById('uploadbin').style.display = el.value=='' ? 'none' : 'initial';})(this)\"><input type='file' name='update' accept='.bin,application/octet-stream'><button id='uploadbin' type='submit' class='h D'>Update</button></form>* May not function inside captive portal, open in browser http://192.168.4.1";
153	const char HTTP_UPDATE_FAIL[] PROGMEM = "
Update failed!
Reboot device and try again
";
154	const char HTTP_UPDATE_SUCCESS[] PROGMEM = "
Update successful.
 Device rebooting now...
";
155
156	#ifdef WM_JSTEST
157	const char HTTP_JS[] PROGMEM =
158	"";
174	#endif
175
176	// Info html
177	// @todo remove html elements from progmem, repetetive strings
178	#ifdef ESP32
179		const char HTTP_INFO_esphead[]    PROGMEM = "
esp32

";
180		const char HTTP_INFO_chiprev[]    PROGMEM = "
Chip rev

{1}
";
181	  	const char HTTP_INFO_lastreset[]  PROGMEM = "
Last reset reason

CPU0: {1}
CPU1: {2}
";
182	  	const char HTTP_INFO_aphost[]     PROGMEM = "
Access point hostname

{1}
";
183	    const char HTTP_INFO_psrsize[]    PROGMEM = "
PSRAM Size

{1} bytes
";
184		const char HTTP_INFO_temp[]       PROGMEM = "
Temperature

{1} C° / {2} F°
";
185	    const char HTTP_INFO_hall[]       PROGMEM = "
Hall

{1}
";
186	#else
187		const char HTTP_INFO_esphead[]    PROGMEM = "
esp8266

";
188		const char HTTP_INFO_fchipid[]    PROGMEM = "
Flash chip ID

{1}
";
189		const char HTTP_INFO_corever[]    PROGMEM = "
Core version

{1}
";
190		const char HTTP_INFO_bootver[]    PROGMEM = "
Boot version

{1}
";
191		const char HTTP_INFO_lastreset[]  PROGMEM = "
Last reset reason

{1}
";
192		const char HTTP_INFO_flashsize[]  PROGMEM = "
Real flash size

{1} bytes
";
193	#endif
194
195	const char HTTP_INFO_memsmeter[]  PROGMEM = "
<progress value='{1}' max='{2}'></progress>
";
196	const char HTTP_INFO_memsketch[]  PROGMEM = "
Memory - Sketch size

Used / Total bytes
{1} / {2}";
197	const char HTTP_INFO_freeheap[]   PROGMEM = "
Memory - Free heap

{1} bytes available
";
198	const char HTTP_INFO_wifihead[]   PROGMEM = "

WiFi

";
199	const char HTTP_INFO_uptime[]     PROGMEM = "
Uptime

{1} mins {2} secs
";
200	const char HTTP_INFO_chipid[]     PROGMEM = "
Chip ID

{1}
";
201	const char HTTP_INFO_idesize[]    PROGMEM = "
Flash size

{1} bytes
";
202	const char HTTP_INFO_sdkver[]     PROGMEM = "
SDK version

{1}
";
203	const char HTTP_INFO_cpufreq[]    PROGMEM = "
CPU frequency

{1}MHz
";
204	const char HTTP_INFO_apip[]       PROGMEM = "
Access point IP

{1}
";
205	const char HTTP_INFO_apmac[]      PROGMEM = "
Access point MAC

{1}
";
206	const char HTTP_INFO_apssid[]     PROGMEM = "
Access point SSID

{1}
";
207	const char HTTP_INFO_apbssid[]    PROGMEM = "
BSSID

{1}
";
208	const char HTTP_INFO_stassid[]    PROGMEM = "
Station SSID

{1}
";
209	const char HTTP_INFO_staip[]      PROGMEM = "
Station IP

{1}
";
210	const char HTTP_INFO_stagw[]      PROGMEM = "
Station gateway

{1}
";
211	const char HTTP_INFO_stasub[]     PROGMEM = "
Station subnet

{1}
";
212	const char HTTP_INFO_dnss[]       PROGMEM = "
DNS Server

{1}
";
213	const char HTTP_INFO_host[]       PROGMEM = "
Hostname

{1}
";
214	const char HTTP_INFO_stamac[]     PROGMEM = "
Station MAC

{1}
";
215	const char HTTP_INFO_conx[]       PROGMEM = "
Connected

{1}
";
216	const char HTTP_INFO_autoconx[]   PROGMEM = "
Autoconnect

{1}
";
217
218	const char HTTP_INFO_aboutver[]     PROGMEM = "
WiFiManager

{1}
";
219	const char HTTP_INFO_aboutarduino[] PROGMEM = "
Arduino

{1}
";
220	const char HTTP_INFO_aboutsdk[]     PROGMEM = "
ESP-SDK/IDF

{1}
";
221	const char HTTP_INFO_aboutdate[]    PROGMEM = "
Build date

{1}
";
222
223	const char S_brand[]              PROGMEM = "WiFiManager";
224	const char S_debugPrefix[]        PROGMEM = "*wm:";
225	const char S_y[]                  PROGMEM = "Yes";
226	const char S_n[]                  PROGMEM = "No";
227	const char S_enable[]             PROGMEM = "Enabled";
228	const char S_disable[]            PROGMEM = "Disabled";
229	const char S_GET[]                PROGMEM = "GET";
230	const char S_POST[]               PROGMEM = "POST";
231	const char S_NA[]                 PROGMEM = "Unknown";
232	const char S_passph[]             PROGMEM = "********";
233	const char S_titlewifisaved[]     PROGMEM = "Credentials saved";
234	const char S_titlewifisettings[]  PROGMEM = "Settings saved";
235	const char S_titlewifi[]          PROGMEM = "Config ESP";
236	const char S_titleinfo[]          PROGMEM = "Info";
237	const char S_titleparam[]         PROGMEM = "Setup";
238	const char S_titleparamsaved[]    PROGMEM = "Setup saved";
239	const char S_titleexit[]          PROGMEM = "Exit";
240	const char S_titlereset[]         PROGMEM = "Reset";
241	const char S_titleerase[]         PROGMEM = "Erase";
242	const char S_titleclose[]         PROGMEM = "Close";
243	const char S_options[]            PROGMEM = "options";
244	const char S_nonetworks[]         PROGMEM = "No networks found. Refresh to scan again.";
245	const char S_staticip[]           PROGMEM = "Static IP";
246	const char S_staticgw[]           PROGMEM = "Static gateway";
247	const char S_staticdns[]          PROGMEM = "Static DNS";
248	const char S_subnet[]             PROGMEM = "Subnet";
249	const char S_exiting[]            PROGMEM = "Exiting";
250	const char S_resetting[]          PROGMEM = "Module will reset in a few seconds.";
251	const char S_closing[]            PROGMEM = "You can close the page, portal will continue to run";
252	const char S_error[]              PROGMEM = "An error occured";
253	const char S_notfound[]           PROGMEM = "File not found\n\n";
254	const char S_uri[]                PROGMEM = "URI: ";
255	const char S_method[]             PROGMEM = "\nMethod: ";
256	const char S_args[]               PROGMEM = "\nArguments: ";
257	const char S_parampre[]           PROGMEM = "param_";
258
259	// debug strings
260	const char D_HR[]                 PROGMEM = "--------------------";
261
262
263	// softap ssid default prefix
264	#ifdef ESP8266
265	    const char S_ssidpre[]        PROGMEM = "ESP";
266	#elif defined(ESP32)
267	    const char S_ssidpre[]        PROGMEM = "ESP32";
268	#else
269	    const char S_ssidpre[]        PROGMEM = "WM";
270	#endif
271
272	// END WIFI_MANAGER_OVERRIDE_STRINGS
273	#endif
274
275	#endif
276

/**
 * wm_strings_en.h
 * engligh strings for
 * WiFiManager, a library for the ESP8266/Arduino platform
 * for configuration of WiFi credentials using a Captive Portal
 *
 * @author Creator tzapu
 * @author tablatronix
 * @version 0.0.0
 * @license MIT
 */

#ifndef _WM_STRINGS_EN_H_
#define _WM_STRINGS_EN_H_

#ifndef WIFI_MANAGER_OVERRIDE_STRINGS
// !!! ABOVE WILL NOT WORK if you define in your sketch, must be build flag, if anyone one knows how to order includes to be able to do this it would be neat.. I have seen it done..

// strings files must include a consts file!
#include "wm_consts_en.h" // include constants, tokens, routes

const char WM_LANGUAGE[] PROGMEM = "en-US"; // i18n lang code

const char HTTP_HEAD_START[]       PROGMEM = "<!DOCTYPE html>"
""
"<meta name='format-detection' content='telephone=no'>"
"<meta charset='UTF-8'>"
"<meta  name='viewport' content='width=device-width,initial-scale=1,user-scalable=no'/>"
"<title>{v}</title>";

const char HTTP_SCRIPT[]           PROGMEM = ""; // @todo add button states, disable on click , show ack , spinner etc

const char HTTP_HEAD_END[]         PROGMEM = "
"; // {c} = _bodyclass
// example of embedded logo, base64 encoded inline, No styling here
// const char HTTP_ROOT_MAIN[]        PROGMEM = "<img title=' alt=' src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAADQElEQVRoQ+2YjW0VQQyE7Q6gAkgFkAogFUAqgFQAVACpAKiAUAFQAaECQgWECggVGH1PPrRvn3dv9/YkFOksoUhhfzwz9ngvKrc89JbnLxuA/63gpsCmwCADWwkNEji8fVNgotDM7osI/x777x5l9F6JyB8R4eeVql4P0y8yNsjM7KGIPBORp558T04A+CwiH1UVUItiUQmZ2XMReSEiAFgjAPBeVS96D+sCYGaUx4cFbLfmhSpnqnrZuqEJgJnd8cQplVLciAgX//Cf0ToIeOB9wpmloLQAwpnVmAXgdf6pwjpJIz+XNoeZQQZlODV9vhc1Tuf6owrAk/8qIhFbJH7eI3eEzsvydQEICqBEkZwiALfF70HyHPpqScPV5HFjeFu476SkRA0AzOfy4hYwstj2ZkDgaphE7m6XqnoS7Q0BOPs/sw0kDROzjdXcCMFCNwzIy0EcRcOvBACfh4k0wgOmBX4xjfmk4DKTS31hgNWIKBCI8gdzogTgjYjQWFMw+o9LzJoZ63GUmjWm2wGDc7EvDDOj/1IVMIyD9SUAL0WEhpriRlXv5je5S+U1i2N88zdPuoVkeB+ls4SyxCoP3kVm9jsjpEsBLoOBNC5U9SwpGdakFkviuFP1keblATkTENTYcxkzgxTKOI3jyDxqLkQT87pMA++H3XvJBYtsNbBN6vuXq5S737WqHkW1VgMQNXJ0RshMqbbT33sJ5kpHWymzcJjNTeJIymJZtSQd9NHQHS1vodoFoTMkfbJzpRnLzB2vi6BZAJxWaCr+62BC+jzAxVJb3dmmiLzLwZhZNPE5e880Suo2AZgB8e8idxherqUPnT3brBDTlPxO3Z66rVwIwySXugdNd+5ejhqp/+NmgIwGX3Py3QBmlEi54KlwmjkOytQ+iJrLJj23S4GkOeecg8G091no737qvRRdzE+HLALQoMTBbJgBsCj5RSWUlUVJiZ4SOljb05eLFWgoJ5oY6yTyJp62D39jDANoKKcSocPJD5dQYzlFAFZJflUArgTPZKZwLXAnHmerfJquUkKZEgyzqOb5TuDt1P3nwxobqwPocZA11m4A1mBx5IxNgRH21ti7KbAGiyNn3HoF/gJ0w05A8xclpwAAAABJRU5ErkJggg==' />
{v}

WiFiManager
";
const char HTTP_ROOT_MAIN[]        PROGMEM = "
{t}

{v}
";

const char * const HTTP_PORTAL_MENU[] PROGMEM = {
"<form action='/wifi'    method='get'><button>Configure WiFi</button></form>
\n", // MENU_WIFI
"<form action='/0wifi'   method='get'><button>Configure WiFi (No scan)</button></form>
\n", // MENU_WIFINOSCAN
"<form action='/info'    method='get'><button>Info</button></form>
\n", // MENU_INFO
"<form action='/param'   method='get'><button>Setup</button></form>
\n",//MENU_PARAM
"<form action='/close'   method='get'><button>Close</button></form>
\n", // MENU_CLOSE
"<form action='/restart' method='get'><button>Restart</button></form>
\n",// MENU_RESTART
"<form action='/exit'    method='get'><button>Exit</button></form>
\n",  // MENU_EXIT
"<form action='/erase'   method='get'><button class='D'>Erase</button></form>
\n", // MENU_ERASE
"<form action='/update'  method='get'><button>Update</button></form>
\n",// MENU_UPDATE
"

" // MENU_SEP
};

// const char HTTP_PORTAL_OPTIONS[]   PROGMEM = strcat(HTTP_PORTAL_MENU[0] , HTTP_PORTAL_MENU[3] , HTTP_PORTAL_MENU[7]);
const char HTTP_PORTAL_OPTIONS[]   PROGMEM = "";
const char HTTP_ITEM_QI[]          PROGMEM = "

"; // rssi icons
const char HTTP_ITEM_QP[]          PROGMEM = "
{r}%
"; // rssi percentage {h} = hidden showperc pref
const char HTTP_ITEM[]             PROGMEM = "
{v}{qi}{qp}
"; // {q} = HTTP_ITEM_QI, {r} = HTTP_ITEM_QP
// const char HTTP_ITEM[]            PROGMEM = "
{v} {R} {r}% {q} {e}
"; // test all tokens

const char HTTP_FORM_START[]       PROGMEM = "<form method='POST' action='{v}'>";
const char HTTP_FORM_WIFI[]        PROGMEM = "SSID<input id='s' name='s' maxlength='32' autocorrect='off' autocapitalize='none' placeholder='{v}'>
Password<input id='p' name='p' maxlength='64' type='password' placeholder='{p}'><input type='checkbox' id='showpass' onclick='f()'> Show Password
";
const char HTTP_FORM_WIFI_END[]    PROGMEM = "";
const char HTTP_FORM_STATIC_HEAD[] PROGMEM = "

";
const char HTTP_FORM_END[]         PROGMEM = "

<button type='submit'>Save</button></form>";
const char HTTP_FORM_LABEL[]       PROGMEM = "{t}";
const char HTTP_FORM_PARAM_HEAD[]  PROGMEM = "

";
const char HTTP_FORM_PARAM[]       PROGMEM = "
<input id='{i}' name='{n}' maxlength='{l}' value='{v}' {c}>\n"; // do not remove newline!

const char HTTP_SCAN_LINK[]        PROGMEM = "
<form action='/wifi?refresh=1' method='POST'><button name='refresh' value='1'>Refresh</button></form>";
const char HTTP_SAVED[]            PROGMEM = "
Saving Credentials
Trying to connect ESP to network.
If it fails reconnect to AP to try again
";
const char HTTP_PARAMSAVED[]       PROGMEM = "
Saved

";
const char HTTP_END[]              PROGMEM = "
";
const char HTTP_ERASEBTN[]         PROGMEM = "
<form action='/erase' method='get'><button class='D'>Erase WiFi config</button></form>";
const char HTTP_UPDATEBTN[]        PROGMEM = "
<form action='/update' method='get'><button>Update</button></form>";
const char HTTP_BACKBTN[]          PROGMEM = "

<form action='/' method='get'><button>Back</button></form>";

const char HTTP_STATUS_ON[]        PROGMEM = "
Connected to {v}
with IP {i}
";
const char HTTP_STATUS_OFF[]       PROGMEM = "
Not connected to {v}{r}
"; // {c=class} {v=ssid} {r=status_off}
const char HTTP_STATUS_OFFPW[]     PROGMEM = "
Authentication failure"; // STATION_WRONG_PASSWORD,  no eps32
const char HTTP_STATUS_OFFNOAP[]   PROGMEM = "
AP not found";   // WL_NO_SSID_AVAIL
const char HTTP_STATUS_OFFFAIL[]   PROGMEM = "
Could not connect"; // WL_CONNECT_FAILED
const char HTTP_STATUS_NONE[]      PROGMEM = "
No AP set
";
const char HTTP_BR[]               PROGMEM = "
";

const char HTTP_STYLE[]            PROGMEM = "";

#ifndef WM_NOHELP
const char HTTP_HELP[]             PROGMEM =
 "

Available pages

"
 "
"
 "

Page	Function

"
 "
/	"
 "Menu page.
"
 "
/wifi	"
 "Show WiFi scan results and enter WiFi configuration.(/0wifi noscan)
"
 "
/wifisave	"
 "Save WiFi configuration information and configure device. Needs variables supplied.
"
 "
/param	"
 "Parameter page
"
 "
/info	"
 "Information page
"
 "
/u	"
 "OTA Update
"
 "
/close	"
 "Close the captiveportal popup, config portal will remain active
"
 "
/exit	"
 "Exit Config portal, config portal will close
"
 "
/restart	"
 "Reboot the device
"
 "
/erase	"
 "Erase WiFi configuration and reboot device. Device will not reconnect to a network until new WiFi configuration data is entered.
"
 "
"
 "
Github https://github.com/tzapu/WiFiManager.";
#else
const char HTTP_HELP[]             PROGMEM = "";
#endif

const char HTTP_UPDATE[] PROGMEM = "Upload new firmware
<form method='POST' action='u' enctype='multipart/form-data' onchange=\"(function(el){document.getElementById('uploadbin').style.display = el.value=='' ? 'none' : 'initial';})(this)\"><input type='file' name='update' accept='.bin,application/octet-stream'><button id='uploadbin' type='submit' class='h D'>Update</button></form>* May not function inside captive portal, open in browser http://192.168.4.1";
const char HTTP_UPDATE_FAIL[] PROGMEM = "
Update failed!
Reboot device and try again
";
const char HTTP_UPDATE_SUCCESS[] PROGMEM = "
Update successful.
 Device rebooting now...
";

#ifdef WM_JSTEST
const char HTTP_JS[] PROGMEM =
"";
#endif

// Info html
// @todo remove html elements from progmem, repetetive strings
#ifdef ESP32
	const char HTTP_INFO_esphead[]    PROGMEM = "
esp32

";
	const char HTTP_INFO_chiprev[]    PROGMEM = "
Chip rev

{1}
";
  	const char HTTP_INFO_lastreset[]  PROGMEM = "
Last reset reason

CPU0: {1}
CPU1: {2}
";
  	const char HTTP_INFO_aphost[]     PROGMEM = "
Access point hostname

{1}
";
    const char HTTP_INFO_psrsize[]    PROGMEM = "
PSRAM Size

{1} bytes
";
	const char HTTP_INFO_temp[]       PROGMEM = "
Temperature

{1} C° / {2} F°
";
    const char HTTP_INFO_hall[]       PROGMEM = "
Hall

{1}
";
#else
	const char HTTP_INFO_esphead[]    PROGMEM = "
esp8266

";
	const char HTTP_INFO_fchipid[]    PROGMEM = "
Flash chip ID

{1}
";
	const char HTTP_INFO_corever[]    PROGMEM = "
Core version

{1}
";
	const char HTTP_INFO_bootver[]    PROGMEM = "
Boot version

{1}
";
	const char HTTP_INFO_lastreset[]  PROGMEM = "
Last reset reason

{1}
";
	const char HTTP_INFO_flashsize[]  PROGMEM = "
Real flash size

{1} bytes
";
#endif

const char HTTP_INFO_memsmeter[]  PROGMEM = "
<progress value='{1}' max='{2}'></progress>
";
const char HTTP_INFO_memsketch[]  PROGMEM = "
Memory - Sketch size

Used / Total bytes
{1} / {2}";
const char HTTP_INFO_freeheap[]   PROGMEM = "
Memory - Free heap

{1} bytes available
";
const char HTTP_INFO_wifihead[]   PROGMEM = "

WiFi

";
const char HTTP_INFO_uptime[]     PROGMEM = "
Uptime

{1} mins {2} secs
";
const char HTTP_INFO_chipid[]     PROGMEM = "
Chip ID

{1}
";
const char HTTP_INFO_idesize[]    PROGMEM = "
Flash size

{1} bytes
";
const char HTTP_INFO_sdkver[]     PROGMEM = "
SDK version

{1}
";
const char HTTP_INFO_cpufreq[]    PROGMEM = "
CPU frequency

{1}MHz
";
const char HTTP_INFO_apip[]       PROGMEM = "
Access point IP

{1}
";
const char HTTP_INFO_apmac[]      PROGMEM = "
Access point MAC

{1}
";
const char HTTP_INFO_apssid[]     PROGMEM = "
Access point SSID

{1}
";
const char HTTP_INFO_apbssid[]    PROGMEM = "
BSSID

{1}
";
const char HTTP_INFO_stassid[]    PROGMEM = "
Station SSID

{1}
";
const char HTTP_INFO_staip[]      PROGMEM = "
Station IP

{1}
";
const char HTTP_INFO_stagw[]      PROGMEM = "
Station gateway

{1}
";
const char HTTP_INFO_stasub[]     PROGMEM = "
Station subnet

{1}
";
const char HTTP_INFO_dnss[]       PROGMEM = "
DNS Server

{1}
";
const char HTTP_INFO_host[]       PROGMEM = "
Hostname

{1}
";
const char HTTP_INFO_stamac[]     PROGMEM = "
Station MAC

{1}
";
const char HTTP_INFO_conx[]       PROGMEM = "
Connected

{1}
";
const char HTTP_INFO_autoconx[]   PROGMEM = "
Autoconnect

{1}
";

const char HTTP_INFO_aboutver[]     PROGMEM = "
WiFiManager

{1}
";
const char HTTP_INFO_aboutarduino[] PROGMEM = "
Arduino

{1}
";
const char HTTP_INFO_aboutsdk[]     PROGMEM = "
ESP-SDK/IDF

{1}
";
const char HTTP_INFO_aboutdate[]    PROGMEM = "
Build date

{1}
";

const char S_brand[]              PROGMEM = "WiFiManager";
const char S_debugPrefix[]        PROGMEM = "*wm:";
const char S_y[]                  PROGMEM = "Yes";
const char S_n[]                  PROGMEM = "No";
const char S_enable[]             PROGMEM = "Enabled";
const char S_disable[]            PROGMEM = "Disabled";
const char S_GET[]                PROGMEM = "GET";
const char S_POST[]               PROGMEM = "POST";
const char S_NA[]                 PROGMEM = "Unknown";
const char S_passph[]             PROGMEM = "********";
const char S_titlewifisaved[]     PROGMEM = "Credentials saved";
const char S_titlewifisettings[]  PROGMEM = "Settings saved";
const char S_titlewifi[]          PROGMEM = "Config ESP";
const char S_titleinfo[]          PROGMEM = "Info";
const char S_titleparam[]         PROGMEM = "Setup";
const char S_titleparamsaved[]    PROGMEM = "Setup saved";
const char S_titleexit[]          PROGMEM = "Exit";
const char S_titlereset[]         PROGMEM = "Reset";
const char S_titleerase[]         PROGMEM = "Erase";
const char S_titleclose[]         PROGMEM = "Close";
const char S_options[]            PROGMEM = "options";
const char S_nonetworks[]         PROGMEM = "No networks found. Refresh to scan again.";
const char S_staticip[]           PROGMEM = "Static IP";
const char S_staticgw[]           PROGMEM = "Static gateway";
const char S_staticdns[]          PROGMEM = "Static DNS";
const char S_subnet[]             PROGMEM = "Subnet";
const char S_exiting[]            PROGMEM = "Exiting";
const char S_resetting[]          PROGMEM = "Module will reset in a few seconds.";
const char S_closing[]            PROGMEM = "You can close the page, portal will continue to run";
const char S_error[]              PROGMEM = "An error occured";
const char S_notfound[]           PROGMEM = "File not found\n\n";
const char S_uri[]                PROGMEM = "URI: ";
const char S_method[]             PROGMEM = "\nMethod: ";
const char S_args[]               PROGMEM = "\nArguments: ";
const char S_parampre[]           PROGMEM = "param_";

// debug strings
const char D_HR[]                 PROGMEM = "--------------------";

// softap ssid default prefix
#ifdef ESP8266
    const char S_ssidpre[]        PROGMEM = "ESP";
#elif defined(ESP32)
    const char S_ssidpre[]        PROGMEM = "ESP32";
#else
    const char S_ssidpre[]        PROGMEM = "WM";
#endif

// END WIFI_MANAGER_OVERRIDE_STRINGS
#endif

#endif


Now I see the full picture. The WiFiManager library has all its UI strings in `wm_strings_en.h`. This file contains all the English text that appears on the captive portal page. I need to create a Chinese version of this file.

Looking at the file, I can see all the English strings that need to be translated:
- Line 26: `<html lang='en'>` → `lang='zh-CN'`
- Line 42: `WiFiManager` → stayed or changed
- Line 46: `Configure WiFi` → `配置 WiFi`
- Line 47: `Configure WiFi (No scan)` → `配置 WiFi (不扫描)`
- Line 48: `Info` → `信息`
- Line 49: `Setup` → `设置`
- Line 50: `Close` → `关闭`
- Line 51: `Restart` → `重启`
- Line 52: `Exit` → `退出`
- Line 53: `Erase` → `清除`
- Line 54: `Update` → `升级`
- Line 66: `SSID` label, `Password` label, `Show Password`
- Line 69: `Save` → `保存`
- Line 74: `Refresh` → `刷新`
- Line 75: `Saving Credentials...Trying to connect...`
- Line 76: `Saved` → `已保存`
- Line 78: `Erase WiFi config`
- Line 79: `Update`
- Line 80: `Back` → `返回`
- Line 82: `Connected... with IP...`
- Line 83: `Not connected`
- Line 84: `Authentication failure`
- Line 85: `AP not found`
- Line 86: `Could not connect`
- Line 87: `No AP set`
- Line 122-148: Help text
- Line 152-153: Update/Update failed text
- Line 223: brand name
- Line 233-258: Various title/status strings

This is the perfect approach. I'll modify this file directly to change all English strings to Chinese. Since the file is in `.pio/libdeps/`, I need to be careful - it might be overwritten if the library is reinstalled. But for the current build, this will work.

Actually, let me think about a better approach. Instead of modifying the library file (which could be overwritten), I could:
1. Copy `wm_strings_en.h` to a new file in the project (e.g., `include/wm_strings_zh.h`)
2. Modify the WiFiManager include to use our custom strings file

But looking at how WiFiManager includes strings, it likely includes `wm_strings_en.h` directly. Let me check the main WiFiManager.h include path.

Actually wait, looking at line 17-18:
```cpp
#ifndef WIFI_MANAGER_OVERRIDE_STRINGS
// !!! ABOVE WILL NOT WORK if you define in your sketch, must be build flag
```

This means there's a build flag `WIFI_MANAGER_OVERRIDE_STRINGS` that can be used. But the comment says it must be a build flag, not defined in the sketch. So I could add it to `platformio.ini` as a build flag.

But that would require providing ALL string definitions in my own file. That's a lot of work.

The simpler approach: just edit the `wm_strings_en.h` file directly. Yes, it might get overwritten if the library updates, but it's the most straightforward fix. I'll also keep a backup.

Actually, the BEST approach: Create a new file `wm_strings_zh.h` in the project's include directory, and then copy the English file, translate it, and use a build flag. But let me check how WiFiManager includes the strings file first.

Let me look at how WiFiManager.h includes the strings:


找到根源了！WiFiManager 的所有页面文字都在 `wm_strings_en.h` 中。直接把它改成中文。


.pio\libdeps\esp32-s3-devkitc-1\WiFiManager\WiFiManager.h:139:#define WM_STRINGS_FILE "wm_strings_en.h" // this includes constants as dependency


I see - WiFiManager.h has `#define WM_STRINGS_FILE "wm_strings_en.h"`. This means I can potentially override this define to point to a custom Chinese strings file.

Looking at line 139 of WiFiManager.h, the strings file is defined. If I can define `WM_STRINGS_FILE` before WiFiManager.h is included, I could point it to my own Chinese file.

The approach:
1. Create a custom Chinese strings file based on the English one
2. Define `WM_STRINGS_FILE` to point to my custom file before including WiFiManager.h

But actually, looking at how it works, the define is inside WiFiManager.h, so it would already be set by the time I include it. Let me check if there's a guard.

Actually, looking at WiFiManager.h more carefully:


130	#endif
131
132	#include <DNSServer.h>
133	#include <memory>
134
135
136	// Include wm strings vars
137	// Pass in strings env override via WM_STRINGS_FILE
138	#ifndef WM_STRINGS_FILE
139	#define WM_STRINGS_FILE "wm_strings_en.h" // this includes constants as dependency
140	#endif
141	#include WM_STRINGS_FILE
142
143	// prep string concat vars
144	#define WM_STRING2(x) #x
145	#define WM_STRING(x) WM_STRING2(x)
146
147	// #include <esp_idf_version.h>
148	#ifdef ESP_IDF_VERSION
149	    // #pragma message "ESP_IDF_VERSION_MAJOR = " WM_STRING(ESP_IDF_VERSION_MAJOR)

#endif

#include <DNSServer.h>
#include <memory>

// Include wm strings vars
// Pass in strings env override via WM_STRINGS_FILE
#ifndef WM_STRINGS_FILE
#define WM_STRINGS_FILE "wm_strings_en.h" // this includes constants as dependency
#endif
#include WM_STRINGS_FILE

// prep string concat vars
#define WM_STRING2(x) #x
#define WM_STRING(x) WM_STRING2(x)

// #include <esp_idf_version.h>
#ifdef ESP_IDF_VERSION
    // #pragma message "ESP_IDF_VERSION_MAJOR = " WM_STRING(ESP_IDF_VERSION_MAJOR)


Line 138: `#ifndef WM_STRINGS_FILE` — this means I CAN override it by defining `WM_STRINGS_FILE` before including WiFiManager.h!

The approach:
1. Create `include/wm_strings_zh.h` — a Chinese translation of the strings file
2. In `wifi_manager.h` (or `config.h`), define `WM_STRINGS_FILE "wm_strings_zh.h"` before including WiFiManager.h

But wait, `wifi_manager.h` includes `<WiFiManager.h>` at line 18. And `config.h` is included at line 21. So I need to define `WM_STRINGS_FILE` before WiFiManager.h is included.

I should either:
- Define it in `wifi_manager.h` before `#include <WiFiManager.h>`
- Or add it as a build flag in `platformio.ini`

The cleanest approach is to add it in `wifi_manager.h` before the WiFiManager include, and create the Chinese strings file.

Let me create the Chinese strings file first. I'll base it on the English one and translate all the visible strings.


可以覆盖！`WM_STRINGS_FILE` 宏可以在包含 WiFiManager 之前定义，指向自定义中文文件。我来创建中文版。


TodoWrite

创建 wm_strings_zh.h - WiFiManager 配网页面全中文化

修改头文件指向中文语言包

修改 wifi_manager.h 使用中文语言包


创建 wm_strings_zh.h - WiFiManager 配网页面全中文化

修改 wifi_manager.h 使用中文语言包

修改头文件指向中文语言包


Now I need to also read `wm_consts_en.h` since it's included by the strings file and contains route/constant definitions that might have user-visible strings too.