Repeat Quest Helper

Experimental
Helps automate repeatable quest turn-in loops while you stay in NPC dialog.

File Details

SequenceHelper 1.10.3.zip

  • R
  • Apr 21, 2026
  • 1.60 MB
  • 21
  • 2.5.5
  • Classic TBC

File Name

SequenceHelper 1.10.3.zip

Supported Versions

  • 2.5.5
# CHANGELOG

버전 정책: **기능·버그 수정·문서·아이콘 등 저장소 변경 시 `SequenceHelper.toc`의 `## Version` 과 본 파일을 함께 올립니다.**

## 1.10.3
- **Added**: 한방 자가진단 — `runReadinessOneLiner()`. 탱커처럼 풀링 직전·중에 `/seq status` 4~5줄을 매번 읽기 부담스러운 사용자를 위해, **정상이면 1줄 OK · 문제 있으면 헤더 1줄 + 액션 가이드 1~3줄**만 출력.
  - **자동 호출**: 마이크 버튼 **좌클릭 직후** 자동 실행. 진행자 ON/재송출과 함께 그 자리에서 점검 결과를 바로 확인 (탱커가 어차피 누르는 동작에 점검을 묶음).
  - **수동 호출**: 새 명령 `/seq check` (별칭: `/seq ready`, `/seq r`).
  - **점검 항목**: `DB.enabled`, `DB.autoAnnounceBlackMorass`, `DB.iAmAnnouncer`, 인던 안 + 시뮬 모드 동시 ON 여부, 그룹 상태, 진행자 충돌, 송출 트리거 최소 1개 활성(`COMBAT_LOG_EVENT_UNFILTERED` + (`UPDATE_UI_WIDGET` 또는 위젯 API 또는 1초 폴러)).
  - **출력 예 (OK)**: `[OK] 점검 통과  검은 늪 안 · wave 5/18 · 마지막 송출 wave 5 · 진행자 ON · 자동 ON`
  - **출력 예 (문제)**: 헤더 `[!] 점검 실패 N건 — 아래를 처리하세요` + 빨간 번호 매김 액션 (`1) 진행자 OFF — 마이크 버튼 좌클릭`, `2) 검은 늪 안에서 시뮬 모드 ON — /seq sim off`, `3) 송출 트리거 미준비 — /seq probe 로 정밀 점검` 등).
- **Changed**: 슬래시 명령어 `check` 의 의미 이전. 기존에 `check` 는 `/seq probe` (풀덤프) 의 별칭이었으나, 1.10.3 부터 한방 점검(`/seq ready`)의 별칭. `/seq probe` 와 `/seq preflight` 는 풀덤프로 그대로 유지 (정밀 인프라 진단이 필요할 때 사용).
- **Changed**: 인터페이스 옵션의 사용설명 패널 + `/seq help` 슬래시 도움말에 `/seq check` 추가.
- **Net effect**: 탱커는 입장 후 마이크만 누르면 풀링 전 `[OK] 점검 통과` 1줄로 모든 송출 인프라가 준비되었는지 즉시 확인 가능. 문제가 있으면 그 자리에서 정확히 어떤 명령으로 고쳐야 하는지 빨간 번호로 알려 줌. `/seq probe` 의 10+ 줄 풀덤프를 더 이상 매번 읽지 않아도 됨.

## 1.10.3 (English)
- **Added**: One-shot self-test — `runReadinessOneLiner()`. For users (tanks especially) who can't realistically scan 4~5 `/seq status` lines mid-pull, this prints **a single OK line when healthy, or a header + 1~3 numbered action lines when something needs fixing**.
  - **Auto-fired**: runs immediately after **mic button left-click** — same action a tank already performs to start/refresh the announcer, so the readiness check piggybacks on it.
  - **Manual**: new slash command `/seq check` (aliases: `/seq ready`, `/seq r`).
  - **Checks**: `DB.enabled`, `DB.autoAnnounceBlackMorass`, `DB.iAmAnnouncer`, in-instance + sim-mode-still-on, group status, announcer conflict, at least one live send trigger (`COMBAT_LOG_EVENT_UNFILTERED` plus (`UPDATE_UI_WIDGET` or widget API or 1-second poller)).
  - **OK output**: `[OK] check passed  in Black Morass · wave 5/18 · last sent wave 5 · Announcer ON · auto ON`
  - **Failure output**: header `[!] check failed N issues — fix the items below` + red numbered actions (`1) Announcer OFF — left-click mic`, `2) Sim mode ON inside Black Morass — /seq sim off`, `3) send trigger not ready — /seq probe for deep diagnostic`).
- **Changed**: `/seq check` slash command meaning moved. Previously `check` aliased `/seq probe` (full dump); from 1.10.3 it aliases the new one-shot readiness check. `/seq probe` and `/seq preflight` continue to be the full infrastructure dump for deep diagnostics.
- **Changed**: Settings panel help section and `/seq help` slash help text both updated to surface `/seq check`.
- **Net effect**: A tank entering the dungeon just clicks the mic once and gets a single `[OK]` line confirming the entire send pipeline is ready. If anything is wrong, the exact command needed to fix it is printed in red on the same screen. No more reading the 10+ line `/seq probe` dump on every run.

## 1.10.2
- **Fixed (critical)**: 시뮬레이션 모드를 켠 채 검은 늪에 입장하면 **자동 안내가 단 한 줄도 파티에 송출되지 않던 사고** 수정.
  - **재현**: 인던 밖에서 `/seq sim run` 으로 시연 → 끄지 않고 검은 늪 입장 → 마이크 좌클릭(진행자 ON) + 봉화순서는 정상 송출되지만, wave 6/12/18 보스 줄과 wave 13~17 호명은 **본인 채팅창에 `[SIM]` 프리뷰로만** 출력되고 파티엔 빈 상태.
  - **로그 증거 (사용자 제공, 실전 1런)**: `simActive=true`, `widgetEvents=12`, `announceSent=12` 로 트리거·송출 결정은 정상이었으나 `trySendPartyLine` 이 sim 가드에 걸려 모두 본인 프리뷰로 빠짐.
  - **원인**: `trySendPartyLine` 의 sim 가드(`if bmSimActive and not bmSimAllowChat then ... return`) 가 인던 안/밖을 구분하지 않아, sim 모드 ON 상태로 입장하면 봉화순서 외 모든 자동 안내가 본인 채팅창으로만 빠짐.
  - **Fix 1**: `trySendPartyLine` 의 sim 가드를 **인던 밖에서만** 활성화 — `instanceIsBlackMorass()` 체크 추가. 인던 안 = 실전 컨텍스트로 간주.
  - **Fix 2 (UX 안전망)**: `updateBlackMorassZoneState` 에서 검은 늪 진입 시점에 `bmSimEnable(false)` 자동 호출 + 호박색 안내 1회 출력 (`"검은 늪 진입 — 시뮬레이션 모드 자동 OFF (실전 모드로 전환)"`).
- **Net effect**: 이제 sim 모드를 끄지 않은 채 입장해도 (a) 입장 즉시 sim 자동 OFF 되고 (b) 만에 하나 sim 가드가 살아있어도 인던 안에서는 무시되어 wave 6/12/18 보스 줄과 wave 13~17 호명이 정상적으로 파티에 발송됨.

## 1.10.2 (English)
- **Fixed (critical)**: Auto-announce lines silently dropped to local-only `[SIM]` preview when entering Black Morass with simulation mode left on.
  - **Repro**: Run `/seq sim run` outside the dungeon, don't disable sim, walk into Black Morass, click mic (Announcer ON). Beacon-order send goes to party fine, but every wave 6/12/18 boss line and every wave 13~17 call-out only shows in the announcer's own chat as `[SIM] ...` — party sees nothing.
  - **Evidence (user log, live run)**: `simActive=true`, `widgetEvents=12`, `announceSent=12` — triggers and announce decisions all fired correctly, but `trySendPartyLine` short-circuited every line into the local SIM preview.
  - **Root cause**: `trySendPartyLine` sim guard (`if bmSimActive and not bmSimAllowChat then ... return`) didn't distinguish inside-vs-outside instance. Once sim was on, every auto-announce in Black Morass went to the local preview path.
  - **Fix 1**: sim guard in `trySendPartyLine` now only fires **outside** the instance (`instanceIsBlackMorass()` check). Inside the dungeon = live context.
  - **Fix 2 (UX safety net)**: on Black Morass enter, `updateBlackMorassZoneState` automatically calls `bmSimEnable(false)` and prints an amber notice once (`"sim mode auto-disabled on instance enter"`).
- **Net effect**: Even if a user forgets to stop sim before entering, sim is disabled on entry AND the in-instance sim guard is bypassed — wave 6/12/18 boss lines and wave 13~17 call-outs reach party chat reliably.

## 1.10.1
- **Changed**: `applyFlatFrameStyle` 의 backdrop 톤을 ElvUI 기본 창과 일치시키고 테두리를 제거.
  - 배경: `(0.06, 0.06, 0.08, 0.95)` → `(0.08, 0.08, 0.08, 0.8)` — ElvUI 기본 backdrop alpha 0.8 일치
  - 테두리: `edgeFile` 자체를 `nil` 로 빼서 1px 회색 테두리 제거 (`SetBackdropBorderColor` 호출도 같이 삭제)
  - `insets` 1 → 0 (테두리가 없으므로 안쪽 여백도 회수)
- **영향 범위**: `applyFlatFrameStyle` 을 쓰는 곳은 봉화순서 도우미 메인 창(`mainFrame`) 뿐. 인터페이스 옵션 패널 안의 사용설명 스크롤 호스트나 마이크 버튼은 자체 backdrop 을 쓰므로 변경 없음.
- **Net effect**: 도우미 창이 ElvUI 다른 창들과 같은 어두운 반투명 톤으로 보이고, 외곽선이 사라져 화면에 더 자연스럽게 녹아듦.

## 1.10.0
- **Changed**: 마이크 버튼 툴팁을 간결하게 정리. 한 화면에 들어오는 두 줄 형태로 단축.
  - **활성 상태**: `좌클릭 : 순서 안내 / 진행 ON` + `우클릭 : 진행 OFF`
  - **비활성 상태**: `검은 늪 안 / 5인 파티 완성 / 시뮬 모드 일 때만 사용 가능`
  - 자세한 동작 설명(자동 OFF 시점, 충돌 경고, 시뮬 명령 등)은 인터페이스 옵션 → SequenceHelper 의 사용설명 패널로 일원화.
- **Internal**: 툴팁 렌더링을 `SetText(\n)` → `SetText(타이틀)` + 각 줄 `AddLine` 으로 변경. 일부 클라에서 `SetText` 한 번에 들어간 `\n` 이 줄바꿈 안 되던 문제를 회피하고, 헤더(흰색 굵은 글씨)에 애드온 이름이 박힘.
- **Net effect**: 마이크 버튼에 마우스 올리면 두 줄짜리 짧은 안내가 즉시 보임 — 원래의 7줄 설명이 사용 흐름에 비해 길었음.

## 1.10.0 (English)
- **Changed**: Compacted the mic button tooltip to two short lines.
  - **Enabled**: `Left-click : announce order / Announcer ON` + `Right-click : Announcer OFF`
  - **Disabled**: `Usable inside Black Morass / full 5-man party / sim mode`
  - Detailed behavior (auto-OFF timing, conflict warning, sim commands) lives in the Interface Options → SequenceHelper help panel.
- **Internal**: Tooltip rendering switched from a single `SetText("...\n...\n...")` to `SetText(addon name)` + per-line `AddLine`. Works around the case where `\n` inside `SetText` doesn't actually break lines on some clients, and gives the tooltip a clean white header.
- **Net effect**: Hovering the mic button now shows a two-line summary instead of a 7-line wall of text.

## 1.9.9
- **Changed**: 봉화순서 도우미 창을 컴팩트 레이아웃으로 정리. 새로고침 버튼 제거(1.9.5) 후 남던 빈 여백을 회수.
  - 패널 크기: **165 × 198 → 148 × 184** (너비 -10%, 높이 -7%)
  - 좌우 padding: 12 → 10
  - 제목 텍스트 width: 150 → 130
  - 차원문 안내(`bmRiftHintFs`) 위치: TOPLEFT (12, -42) → (10, -30) — title 직후로 12px 위로 올림
  - 차원문 안내 width: 142 → 124
  - 리스트 영역: TOPLEFT (12, -56) → (10, -48) / BOTTOMRIGHT (-12, 42) → (-10, 38)
  - 마이크 버튼 하단 마진: 10 → 6
- **레이아웃 검증** (검은 늪 안 / 5인 파티 기준):
  - 위쪽 chrome = 6(title 위) + 14(title) + 4(gap) + 14(rift hint) + 10(gap) = 48px
  - 리스트 영역 = 184 - 48 - 38 = **98px** (5 rows × 18 = 90px, 8px 버퍼 OK)
  - 아래쪽 chrome = 6(bottom margin) + 24(mic button) + 8(gap) = 38px
- **Net effect**: 도우미 창이 화면을 덜 가리고, 미니맵 옆에 두기에 더 어울리는 비율. 5인 파티 + 차원문 안내 + 마이크 버튼 모두 그대로 들어감. 이름 표시 너비도 한국어 6~8글자 닉네임에 충분.

## 1.9.8
- **Changed**: 봉화순서 도우미 창의 마이크 버튼 재배치. 1.9.5 에서 새로고침 버튼이 사라진 후로 좌하단(`BOTTOMLEFT 12, 10`) 에 혼자 치우쳐 우측이 비어 보였던 상태를 정리.
  - 위치: `BOTTOMLEFT 12, 10` → `BOTTOM 0, 10` (패널 가운데 아래로 정렬)
  - 폭: 66px → 88px (혼자 남았으니 시각적 무게를 약간 키움)
  - 높이: 22px → 24px (탭/타격감 살짝 증가)
  - 리스트 영역 하단 여백: 38 → 42 (버튼이 커진 만큼 호흡 확보)
- **Removed**: 더 이상 참조되지 않는 회전 화살표 텍스처 좌표 상수(`rotU0`/`rotU1`) 정리.
- **Net effect**: 도우미 창 하단이 좌우 대칭으로 안정됨. 클릭 영역이 약 33% 넓어져 미스클릭이 줄고, 마이크 아이콘이 더 또렷이 보임.

## 1.9.7
- **Changed**: 인터페이스 옵션 패널의 제목 한 줄을 사용자 지정 형식으로 고정 — `봉화 순서 도우미 - 설정 / 사용설명 - 펜구스의 흉포 - 거리기사 Ver. <버전>`. `Ver.` 뒤에는 `SequenceHelper.toc` 의 실제 `## Version` 값(`getAddonVersion()`)을 자동으로 채움.
- **Removed**: 1.9.6 에서 제목 아래 회색으로 따로 박혀있던 `v<버전>` 부제(subtitle) 제거 — 버전이 제목 한 줄에 들어가서 중복.
- **Net effect**: 인터페이스 옵션 → 애드온 → SequenceHelper 패널 상단이 한 줄로 정돈됨. 버전이 바뀌면 자동으로 제목에 반영.

## 1.9.6
- **Changed**: 1.9.5 의 자체 floating 설정 창을 폐기하고, **WoW 표준 인터페이스 옵션 패널 안의 한 카테고리**로 등록. 다른 애드온들과 동일하게 ESC → 인터페이스 → 애드온 → SequenceHelper 트리에서 보이고, 미니맵 좌클릭은 그 카테고리로 바로 점프.
- **Implementation**: `Settings.RegisterCanvasLayoutCategory` (DragonFlight/MoP-Classic 이상의 신형 Settings API) 와 `InterfaceOptions_AddCategory` (Classic/TBC/WotLK/Cata 의 구형 InterfaceOptions API) 둘 다 fallback 등록. Anniversary/Classic 클라에서는 구형 경로가 사용됨. 미니맵 좌클릭의 토글 동작도 두 API 모두 지원 — `Settings.OpenToCategory(ID)` 우선, 없으면 `InterfaceOptionsFrame_OpenToCategory(panel)` 두 번 호출(Classic 의 1차 점프 누락 버그 우회).
- **Removed**: 자체 backdrop, 드래그-이동, 자체 닫기 버튼. 옵션 패널이 그것들을 다 관리해 줌. 플로팅 창이 아니므로 `/seq settings` / 미니맵 좌클릭 → 인터페이스 옵션 패널이 열리고 우리 카테고리가 자동 선택됨.
- **Net effect**: 일관성 — Bartender/Details/WeakAuras 등을 설정하던 위치(인터페이스 옵션 → 애드온)에서 SequenceHelper 도 같은 자리에 보임. 더 이상 화면 가운데에 별도 창이 떠오르지 않음.
- **Init**: `PLAYER_LOGIN` 시점에 `createSettingsFrame()` 을 미리 호출해서 미니맵 좌클릭 전이라도 ESC → 인터페이스에서 SequenceHelper 가 처음부터 보이도록 보장.

## 1.9.6 (English)
- **Changed**: 1.9.5's standalone floating settings frame is gone. Settings/Help is now registered as a **standard Interface Options category**, just like every other addon — visible under ESC → Interface → AddOns → SequenceHelper. Minimap left-click opens the Interface Options frame straight to that category.
- **Implementation**: Dual-path registration — modern `Settings.RegisterCanvasLayoutCategory` (DragonFlight / MoP-Classic+) with fallback to legacy `InterfaceOptions_AddCategory` (Classic / TBC / WotLK / Cata). Toggle uses `Settings.OpenToCategory(ID)` first, then `InterfaceOptionsFrame_OpenToCategory(panel)` × 2 (the classic double-call workaround for the first-jump-misses bug).
- **Removed**: Custom backdrop, drag-to-move, custom close button — the options frame manages all of that. No more floating popup in the middle of the screen.
- **Net effect**: Consistency — SequenceHelper now lives in the same Interface Options spot users already use for Bartender / Details / WeakAuras / etc.
- **Init**: `createSettingsFrame()` is called at `PLAYER_LOGIN` so the entry is registered up-front; users can find SequenceHelper in Interface → AddOns even without ever clicking the minimap button.

## 1.9.5
- **Changed**: 미니맵 버튼 좌/우클릭 동작 재배치.
  - **좌클릭** = 새 **설정 / 사용설명 창** 토글 (이전: 도우미 창 토글)
  - **우클릭** = **봉화순서 도우미 창** 토글 (이전: 애드온 사용함/사용안함 토글)
  - 애드온 on/off 는 이제 설정 창 안의 "애드온 사용함" 체크박스로 이동. 매번 미니맵 우클릭으로 켜고 끄던 사용자가 실수로 도우미 창 토글이 한 번 어긋날 수 있으니 첫 적용 시 설명 창에서 한번 짚어보세요.
- **Added**: `SequenceHelperSettings` 프레임 신설. 옵션 4종(애드온 사용함 / 유닛 프레임 번호 표시 / 도우미 창 위치 잠금 / 채팅 알림 직업색 하이퍼링크) 체크박스 + 스크롤 가능한 사용 설명 본문(미니맵 단축키, 마이크 버튼 사용법, 진행자 자동 OFF 시점, 주요 슬래시 명령어)을 한 창에 정리. 슬래시 `/seq settings` (`/seq config`, `/seq options`) 로도 같은 토글.
- **Removed**: 도우미 창 우하단의 **새로고침 버튼(btnR)** 제거. 패널은 OnShow + 0.5s 오버레이 틱 + 3.2s 하트비트 틱에서 자동 갱신되므로 수동 새로고침이 의미 없었고 마이크 버튼 옆 자리만 차지하던 상태였음. 수동 새로고침이 정 필요하면 도우미 창을 닫았다 다시 열면 OnShow 가 `refreshAll` 호출.
- **Locale**: `L.minimap_left` / `L.minimap_right` / `L.hint` / `L.disabled_msg` / `L.slash_help` 한·영 모두 새 동작 기준으로 갱신. `L.btn_refresh` 는 더 이상 참조되지 않지만 호환을 위해 키 자체는 남겨두지 않고 제거(외부에서 참조할 필요 없는 내부 라벨이었음).
- **Net effect**: 설정/도움말이 한 곳에 모이고, 미니맵 한 번의 좌클릭으로 전체 사용법을 다시 볼 수 있음. 도우미 창은 마이크 버튼 + 닫기 버튼만 남아 더 컴팩트.

## 1.9.5 (English)
- **Changed**: Minimap button left/right click roles swapped & reorganized.
  - **Left-click** = open new **Settings / Help** window (was: toggle helper panel)
  - **Right-click** = toggle the **beacon-order helper panel** (was: enable/disable addon)
  - Addon on/off now lives inside the Settings window as the "Addon enabled" checkbox. If you used to right-click the minimap to toggle the addon on/off, your first new-action right-click will toggle the helper panel instead — open Settings once to relearn the shortcut.
- **Added**: `SequenceHelperSettings` frame. Four option checkboxes (Addon enabled / Show numbers on unit frames / Lock helper panel position / Use class-colored player hyperlinks in chat) plus a scrollable How-to-Use body covering minimap shortcuts, mic button usage, when Announcer auto-turns off, and key slash commands. Also reachable via `/seq settings` (aliases `/seq config`, `/seq options`).
- **Removed**: The **Refresh button (btnR)** at the bottom-right of the helper panel. The panel auto-refreshes via OnShow + the 0.5s overlay ticker + the 3.2s heartbeat ticker, so manual refresh added nothing while consuming the slot next to the mic button. If you really need a manual refresh, close and reopen the helper panel — `OnShow` calls `refreshAll`.
- **Locale**: `L.minimap_left` / `L.minimap_right` / `L.hint` / `L.disabled_msg` / `L.slash_help` updated in both koKR and enUS to reflect the new actions. `L.btn_refresh` is no longer referenced.
- **Net effect**: Settings + help live in one place; one minimap left-click brings up the full how-to. Helper panel is more compact, with only the mic button and close.

## 1.9.4
- **Changed**: `trySendPartyLine` 끝의 본인 패널 컬러 echo (`print("|cff00ff00...|r " .. line)`) 제거. 어차피 `SendChatMessage` 가 보낸 `[파티]` 줄이 본인 채팅창에도 자동 echo 되므로, SH 가 추가로 같은 내용을 색상 입혀 한 번 더 띄우면 본인 화면에 동일 줄이 두 번 떠서 거슬린다는 피드백 반영. 1.9.3 까지의 "본인은 색상 풍부 / 파티원은 평문 + 아이콘" 비대칭은 사라지고, 이제 본인도 파티원과 똑같이 평문 + 아이콘만 봄.
- **Kept (debug)**: 송출 검증이 필요할 때를 대비해 컬러 원본은 `seqDbg("local-preview(colored): ...")` 로 옮김. `/seq debug on` 상태에서만 회색 `[debug]` prefix 와 함께 출력. 일반 사용 시엔 안 보임.
- **Net effect**: 진행자 본인 채팅창이 깔끔. wave 호명 / 보스 줄은 `[파티]` 탭에 한 번만 뜨고, `{다이아몬드}` / `{해골}` 아이콘은 그대로 보임. 디버그가 필요하면 `/seq debug on` → 같은 줄을 색상까지 살린 형태로 회색 SH 디버그 prefix 와 함께 추가 echo.

## 1.9.4 (English)
- **Changed**: Removed the "colored local echo" `print(...)` at the end of `trySendPartyLine`. The `[파티]` line emitted by `SendChatMessage` already echoes back to the sender's own chat frame, so SH printing the same content again with color codes was producing a duplicate line in the announcer's chat — distracting per user feedback. The 1.9.3 asymmetry of "rich-colored for self / plain-text + icon for party" is gone; the announcer now sees exactly what party members see.
- **Kept (debug)**: For send-path verification, the original colored line is now logged via `seqDbg("local-preview(colored): ...")` — only emitted when `/seq debug on`, behind the gray `[debug]` prefix. Invisible during normal play.
- **Net effect**: Announcer's chat frame is clean — wave-call / boss lines appear once in `[파티]`, with the `{rt3}` / `{rt8}` raid target icons intact. If you need to inspect the colored original, `/seq debug on` brings back the rich version as a gray debug echo.

## 1.9.3
- **Added**: Wave 호명 / 보스 자동 멘트의 맨 앞에 WoW 공격대 표시 아이콘(raid target marker)을 추가. 호명 줄 = `{다이아몬드}`(보라 다이아몬드), 보스 줄 = `{해골}`(흰 해골). 이 토큰은 `{...}` 형태로 서버를 통과한 뒤 모든 수신자의 클라이언트에서 진짜 raid target 아이콘으로 렌더되므로, `|T|t` 텍스처 escape 와 달리 Anniversary `SendChatMessage` 에서 silent-drop 되지 않음. 1.9.2 의 평문 송출 정책은 그대로 유지(색상/`◈`/`»`/`—` 는 여전히 스크럽).
- **Net effect**: 파티원의 `[파티]` 채팅에 색상 없는 평문이지만, 줄 맨 앞에 진짜 보라 다이아몬드 / 흰 해골 아이콘이 떠서 호명/보스 줄이 일반 잡담과 시각적으로 명확히 구분됨. 본인 패널의 로컬 프리뷰는 색상까지 살아있는 풍부한 형태 그대로.
- **Why this is safe**: `{다이아몬드}` / `{해골}` 토큰은 WoW 채팅 시스템이 1차 시민으로 다루는 마커. `|T|t` 처럼 아이콘 텍스처 경로를 클라가 직접 열지 않고, 서버가 토큰만 전달 → 각 수신자 클라가 자기 로케일/리소스로 아이콘을 그리는 구조라 거절되지 않음. 색상 코드/임의 글리프와 달리 silent-drop 사례가 보고된 적 없음. 한국어 클라(`{다이아몬드}`/`{해골}`)와 영어 클라(`{rt3}`/`{rt8}`)에서 각각 자국어 토큰 사용 — 둘 다 같은 raid target 인덱스(3/8)를 가리키므로 cross-locale 파티에서도 동일하게 렌더됨.

## 1.9.3 (English)
- **Added**: Wave-call / boss auto lines now lead with a WoW raid target marker — wave call uses `{rt3}` (purple diamond), boss line uses `{rt8}` (white skull). These `{...}` tokens are first-class chat markers that survive the server roundtrip and render as real raid target icons on every receiver's client, unlike `|T|t` texture escapes which the Anniversary `SendChatMessage` silently drops. 1.9.2's plain-text policy is preserved (color codes / `◈` / `»` / `—` are still scrubbed before send).
- **Net effect**: Party chat now shows plain-text-but-icon-prefixed lines — a real purple diamond / white skull icon at the start of every wave-call / boss line, making them visually distinct from normal chatter. The announcer's own local preview keeps the full colored formatting.
- **Why this is safe**: `{rt1}`-`{rt8}` (and the localized aliases `{다이아몬드}`/`{해골}`) are markers the WoW chat system treats as first-class. Unlike `|T|t`, the client doesn't open a texture path — the server just passes the token, and each receiver's client renders the icon from its own locale/resources. No silent-drop case has ever been reported for these. koKR clients send `{다이아몬드}`/`{해골}`, enUS clients send `{rt3}`/`{rt8}`; both resolve to the same raid target index (3/8), so cross-locale parties see the same icon.

## 1.9.2
- **Fixed (CRITICAL, the actual silent-drop)**: 1.9.1 fixed the `featureOn=false` gate, but the very next dungeon run revealed a *second* layer of silent failure — auto-announce paths now passed every gate, `pcall(SendChatMessage, line, "PARTY")` returned `OK`, the local SH preview rendered the line in chat, **but the message never appeared in the [파티] log of the sender (and almost certainly not for any party member either)**. Diagnosis from in-dungeon `/seq debug on` log:
  - Same `trySendPartyLine` function. Same `pcall` returning OK.
  - Manual `[봉화순서] 13. 거리전사 / 14. ...` line: **delivered** to `[파티]`.
  - Auto wave-call `◈ [다음 차원문 16] 두닥 님 » 봉화 사용!`: **silently dropped** despite OK.
  - Auto boss `[보스] 아에누스 — 전투준비! 충분히 탐하고 이동!`: **silently dropped** despite OK.
  - The single-axis difference between delivered and dropped: the delivered line is plain Korean + ASCII only; the dropped lines all carry **`|cXXXXXXXX|r` color codes AND/OR BMP-outside glyphs** (`◈` U+25C8 Geometric Shapes, `»` U+00BB, `—` U+2014 em-dash). That combination is silently scrubbed/rejected by the Anniversary-koKR client's `SendChatMessage` path (same family of bug as the `|T|t` / `|H|h` rejection we already worked around in 1.7-ish).
- **Fix**: `scrubChatLineForSend` extended to also strip color escapes (`|cXXXXXXXX...|r`) and replace the three confirmed-suspect glyphs with ASCII (`◈`→`>`, `»`→`>>`, `—`→`-`) **immediately before** `SendChatMessage`. The original (color + pretty) line is still printed to the user's own chat as the local preview, so the announcer's panel readability is preserved; only the line that actually crosses the network is the plain version. With this, `SendChatMessage(PARTY) OK` and actual party delivery finally agree.
- **Net effect (next dungeon run)**: After clicking the mic, every wave 13-17 호명 line and every wave 6/12/18 boss line will land in `[파티]` for everyone — same as the manual `[봉화순서]` line that was already working. No more "OK 받고 누락" pattern.
- **Diagnostic note for future "OK but no delivery"**: The pattern to watch for is *"`SendChatMessage(PARTY) OK` in debug AND no echo of your own line in `[파티]`"*. That always means the koKR/Anniversary chat pipeline silently rejected the payload — usually a not-yet-known character or escape. Add the offending character to the scrubber's replacement table and move on; don't waste another six versions on the upstream gate.

## 1.9.2 (한국어)
- **수정 (치명, 진짜 silent-drop)**: 1.9.1 가 `featureOn=false` 게이트를 잡은 직후의 첫 인던 판에서 **두 번째 단계의 조용한 실패**가 드러남 — 자동 송출 경로가 모든 게이트를 통과하고, `pcall(SendChatMessage, line, "PARTY")` 가 `OK` 를 반환하고, 본인 채팅창에 SH 로컬 프리뷰까지 색상 그대로 떠있는데, **본인의 [파티] 로그에는 그 줄이 끝까지 안 나타남(=거의 확실히 다른 파티원에게도 안 나감)**. `/seq debug on` 인던 로그로 진단:
  - 같은 `trySendPartyLine` 함수, 같은 `pcall` OK.
  - 수동 `[봉화순서] 13. 거리전사 / 14. ...` 줄: `[파티]` **정상 송출**.
  - 자동 호명 `◈ [다음 차원문 16] 두닥 님 » 봉화 사용!`: OK 받고 **silent drop**.
  - 자동 보스 `[보스] 아에누스 — 전투준비! 충분히 탐하고 이동!`: OK 받고 **silent drop**.
  - 송출되는 줄과 누락되는 줄의 단 하나의 축 차이: 송출되는 줄은 평문 한글+ASCII 만, 누락되는 줄은 모두 **`|cXXXXXXXX|r` 색상 코드 + BMP 외곽 글리프**(`◈` U+25C8 기하학 도형, `»` U+00BB, `—` U+2014 em-dash) 를 같이 들고 있음. 이 조합이 Anniversary-koKR 클라의 `SendChatMessage` 경로에서 조용히 스크럽/거부됨 (1.7 즈음에 이미 우회했던 `|T|t` / `|H|h` 거부와 동일 계열의 버그).
- **수정 내용**: `scrubChatLineForSend` 확장 — 송출 직전에 색상 escape (`|cXXXXXXXX...|r`) 를 제거하고, 의심 3글리프를 ASCII 로 치환(`◈`→`>`, `»`→`>>`, `—`→`-`). 본인 패널의 로컬 프리뷰는 **원본(색상 + 글리프 그대로)** 줄을 보여주도록 분리 — 진행자 본인 가독성은 그대로, 네트워크에 나가는 줄만 평문. 이제 `SendChatMessage(PARTY) OK` 와 실제 파티 송출이 비로소 일치.
- **결과 (다음 인던 판)**: 마이크 클릭 후 wave 13-17 의 모든 호명 줄과 wave 6/12/18 의 모든 보스 줄이 `[파티]` 에 정상 표시됨 — 이미 잘 되던 수동 `[봉화순서]` 와 동일 신뢰도. "OK 받고 누락" 패턴 종결.
- **앞으로의 진단 메모**: 이 패턴 — *"디버그에 `SendChatMessage(PARTY) OK` 가 찍히는데 본인 [파티] 에 자기 줄이 안 보임"* — 은 항상 koKR/Anniversary 채팅 파이프라인이 페이로드를 조용히 거절했다는 뜻. 보통 아직 알려지지 않은 글자/escape 가 원인. 해당 글자를 scrubber 의 치환 테이블에 추가하고 끝내면 됨; 또 6 버전을 윗단(게이트) 잡는 데 낭비하지 말 것.

## 1.9.1
- **Fixed (CRITICAL, root cause finally identified)**: After 6 versions of chasing the wrong rabbit, real in-dungeon debug output (`/seq debug on`) revealed the actual cause — every widget portal advance line read `(autoBM=true, featureOn=false, iAmAnnouncer=true)`. **`featureOn=false`** is the gate that was killing every auto-announce path: boss lines (waves 6/12/18) and beacon-call lines (waves 13-17). Manual `[봉화순서]` from mic-click survived because it goes through a different code path that doesn't consult that gate. Root cause: `sequenceHelperFeatureActive()` is defined at line ~399, but `local DB = {}` only happens at line ~502. Lua resolves variable names at function-compile time — at line 399, `DB` is not yet a local in scope, so the function compiles with `DB` as a **global** lookup (`_ENV.DB`). At runtime `_G.DB` is nil → `nil and DB.enabled ~= false` short-circuits to nil (falsy) → returns false unconditionally, **regardless of the actual SavedVariables `DB.enabled = true`**. Same shape of bug bit several other helpers defined before line 502 — `announcerConflictPeers`, `currentAnnouncerName`, the heartbeat sender, etc. — they were all silently reading nil for DB the entire time. (That's why announcer-conflict warnings, despite being designed and tested, never actually fired in the field — the same shadowed `DB` capture.)
- **Fix**: Added `local DB` forward declaration at the top of the file (alongside `ADDON_NAME`/`FLAT_TEX`). Changed line 502's `local DB = {}` to `DB = {}` — same upvalue, just initial assignment. All helpers in the file now share the single canonical `DB` upvalue and the runtime `DB = SequenceHelperDB` assignment in `PLAYER_LOGIN` propagates correctly to every consumer. Net effect: `featureOn` will now correctly report `true` whenever `SequenceHelperDB.enabled ~= false` (i.e., always, unless user explicitly `/seq off`-ed). The 3-redundancy trigger system (CLEU + widget event + 1s poller) all become functional. Boss/beacon auto-announce works in the next dungeon run.
- **수정 (치명, 6 버전 만의 진짜 원인)**: 잘못된 토끼만 쫓던 끝에, 실제 인던에서 `/seq debug on` 으로 받은 로그가 정답을 보여줌 — 모든 widget portal advance 줄이 `(autoBM=true, featureOn=false, iAmAnnouncer=true)`. **`featureOn=false`** 가 모든 자동 송출(보스 6/12/18, 호명 13-17)을 막던 게이트. 마이크 클릭의 `[봉화순서]` 만 살아남은 이유는, 이 줄은 그 게이트를 지나가지 않는 다른 경로라서. 원인: `sequenceHelperFeatureActive()` 가 ~399 행에서 정의되는데, `local DB = {}` 는 ~502 행에서 일어남. Lua 는 이름 해석을 **함수 컴파일 시점**에 하므로, 399 행 시점엔 `DB` 가 아직 local 이 아님 → 컴파일러가 `DB` 를 **global** lookup(`_ENV.DB`) 으로 컴파일. 런타임에 `_G.DB` 는 nil → `nil and DB.enabled ~= false` 는 nil(falsy) 로 단락 → SavedVariables 의 실제 `DB.enabled = true` 와 **무관하게 항상 false 반환**. 같은 형태의 버그가 502 행 이전에 정의된 여러 헬퍼(`announcerConflictPeers`, `currentAnnouncerName`, 하트비트 송신 등)에도 동일하게 있었음 — 모두 조용히 nil 을 보고 있었음. (설계되고 테스트도 한 진행자 충돌 경고가 현장에서 한 번도 안 뜨던 이유 = 같은 shadowed DB 캡처.)
- **수정 내용**: 파일 상단(`ADDON_NAME`/`FLAT_TEX` 옆) 에 `local DB` 전방 선언 추가. 502 행의 `local DB = {}` 를 `DB = {}` 로 변경 — 같은 upvalue 에 초기 할당만. 이제 파일 전체의 모든 헬퍼가 단 하나의 정식 `DB` upvalue 를 공유하고, `PLAYER_LOGIN` 의 `DB = SequenceHelperDB` 할당이 모든 소비자에게 정상 전파됨. 결과: `SequenceHelperDB.enabled ~= false` (사용자가 `/seq off` 명시적으로 안 한 한 항상 참) 이면 `featureOn=true` 로 정확히 보고됨. 3중 redundancy 트리거 시스템(CLEU + 위젯 이벤트 + 1초 폴러) 이 모두 비로소 작동. 다음 판부터 보스/호명 자동 송출 정상.
- **참고 (왜 이전 6 버전에 못 잡았나)**: 1.8.4 ~ 1.9.0 디버그 로그는 본인 채팅창의 노이즈를 줄이려고 차원문 진행에 비례해 출력하도록 게이팅돼 있었고, 동시에 `featureOn` 라벨 자체가 디버그 출력 안에 들어있었지만, 그 게이트가 통과 못해서 `seqDbg` 호출 자체가 실행되지 않았음 → 정작 해당 줄을 본 적이 없었음. 1.8.6 의 위젯 advance 디버그 추가가 게이트 *전*에 출력하도록 바뀌면서 비로소 이 줄이 본인 채팅창에 떴고, 그 결과 `featureOn=false` 라는 결정적 단서가 잡힘. 진단 출력은 게이트 *전*에 있어야 한다는 교훈.

## 1.9.0
- **Fixed (Critical, Catch-up swallowing real waves)**: 1.8.9's catch-up rule used `bmLastAnnouncedWave == 0` as the catch-up trigger, but that variable only advances when the announce gate (`iAmAnnouncer`) actually passes. Real-world failure: player enters BM, doesn't click mic, waves 1-5 fire widget events that pass through the gate as `iAmAnnouncer == false` → `bmLastAnnouncedWave` stays 0 the whole time. Player clicks mic at wave 5. When wave 6 arrives, the catch-up rule sees `bmLastAnnouncedWave == 0 && n == 6 >= 2` → treats it as a mid-run join and **swallows the [보스] 데자 line**. Same logic eats waves 12, 13-17, 18 if mic is enabled later. The new rule keys on `prev == 0 && n >= 2` (the *first* widget reading itself jumped from 0 to >=2), which is the actual signal of "joined a run already in progress." Once any wave has been observed (`prev > 0`), no catch-up regardless of announce state. Net effect: if you're already in BM when wave 1 fires, wave 6/12/18/13-17 will all announce normally even if you toggle the mic mid-run.
- **Added (Diagnostics, trigger counters)**: `/seq status` now prints `triggers: cleuMatched=N  widgetEvents=N  pollerAdvances=N  announceSent=N`. This makes it instantly visible which of the three trigger paths is alive and which is dead in your client. Diagnostic recipe — if `widgetEvents > 0` but `announceSent == 0`, the announce gate (mic / catch-up) is the culprit, not the trigger. If `widgetEvents == 0` while wave is advancing, the widget event isn't firing in your client → poller/CLEU is doing the work. If all four are 0 while wave advances, something is reading the widget through the silent panel-refresh path only — open `/seq probe` to confirm.
- **Added (Visible warning, no-debug-needed)**: When a portal opens and `iAmAnnouncer == false`, an amber warning prints to your chat **once per BM run**: "⚠ 차원문 N번 열림 감지 — 진행자(Announcer) 가 OFF 라 자동 안내가 송출되지 않습니다." Previously you only saw the gate-failure reason via `/seq debug on`; now you get a single proactive nudge with debug OFF. Reset on BM enter.
- **Internal (Safety): catch-up applied at the data layer**: The data-level catch-up (`prev == 0 && n >= 2 → set bmLastAnnouncedWave = n`) is applied in **all** widget paths (event handler, poller, silent panel-refresh) so the addon's state stays consistent regardless of which path observes the first widget value. Previously the silent panel-refresh path could update `bmPortalWaveThisRun` without marking catch-up, leading to the same swallow bug as above on subsequent waves.
- **Internal**: Forward-declared `maybeWarnAnnouncerOff` at the top of the chunk (alongside `seqDbg` and `sendBlackMorassPortalLine`) — its definition lives below the widget/CLEU/poller handlers that call it. Without forward declaration, Lua would compile those callers with a global lookup → `nil` → runtime error on first portal (same shape of bug as the 1.8.7 `seqDbg` crash).
- **수정 (치명, catch-up 이 진짜 wave 를 삼킴)**: 1.8.9 의 catch-up 규칙은 `bmLastAnnouncedWave == 0` 을 catch-up 의 트리거로 썼지만, 이 변수는 송출 게이트(`iAmAnnouncer`) 가 실제 통과해야만 갱신됨. 실제 실패 시나리오: 플레이어가 검은 늪 입장 → 마이크 안 누름 → wave 1-5 의 위젯 이벤트들이 `iAmAnnouncer == false` 로 게이트 차단 → `bmLastAnnouncedWave` 는 줄곧 0. wave 5 즈음 마이크 클릭. wave 6 도착 시 catch-up 규칙이 `bmLastAnnouncedWave == 0 && n == 6 >= 2` 로 보고 mid-run join 으로 간주 → **[보스] 데자 멘트가 통째로 삼켜짐**. 같은 식으로 wave 12, 13-17, 18 도 마이크를 늦게 켰다면 모두 누락. 새 규칙은 `prev == 0 && n >= 2` (위젯이 보고한 *첫* 값 자체가 0 에서 >=2 로 점프) 를 키로 사용 — 이게 진짜 "이미 진행 중인 판에 합류" 의 신호. 한 번이라도 wave 가 관측되면(`prev > 0`) 송출 상태와 무관하게 catch-up 안 걸림. 결과: wave 1 시점에 이미 검은 늪 안에 있었다면, 마이크를 도중에 켜더라도 wave 6/12/18 보스와 13-17 호명이 모두 정상 송출됨.
- **추가 (진단, 트리거 카운터)**: `/seq status` 에 `triggers: cleuMatched=N  widgetEvents=N  pollerAdvances=N  announceSent=N` 줄 추가. 본인 클라이언트에서 3개 트리거 경로 중 어느 게 살아있고 어느 게 죽었는지 즉시 가시화. 진단 레시피 — `widgetEvents > 0` 인데 `announceSent == 0` 이면 트리거가 아니라 송출 게이트(마이크/catch-up) 쪽 문제. wave 가 진행되는데 `widgetEvents == 0` 이면 본인 클라엔 위젯 이벤트가 안 옴 → 폴러나 CLEU 가 일을 하고 있음. wave 진행 중에 4개 모두 0 이면 silent panel-refresh 로만 카운터가 올라가는 비정상 상태 → `/seq probe` 로 확인.
- **추가 (가시 경고, 디버그 OFF 여도 보임)**: 차원문이 열렸는데 `iAmAnnouncer == false` 면 본인 채팅창에 **검은 늪 한 판당 1회** 호박색 경고 출력 — "⚠ 차원문 N번 열림 감지 — 진행자(Announcer) 가 OFF 라 자동 안내가 송출되지 않습니다." 기존엔 게이트 차단 사유를 `/seq debug on` 켜야만 볼 수 있었는데, 이제 디버그 OFF 여도 1회만 즉시 안내. 검은 늪 재입장 시 리셋.
- **내부 (안전): catch-up 을 데이터 계층에 적용**: 데이터 레벨 catch-up (`prev == 0 && n >= 2 → bmLastAnnouncedWave = n`) 을 위젯의 **모든** 경로(이벤트 핸들러, 폴러, silent panel-refresh) 에 적용해, 첫 위젯 값을 어느 경로가 관측하든 애드온 내부 상태가 일관되게 유지됨. 이전엔 silent panel-refresh 가 `bmPortalWaveThisRun` 만 갱신하고 catch-up 마킹은 안 해서, 그 다음 wave 부터 위와 동일한 swallow 버그가 재현될 수 있었음.
- **내부**: `maybeWarnAnnouncerOff` 를 청크 상단에 전방 선언 (`seqDbg`, `sendBlackMorassPortalLine` 옆). 정의는 호출자(위젯/CLEU/폴러 핸들러) 보다 아래에 있음. 전방 선언 없으면 Lua 가 호출자들을 컴파일할 때 global lookup → `nil` → 첫 차원문에서 런타임 에러 (1.8.7 의 `seqDbg` 크래시와 동일한 형태의 버그).

## 1.8.9
- **Added (Catch-up protection)**: When the widget paths (`UPDATE_UI_WIDGET` event handler and 1-second poller) report a wave for the first time, the new rule is: if `bmLastAnnouncedWave == 0` and the reported `n >= 2`, treat it as a *catch-up sync* (joined a run already in progress, e.g. `/reload` mid-Black-Morass). The counter is updated and `bmLastAnnouncedWave` is set to `n`, but **no chat is sent**. This prevents the most-likely scenario for accidental retroactive spam — e.g. reloading at wave 11 then having the addon re-announce "[다음 차원문 13] X 님 » 봉화 사용!" to party after the player already used their beacon. Genuine new entries are unaffected because the first portal in a fresh run is wave 1 (not >= 2), so the rule never triggers there.
- **Note**: This catch-up rule lives only on the widget paths. The CLEU (combat log) path is event-driven by the actual portal-channel cast, so it can't generate retroactive announcements by design — no protection needed there. The poller and event handler share identical guard logic so the behavior is consistent regardless of which trigger lands first after a reload.
- **Trade-off accepted**: If `/reload` happens during the exact ~0.5s window of a portal-channel cast, that single wave's announcement may be skipped. Mitigated by 3 redundant trigger paths (CLEU + widget event + 1s poller); realistic miss probability is near zero. The benefit (no false spam to party chat) outweighs the cost (rare single-wave miss, easily recovered by another party member or a glance at the panel).
- **추가 (catch-up 보호)**: 위젯 경로(`UPDATE_UI_WIDGET` 이벤트 핸들러 + 1초 폴러)가 wave 를 처음 보고할 때, 새 규칙: `bmLastAnnouncedWave == 0` 인데 보고된 `n >= 2` 면 *catch-up sync* (이미 진행 중인 판에 합류 — 예: 검은 늪 안에서 `/reload`) 로 간주. 카운터만 갱신하고 `bmLastAnnouncedWave = n` 으로 마킹하되, **채팅 송출은 건너뜀**. retroactive spam 의 가장 흔한 시나리오 차단 — 예를 들어 wave 11 에서 `/reload` 한 직후 "[다음 차원문 13] X 님 » 봉화 사용!" 같은 줄이 본인이 이미 봉화 쓴 후에 다시 송출되는 사고. 정상 신규 진입은 첫 차원문이 wave 1 이라 (n >= 2 아님) 이 규칙에 안 걸리므로 영향 없음.
- **참고**: 이 catch-up 규칙은 위젯 경로에만 있음. CLEU(전투로그) 경로는 실제 portal-channel 시전이라는 사건 자체에 묶여있어 retroactive 발화가 원천적으로 불가능 — 보호 불필요. 폴러와 이벤트 핸들러는 동일 가드 로직을 공유해, reload 후 어느 트리거가 먼저 도착하든 동일 동작.
- **수용된 trade-off**: `/reload` 가 portal-channel 시전의 ~0.5초 찰나와 정확히 겹치면 그 한 wave 의 안내가 누락될 수 있음. 3중 redundancy(CLEU + 위젯 이벤트 + 1초 폴러)로 실질 누락 확률은 거의 0. 잘못된 spam 방지의 이득이, 드문 케이스의 한 wave 누락(다른 파티원이 채팅으로 알려주거나 패널 보면 회복 가능) 보다 큼.

## 1.8.8
- **Added (Reliability, 3rd trigger path)**: A 1-second poller for the Blizzard portal-counter widget now runs whenever you're inside Black Morass. This is a redundant safety net on top of (1) `COMBAT_LOG_EVENT_UNFILTERED` Portal-Channeling matching and (2) `UPDATE_UI_WIDGET` events. Some clients / servers (Anniversary in particular) may silently drop one or both of those — the poller doesn't depend on either; it just polls `C_UIWidgetManager.GetIconAndTextWidgetVisualizationInfo(3120/527)` directly and fires the announcement when the counter advances `N → N+1`. The existing `bmLastAnnouncedWave` guard ensures any single wave only fires once regardless of which path wins the race.
- **Added (Pre-flight)**: New `/seq probe` (alias `/seq preflight`, `/seq check`) — a comprehensive pre-flight check you can run *before* entering Black Morass to confirm the announce infrastructure will work this run. Verifies SavedVariables, DB flags, CLEU/UPDATE_UI_WIDGET event registration, `C_UIWidgetManager` API availability, the 1-second poller startup, and prints a green "송출 인프라 OK" verdict only if at least one trigger path is live and at least one widget path is available. Also queries the widget directly and prints the live text + parse result for spot-checking.
- **Internal**: `tryRefreshBlackMorassPortalFromWidgets` now takes an optional `announceIfAdvanced` boolean. Existing callers (panel sync only) keep their original behavior — they call it without the argument. The new poller calls it with `true`, which makes the same gating + send happen there too. `startBlackMorassPortalPoller` is fired once at `PLAYER_LOGIN` next to `startTicker`. Poller is gated by `instanceIsBlackMorass()` so it's effectively zero-cost outside BM.
- **추가 (신뢰성, 송출 트리거 3번째)**: 검은 늪 안에 있는 동안 1초마다 블리자드 차원문 카운터 위젯을 직접 폴링하는 안전망 추가. (1) `COMBAT_LOG_EVENT_UNFILTERED` Portal-Channeling 매칭, (2) `UPDATE_UI_WIDGET` 이벤트 위에 얹는 redundancy. 일부 클라이언트(특히 Anniversary)에서 둘 중 하나 또는 둘 다 조용히 누락될 수 있는데, 폴러는 둘 어느 쪽에도 의존하지 않고 `C_UIWidgetManager.GetIconAndTextWidgetVisualizationInfo(3120/527)` 를 직접 1초마다 폴링해 카운터가 `N → N+1` 로 올라가는 순간 송출. `bmLastAnnouncedWave` 가드 덕분에 세 경로 중 누가 먼저 잡든 한 wave 당 1회만 송출.
- **추가 (사전 점검)**: `/seq probe` (별칭 `/seq preflight`, `/seq check`) — 검은 늪 *입장 전*에 미리 돌려보는 종합 사전 점검. SavedVariables, DB 플래그, CLEU/UPDATE_UI_WIDGET 이벤트 등록 상태, `C_UIWidgetManager` API 가용성, 1초 폴러 기동 여부를 모두 확인하고, 송출 트리거 1개 이상 + 위젯 경로 1개 이상이 살아있어야만 녹색 "송출 인프라 OK" 판정. 위젯도 즉시 한 번 호출해 실제 텍스트 + 파싱 결과를 같이 표시해 현장 확인 가능.
- **내부**: `tryRefreshBlackMorassPortalFromWidgets` 가 옵션 인자 `announceIfAdvanced` 추가. 기존 호출자(패널 동기화 용도) 는 인자 없이 호출 → 원래 동작 유지. 새 폴러는 `true` 로 호출 → 동일 게이트 + 송출 수행. `startBlackMorassPortalPoller` 는 `PLAYER_LOGIN` 시점에 `startTicker` 옆에서 한 번만 부팅. 폴러는 `instanceIsBlackMorass()` 로 즉시 게이팅 — 검은 늪 밖에선 사실상 무비용.

## 1.8.7
- **Fixed (Critical)**: 1.8.6's widget-driven auto-announce path was crashing on every UI widget update with `attempt to call global 'seqDbg' (a nil value)` at `handleBlackMorassUiWidgetUpdate`. Root cause: `seqDbg` was declared as `local function` *below* the widget handler in source order, so when the handler ran Lua looked it up as a global → nil → runtime error → execution aborted before reaching the `sendBlackMorassPortalLine(n)` fallback call. Net effect: the entire 1.8.6 widget fallback was silently dead, and the original CLEU-only path was the only thing left (i.e. exactly the bug 1.8.6 was supposed to fix). Now `seqDbg` is forward-declared at the top of the chunk alongside `sendBlackMorassPortalLine`, and its definition is rewritten as `seqDbg = function ...` so the upvalue is shared. Confirmed Korean-client widget text (`"시간의 균열 열림: 1/18"`) parses correctly into `n=1` — only the debug call was killing the path.
- **Changed (Debug noise)**: `/seq debug on` no longer floods the chat with every Creature `SPELL_CAST_SUCCESS` inside Black Morass (pet/trash spells, channels, etc). It now prints only portal-related events: widget advance, portal-channel match, gating decision, and `trySendPartyLine` outcome. The full per-spell trace (useful for finding the right spellId/name to add to `BM_PORTAL_CHANNEL_SPELL_IDS`) is moved behind `/seq debug verbose`.
- **Added**: New debug levels — `/seq debug on` (portal-focused, recommended), `/seq debug verbose` (everything, spammy), `/seq debug off`. `/seq status` and `/seq debug` (no arg) now show the current level (`OFF` / `ON` / `VERBOSE`). `DB.debug` is now a tri-state value (`false` / `true` / `"verbose"`) but the truthiness check inside `seqDbg` still works for both `true` and `"verbose"`.
- **수정 (치명)**: 1.8.6 의 위젯-driven 자동 송출 경로가 위젯 업데이트마다 `attempt to call global 'seqDbg' (a nil value)` 로 죽고 있던 문제 해결. 원인: `seqDbg` 가 `local function` 으로 위젯 핸들러보다 *아래* 라인에 정의돼 있어, 핸들러 실행 시 Lua 가 global lookup → nil → 런타임 에러로 그 아래 `sendBlackMorassPortalLine(n)` fallback 호출까지 통째로 중단됐음. 결과적으로 **1.8.6 의 핵심 수정인 위젯 fallback 자체가 무력화** 되어, 1.8.5 와 동일하게 CLEU 단독 경로만 살아있었음(=고치려던 버그가 그대로 재현). `seqDbg` 를 청크 상단에 `sendBlackMorassPortalLine` 과 함께 전방 선언, 정의도 `seqDbg = function ...` 로 변경해 upvalue 공유. 한글 클라이언트 위젯 텍스트(`"시간의 균열 열림: 1/18"`) 가 `n=1` 로 정상 파싱되는 것도 사이드로 확인됨 — 파싱이 아니라 debug 호출 한 줄이 경로 전체를 죽이고 있었음.
- **변경 (디버그 노이즈)**: `/seq debug on` 이 더 이상 검은 늪 안 모든 크리쳐의 `SPELL_CAST_SUCCESS` (잡몹 평타·시전 등) 를 채팅에 쏟지 않음. 차원문 관련만 출력 — 위젯 advance, portal-channel 매칭, 게이트 통과/차단, `trySendPartyLine` 결과. 모든 크리쳐 스펠을 보고 싶으면(`BM_PORTAL_CHANNEL_SPELL_IDS` 에 추가할 spellId/이름 확인용) `/seq debug verbose` 로.
- **추가**: 디버그 레벨 신설 — `/seq debug on` (차원문 중심, 권장), `/seq debug verbose` (전체, 시끄러움), `/seq debug off`. `/seq status` 와 `/seq debug` (인자 없음) 에 현재 레벨(`OFF` / `ON` / `VERBOSE`) 표시. `DB.debug` 는 이제 3-state 값(`false` / `true` / `"verbose"`) 이지만 `seqDbg` 내부의 truthiness 체크가 둘 다 잡아냄.

## 1.8.6
- **Fixed (Critical, Reliability)**: Boss/beacon-call lines kept silently failing in real Black Morass even though `iAmAnnouncer` was clearly ON (player was successfully sending `[봉화순서]` via mic-click). Root cause: the only trigger for the auto-announce path was the combat log `SPELL_CAST_SUCCESS` for *Portal Channeling*, and the spell name/id matcher (`bmSpellMatchesPortalChannel` checking spellId 31387 + the substrings `차원문` + `채널/집중`) did not match the actual spell on the Anniversary/koKR client (likely a different localized name or a different spell id altogether for the Rift Keeper channel). Now the **Blizzard portal-counter UI widget** (widgetID 3120 / 527 — same source as the in-game "12/18" indicator, also used by DBM) is wired as a redundant trigger: whenever the widget reports the wave going `N → N+1`, the same gating (`autoAnnounceBlackMorass / enabled / iAmAnnouncer`) is applied and the boss/call line fires. So even on clients where the spell match silently misses, the widget keeps announcements flowing.
- **Added (Anti-duplicate)**: New `bmLastAnnouncedWave` guard ensures that wave N is announced exactly once per Black Morass run, no matter which trigger fires first (combat log vs widget). Resets to 0 on BM enter/leave.
- **Added (Diagnostics)**: `/seq status` now also prints `lastAnnounced=N`. With `/seq debug on`, widget-driven advances log a `widget portal advance: N → N+1` line so you can see which trigger path is doing the work in your specific client.
- **Internal**: `sendBlackMorassPortalLine` is now forward-declared at the top of the chunk so `handleBlackMorassUiWidgetUpdate` (defined earlier in source order) can call it. Definition site changed from `local function sendBlackMorassPortalLine` to `sendBlackMorassPortalLine = function`.
- **수정 (치명·신뢰성)**: 진행자 ON 으로 마이크 좌클릭 [봉화순서] 안내는 잘 나가는데, 정작 차원문이 열릴 때 자동 보스/호명 멘트가 침묵하던 문제 해결. 원인: 자동 송출 트리거가 균열 지기의 *Portal Channeling* SPELL_CAST_SUCCESS 단 하나뿐이었고, 매칭 함수(`bmSpellMatchesPortalChannel` — spellId 31387 + `차원문`+`채널/집중` 부분 일치) 가 한글/Anniversary 클라이언트에서 실제 spell 과 어긋나면(현지화 이름/ID 차이) 한 번도 발화하지 못함. 이제 **블리자드 차원문 카운터 UI 위젯**(widgetID 3120 / 527 — 게임 내 "12/18" 표시기와 동일 소스, DBM 도 같은 ID 사용) 을 보조 트리거로 결합. 위젯이 N → N+1 로 올라가면 동일 게이트(`autoAnnounceBlackMorass / enabled / iAmAnnouncer`) 통과 후 보스/호명 멘트 송출. spell 매칭이 누락되는 클라이언트에서도 위젯이 안내를 계속 흘려줍니다.
- **추가 (중복 방지)**: 같은 차원문 번호가 두 트리거(전투로그·위젯) 양쪽으로 잡혀도 1회만 송출되도록 `bmLastAnnouncedWave` 가드 추가. 검은 늪 입퇴장 시 0으로 리셋.
- **추가 (진단)**: `/seq status` 에 `lastAnnounced=N` 표시 추가. `/seq debug on` 상태에서는 위젯 트리거 시 `widget portal advance: N → N+1` 줄이 회색으로 출력되어, 본인 클라이언트에서 실제로 어느 경로(전투로그 vs 위젯) 가 송출을 담당했는지 확인 가능.
- **내부**: `handleBlackMorassUiWidgetUpdate`(소스 순서상 위쪽) 에서 호출하기 위해 `sendBlackMorassPortalLine` 을 청크 상단에 전방 선언. 정의는 `local function …` → `sendBlackMorassPortalLine = function …` 로 변경.

## 1.8.5
- **Added (Diagnostics)**: New `/seq debug on|off` toggle and `/seq status` command to investigate why boss/beacon lines aren't reaching party chat. With debug ON, every Black Morass portal channel cast prints which gate (autoBM / addon enabled / `iAmAnnouncer` / `IsInGroup`) blocked the broadcast. `/seq status` prints a one-shot snapshot of all relevant flags plus the most common failure causes and how to fix each.
- **Internal**: New `seqDbg(fmt, ...)` helper (silent unless `DB.debug` is true). `handleBlackMorassPortalFromCombatLog` logs the candidate `SPELL_CAST_SUCCESS` (id + name), gating outcome and the four conditions. `sendBlackMorassPortalLine` logs the chosen branch (호명 / 보스전 / silent) and beacon mapping result. `trySendPartyLine` logs `IsInGroup`, final length, and `SendChatMessage` success/skip. `DB.debug` defaults to `false`; nothing prints unless explicitly enabled.
- **추가 (진단)**: `/seq debug on|off` 토글과 `/seq status` 명령 신설 — "보스/13~17 멘트가 왜 파티에 안 나가는지" 직접 짚어볼 수 있도록 함. debug 를 켜면 검은 늪 차원문 시전이 감지될 때마다 어떤 게이트(`autoBM` / `enabled` / `iAmAnnouncer` / `IsInGroup`) 가 막았는지 회색 로그로 출력. `/seq status` 는 현재 핵심 플래그 전체와 가장 흔한 미송출 원인 3가지 + 해결법을 한 번에 표시.
- **내부**: `seqDbg(fmt, ...)` 헬퍼 추가 (`DB.debug=true` 일 때만 출력). `handleBlackMorassPortalFromCombatLog` 가 후보 `SPELL_CAST_SUCCESS` (id·이름), 게이트 통과/차단 사유, 4가지 조건값을 모두 기록. `sendBlackMorassPortalLine` 은 선택된 분기(호명 / 보스전 / 침묵)와 봉화 매핑 결과를, `trySendPartyLine` 은 `IsInGroup`·최종 길이·`SendChatMessage` 성공/스킵을 기록. `DB.debug` 기본값 `false`.

## 1.8.4
- **Added (Visual)**: Each row in the list panel now shows a **green hollow border** around the addon-user icon when that party member is currently the Announcer. Source of truth: `DB.iAmAnnouncer` for self, `seqAddonPeerLeaders[guid]` (already maintained from peer heartbeats) for others. Border auto-updates whenever announcer state changes (left/right-click on mic, slash command, BM enter/leave, sim toggle) since those all flow through `refreshAll() → updateListPanel()`.
- **Internal**: `ensureSeqListRow` now also creates `row.iconBorder` (a small backdrop frame with a 1.5px green edge texture, hidden by default). `updateListPanel` toggles it together with the icon — never shown when the addon icon itself is hidden, and never shown for sim entries (sim uses the desaturated icon to emphasize "fake").
- **추가 (시각)**: 목록 패널 각 행의 애드온 사용자 아이콘에 **녹색 빈 테두리** 표시 — 그 파티원이 현재 진행자(Announcer) 인 경우. 본인 판정은 `DB.iAmAnnouncer`, 다른 파티원은 하트비트로 갱신되는 `seqAddonPeerLeaders[guid]` 기준. 진행자 상태가 바뀌는 모든 경로(마이크 좌/우클릭, 슬래시, 검은 늪 입퇴장, 시뮬 토글) 가 이미 `refreshAll() → updateListPanel()` 를 호출하므로 테두리 표시도 자동 갱신.
- **내부**: `ensureSeqListRow` 가 `row.iconBorder` (1.5px 녹색 테두리 백드롭 프레임, 기본 숨김) 도 생성. `updateListPanel` 에서 아이콘 표시 여부와 함께 토글 — 아이콘 자체가 숨김인 행이나 시뮬 가짜 멤버 행에는 테두리도 표시 안 함 (시뮬은 흑백 아이콘 자체로 "가짜" 강조).

## 1.8.3
- **Added (UX)**: Right-click on the mic button now manually flips Announcer **OFF** immediately — previously the only way to do this was via `/seq leader off`. Left-click behavior is unchanged (Announcer ON + send beacon order; re-click re-broadcasts). Right-click prints `[진행자 OFF]` (or `[Announcer OFF]`) and propagates the heartbeat so peers see your state change. If you weren't Announcer to begin with, it prints a small "이미 진행자 OFF 입니다." (`Announcer is already OFF.`) note instead of doing nothing silently.
- **Changed (Button enable)**: `syncAnnouncerEnabled` now keeps the mic button enabled whenever you are currently Announcer, even if the activation conditions (in BM / sim / full 5-party) become invalid mid-session (e.g. a member leaves and party drops to 4). This guarantees the right-click-to-OFF escape hatch always works from the UI; otherwise you'd be stuck calling the slash command. Enable rule restated: `DB.enabled AND (canBecomeAnnouncer() OR DB.iAmAnnouncer)`.
- **i18n**: `L.announcer_already_off` (koKR/enUS); `L.btn_announce_tt` (koKR/enUS) tooltip rewritten to document left/right-click split.
- **추가 (UX)**: 마이크 버튼 **우클릭** 시 진행자 즉시 **OFF** — 이전에는 `/seq leader off` 슬래시뿐이었음. 좌클릭 동작은 동일(진행자 ON + 봉화순서 송출 / 재좌클릭 시 재송출). 우클릭은 `[진행자 OFF]` 안내를 띄우고 하트비트를 즉시 전파해 다른 SequenceHelper 사용자도 본인 상태 변화를 인지함. 이미 OFF 였으면 "이미 진행자 OFF 입니다." 안내만 띄움.
- **변경 (버튼 활성 규칙)**: `syncAnnouncerEnabled` 가 본인이 진행자 ON 인 동안에는 활성 조건(검은 늪 / 시뮬 / 5인 파티) 이 도중에 깨져도 마이크 버튼을 활성 유지함 (예: 파티원 빠져 4명이 됨). UI 우클릭 OFF 탈출구를 항상 보장하기 위함. 새로운 규칙: `DB.enabled AND (canBecomeAnnouncer() OR DB.iAmAnnouncer)`.
- **i18n**: `L.announcer_already_off` (한/영), `L.btn_announce_tt` (한/영) 툴팁을 좌/우클릭 구분 표기로 재작성.

## 1.8.2
- **Fixed (Critical)**: Boss lines for rifts 6/12/18 and beacon-call lines for rifts 13–17 silently failed to reach party chat in real Black Morass. Root cause: the message templates introduced in 1.8.0 included `|T…|t` texture escapes (skull raid target marker, Darnassus portal icon). The Anniversary client rejects `|T…|t` (and `|H…|h`) in `SendChatMessage` with "Invalid escape code in chat message" — same restriction documented in 1.1.11 for `|Hplayer:…|h`. The error was caught by `pcall` and printed once but easy to miss; net result: the announcer pressed the mic, but party saw nothing.
- **Changed (Templates)**: Removed all `|T…|t` from outgoing chat templates and replaced with safe text+color alternatives — color codes `|c…|r` are still allowed and render on every client.
  - `L.bm_boss_*` (koKR/enUS): skull texture → red `[보스]` / `[BOSS]` colored prefix.
  - `L.bm_call_member` (koKR/enUS): Darnassus portal icon → pink `◈` glyph (still pretty, no escape).
- **Added (Defensive)**: `trySendPartyLine` now runs `scrubChatLineForSend(line)` before `SendChatMessage` to strip any `|T…|t` and `|H…|h` escapes from any future template that accidentally reintroduces them. First strip prints a one-time amber warning so it's noticed. Failed sends now print BOTH the error AND the offending line in red so diagnosis is easier next time.
- **수정 (치명)**: 1.8.0 에서 도입한 `|T…|t` 텍스처 escape 가 들어 있는 멘트(보스 6/12/18 의 해골 표식, 13~17 호명의 다나서스 포탈 아이콘)가 Anniversary 클라이언트의 `SendChatMessage` 에서 "Invalid escape code in chat message" 로 거부되어 **실제 검은 늪에서 진행자 ON 상태인데도 파티 채팅에 한 줄도 안 나가던 문제** 해결. 같은 이슈가 1.1.11 에서 `|Hplayer:…|h` 하이퍼링크에 대해서 이미 문서화되어 있었으나 텍스처 escape 도 동일 제한이 있다는 점을 못 잡고 있었음. `pcall` 이 한 줄 에러를 띄우긴 했지만 놓치기 쉬움.
- **변경 (멘트 템플릿)**: 송출용 멘트에서 `|T…|t` 를 모두 제거하고 색상 escape `|c…|r` (모든 클라에서 정상 렌더) + 평문 글리프로 대체.
  - `L.bm_boss_*` (한/영): 해골 텍스처 → 빨간 `[보스]` / `[BOSS]` prefix.
  - `L.bm_call_member` (한/영): 다나서스 포탈 아이콘 → 분홍 `◈` 글리프 (escape 없이 시각적 강조 유지).
- **추가 (방어)**: `trySendPartyLine` 이 `SendChatMessage` 호출 직전에 `scrubChatLineForSend(line)` 으로 어떤 경로로든 메시지에 섞여들어온 `|T…|t`, `|H…|h` escape 를 자동으로 정화. 한 번이라도 정화가 일어나면 호박색으로 1회 경고를 띄워 향후 재발 시 즉시 알아차릴 수 있음. 송출 실패 시 에러 메시지와 함께 **실제 실패한 라인 자체도 빨간색으로 출력** 하도록 진단 강화.

## 1.8.1
- **Changed (Mic enable condition)**: The announcer (mic) button is no longer locked to "inside Black Morass + sim mode" only. It now also enables when a **full 5-man party is formed**, so the leader can broadcast the beacon order as a heads-up before the group walks into the dungeon. Restated condition: enabled when in Black Morass, in `/seq sim` mode, or in a 5-member party (and not in a raid).
- **Refactored**: New helper `canBecomeAnnouncer()` consolidates this rule into one place; `syncAnnouncerEnabled`, the mic button `OnClick` guard, and `/seq leader on` now all share it. Forward-declared `local canBecomeAnnouncer` together with the existing forward-declared upvalues to keep closure capture clean.
- **i18n**: `L.btn_announce_disabled_tt` and `L.announcer_outside_warn` (koKR/enUS) reworded to mention the new "5-man party full" path.
- **Note**: Mic button visibility auto-updates on `GROUP_ROSTER_UPDATE` since the existing event handler already runs `refreshAll() → refreshOperateWidgets() → syncAnnouncerEnabled()`. No new event registration needed.
- **변경 (마이크 활성 조건)**: 진행자 마이크 버튼이 더 이상 "검은 늪 안 + 시뮬 모드" 만으로 한정되지 않습니다. **5인 파티가 가득 찬 경우** 에도 활성화되어, 인던 진입 전에 미리 봉화순서를 파티에 공지할 수 있습니다. 정리된 조건: 검은 늪 안 OR `/seq sim` OR 5인 파티 (+ 공격대 편성이 아닐 것).
- **리팩토링**: `canBecomeAnnouncer()` 헬퍼 신설로 위 조건을 한 곳에 모음. `syncAnnouncerEnabled`, 마이크 OnClick 가드, `/seq leader on` 슬래시 가드가 모두 동일 헬퍼를 사용. 클로저 캡처가 깔끔하도록 `local canBecomeAnnouncer` 도 기존 전방 선언들과 함께 선언.
- **i18n**: `L.btn_announce_disabled_tt`, `L.announcer_outside_warn` (한/영) 문구를 새 조건에 맞게 보완.
- **참고**: 파티원 입출 시 마이크 버튼이 자동으로 활성/비활성 갱신됨 — 기존 이벤트 핸들러가 `GROUP_ROSTER_UPDATE` 에서 `refreshAll() → refreshOperateWidgets() → syncAnnouncerEnabled()` 를 이미 호출하므로 추가 이벤트 등록 불필요.

## 1.8.0
- **Changed (Beacon call line)**: The 13–17 rift call line (`L.bm_call_member`) is restyled for readability: Darnassus pink portal icon (`Spell_Arcane_PortalDarnassus`) + white `[다음 차원문 N]` bracket + class-colored player name + "님" honorific + gold `» 봉화 사용!` action. The class color is embedded directly via `|cffXXXXXX…|r` so recipients see colored names even without a chat-color addon.
- **Changed (Boss raid marker)**: Boss lines for rifts 6/12/18 now embed the actual skull raid target icon via the `|TInterface\TargetingFrame\UI-RaidTargetingIcon_8:0|t` texture escape. The previous `{skull}` token was sender-side macro syntax and was passed through `SendChatMessage` as literal text — recipients saw `{skull}` instead of the icon. Texture escapes are preserved by the chat system and render on all clients with the standard Blizzard asset.
- **Added (Mic re-click)**: Pressing the announcer (mic) button again while already announcing now re-sends the current beacon order, with a local feedback line `봉화순서를 다시 알렸습니다.` so the action is visible to the user. First press still flips announcer ON and prints `[진행자 ON]` as before.
- **Added (i18n)**: `L.announce_resend` (koKR/enUS).
- **Removed (UI noise)**: The "드래그하여 이동 (목록)" hint font string under the panel title is gone (and the now-unused `L.panel_drag` strings cleaned up). The lock button already conveys drag state, so the hint was redundant clutter.
- **Internal**: `getBeaconNameForWave` now returns `name, unit, classFile` so `sendBlackMorassPortalLine` can pass the colored name into the chat format. `colorizeNameByUnit` handles both real party units (via `UnitClass`) and simulation entries (via `classFile` override) — class color works in both real Black Morass and `/seq sim`.
- **변경 (호명 멘트)**: 13~17번 차원문 호명 라인(`L.bm_call_member`) 시각 정리. 분홍 포탈 아이콘(다나서스) + 흰색 `[다음 차원문 N]` 대괄호 + **직업색** 플레이어 이름 + `님` 호칭 + 금색 `» 봉화 사용!`. 직업색은 메시지에 `|cff…|r`로 직접 박혀 있어 받는 사람이 채팅 색상 애드온이 없어도 직업색이 보입니다.
- **변경 (보스전 해골 표식)**: 6/12/18 보스 멘트의 해골 표식을 실제 공격대 표식 텍스처(`|TInterface\TargetingFrame\UI-RaidTargetingIcon_8:0|t`)로 송출하도록 수정. 이전의 `{skull}` 토큰은 매크로 입력 단계에서만 파싱되는 문법이라 `SendChatMessage`로 보낼 땐 그대로 리터럴 텍스트로 전송되어 받는 사람 화면에 `{skull}` 글자로 보였습니다. 텍스처 escape 는 모든 클라이언트가 기본 에셋으로 렌더링.
- **추가 (마이크 재클릭)**: 진행자(마이크) 버튼이 이미 켜진 상태에서 다시 누르면 현재 봉화순서를 다시 송출하며, 본인 채팅창에 `봉화순서를 다시 알렸습니다.` 피드백 한 줄을 띄움. 첫 클릭은 기존처럼 진행자 ON + `[진행자 ON]` 안내.
- **추가 (i18n)**: `L.announce_resend` (한/영).
- **삭제 (UI 정리)**: 패널 타이틀 아래 `드래그하여 이동 (목록)` 안내 텍스트 제거 및 더 이상 쓰이지 않는 `L.panel_drag` 문자열 정리. 좌상단 자물쇠 아이콘이 이미 드래그 가능 여부를 충분히 알려주고 있어 중복이었음.
- **내부**: `getBeaconNameForWave` 가 `name, unit, classFile` 까지 반환하도록 확장하여 `sendBlackMorassPortalLine` 에서 직업색 이름을 그대로 포맷에 끼워넣음. `colorizeNameByUnit` 은 실제 파티원(unit→`UnitClass`)과 시뮬 가짜 파티원(`classFile` 우선)을 모두 처리하므로 검은 늪 실전과 `/seq sim` 양쪽에서 동일하게 직업색이 적용됩니다.

## 1.4.1
- **Removed**: The "WeakAura is enabled — please disable it" one-time chat warning added in 1.4.0. It only inspected the local client's `WeakAurasSaved` and could not see other party members' WeakAuras at all. With the local user already removing the aura, the check is dead code; party-side conflicts cannot be detected client-side. Removed `isWagoBeaconAuraActive`, `maybeWarnWagoConflict`, `_wagoConflictNotified`, both call sites in `updateBlackMorassZoneState`, and the `L.bm_wago_conflict` strings (koKR/enUS).
- **Note**: If a party member still has the original WeakAura active in Black Morass, that member's client will independently send the same lines to PARTY chat (the WeakAura calls `SendChatMessage` from each loaded client whose load conditions match: `zone=검은늪` + `ingroup=group`). SequenceHelper has no way to detect or suppress that — please ask them out-of-band.
- **삭제**: 1.4.0 에서 추가했던 "위크오라가 켜져 있으니 꺼주세요" 1회 안내 제거. 내 PC 의 `WeakAurasSaved` 만 점검할 수 있어 파티원의 위크오라 상태는 어차피 감지 불가였고, 사용자가 이미 본인 위크오라를 삭제한 상황에서는 죽은 코드였음. `isWagoBeaconAuraActive`, `maybeWarnWagoConflict`, `_wagoConflictNotified`, `updateBlackMorassZoneState` 의 두 호출부, 그리고 `L.bm_wago_conflict`(koKR/enUS) 까지 정리.
- **참고**: 파티원 누군가가 원본 위크오라를 여전히 켜둔 채 검은 늪에 있다면, 그 사람 클라에서 동일한 라인이 PARTY 채팅에 별도로 송출됩니다 (위크오라의 로드 조건 `zone=검은늪` + `ingroup=group` 만 만족하면 그 클라가 직접 `SendChatMessage` 호출). 이건 클라이언트 사이드에서 감지·억제할 방법이 없으니, 채팅이 두 번 가면 그 사람에게 직접 위크오라를 꺼달라고 요청해 주세요.

## 1.4.0
- **Added (WeakAura parity)**: Black Morass rift announcer is now feature-equivalent to the WeakAura `검은 늪 - 시간의 봉화` (wago: `3aYcV6UzM`). When the rift counter advances to **13–17**, SequenceHelper auto-calls the matching beacon-order member to PARTY chat as `(다음 웨이브 N) 이름 - 써주세요!`. When the counter hits **6 / 12 / 18**, it sends `보스전! 충분히 탐하고 전투해주세요!` (the original WeakAura's `(6 or 12 or 18)` actually short-circuits to `6` only — that bug is intentionally fixed here). All other rifts (1–5, 7–11) stay silent — only the panel `n/18` indicator updates, matching the WeakAura's tone.
- **Changed**: The previous catch-all rift line `[봉화순서] 검은 늪 — N번째 차원문, N번.` is no longer sent on every rift. It was noisy and not what the original WeakAura did. (`L.bm_auto_party` is kept for now in case you want it back via a future toggle.)
- **Added (i18n)**: `L.bm_call_member`, `L.bm_boss` for koKR/enUS.
- **추가 (위크오라 동등화)**: 검은 늪 차원문 알림이 위크오라 `검은 늪 - 시간의 봉화`(wago: `3aYcV6UzM`) 와 기능 동등이 되었습니다. 차원문 카운트가 **13~17** 이 되면 봉화순서상 해당 슬롯 인원을 파티 채팅에 `(다음 웨이브 N) 이름 - 써주세요!` 로 호명합니다. **6 / 12 / 18** 차원문에서는 `보스전! 충분히 탐하고 전투해주세요!` 를 송출합니다 (원본 위크오라의 `(6 or 12 or 18)` 는 lua 평가상 `6` 으로 단축되어 사실상 6번에서만 발동하는 버그가 있었는데, SequenceHelper 는 이를 의도적으로 6/12/18 모두에서 발동하도록 수정). 그 외(1~5, 7~11) 는 침묵하며, 패널의 `n/18` 표시만 갱신됩니다 — 위크오라와 동일한 톤.
- **변경**: 매 차원문마다 나가던 `[봉화순서] 검은 늪 — N번째 차원문, N번.` 일괄 라인은 더 이상 자동 송출되지 않습니다. 위크오라 원본 동작과 달랐고 시끄러웠던 부분 정리. (`L.bm_auto_party` 문자열은 차후 토글 옵션 부활을 대비해 보존.)
- **참고**: 봉화순서 매핑은 패널·오버레이와 동일한 `getOrderedUnits()` 결과(player 가 13번 시작) 를 그대로 사용합니다. 즉 패널에서 13번이라고 보이는 사람이 13번 차원문 호명 대상입니다. (위크오라는 이름순 정렬을 썼으나 결과 일관성을 위해 패널 순서를 우선.)

## 1.3.1
- **Fixed**: `updateListPanel` raised `attempt to perform arithmetic on global 'bannerH' (a nil value)` at `SequenceHelper.lua:874` whenever the list height was recalculated. `bannerH` was a leftover global reference from an old banner layout that no longer exists in the list area. Replaced with a function-local `local bannerH = 0` so the arithmetic always succeeds; the slot is documented for future banner reinstatement.
- **수정**: `updateListPanel` 안에서 list 높이를 재계산할 때마다 `attempt to perform arithmetic on global 'bannerH' (a nil value)` 에러가 `SequenceHelper.lua:874` 에서 발생하던 문제 해결. `bannerH` 는 list 영역에 더 이상 존재하지 않는 옛 banner 레이아웃의 잔재 전역이었음. 함수 내 `local bannerH = 0` 으로 대체해 산술이 항상 성공하도록 수정 (추후 banner 부활 시 그 자리에 높이 계산을 넣을 수 있도록 주석 명시).

## 1.2.1
- **Fixed**: Lock button tooltip used locale table `L` before it was defined (`L` was nil → error on mouseover). Moved `local L = { … }` / `GetLocale()` block to the top of the file (before `createLockButton`).
- **수정**: 잠금 버튼 툴팁이 로케일 테이블 `L`보다 먼저 정의된 함수에서 `L`을 참조해 마우스 오버 시 에러가 났음. `L` 초기화를 파일 상단(`createLockButton` 앞)으로 이동.

## 1.2.0
- **UI redesign**: Window now uses the same flat dark style as Loot-Roll (flat background, subtle 1px border, flat-styled buttons).
- **Close button**: Added a close button (X) at the top-right corner of the list window.
- **Lock button**: Added a lock/unlock button at the top-left corner. When locked, the window cannot be dragged.
- **UI 디자인 변경**: Loot-Roll과 동일한 플랫 다크 스타일로 변경 (플랫 배경, 1px 테두리, 플랫 버튼).
- **닫기 버튼**: 목록 창 우상단에 닫기(X) 버튼 추가.
- **잠금 버튼**: 좌상단에 자물쇠 아이콘 추가. 잠금 시 드래그 이동 불가.

## 1.1.11
- Removed player hyperlinks (`|Hplayer:…|h[name]|h`) from `SendChatMessage` entirely — Anniversary client rejects them with "Invalid escape code in chat message". Names are now sent as plain text only.
- 채팅 알림에서 플레이어 하이퍼링크(`|Hplayer:…|h`) 완전 제거: Anniversary 클라이언트에서 "Invalid escape code" 에러 발생하던 문제 수정. 이름은 일반 텍스트로만 전송.

## 1.1.9
- Chat announce again uses **player hyperlinks** `|Hplayer:…|h[name]|h` by default so party/raid members usually see **class-colored names in default chat** without needing a chat addon. Not `|cff` (which broke some clients). Toggle: `/seq links on|off` or `/seq links`. Saved as `announcePlayerLinks` in `SequenceHelperDB`.
- 채팅 알림 기본값을 **플레이어 링크**로 복구: 상대가 채팅 애드온 없이도 기본 UI에서 이름이 직업색으로 나오는 경우가 많음(`|cff` 는 사용 안 함). `/seq links on|off`·`/seq links` 로 끄거나 켤 수 있음.

## 1.1.10
- Reverted forced class-color fallback in list rendering: removed addon-defined `CLASS_COLOR_FALLBACK`; now uses `RAID_CLASS_COLORS` only and falls back to white when unavailable.
- 목록 표시에서 강제 직업색 보정(`CLASS_COLOR_FALLBACK`)을 제거해 원복: 이제 `RAID_CLASS_COLORS`만 사용하고 없으면 흰색으로 표시.

## 1.1.8
- Chat announce no longer embeds `|cff…|r` in `SendChatMessage` (some clients showed an empty line or no visible text while the addon still printed “sent” success). List panel class colors unchanged.
- 채팅 알림에서 `|cff` 색상 코드 제거: 일부 클라이언트에서 내용 없이 전송된 것처럼 보이던 문제 수정. 목록 창 직업색은 그대로.

## 1.1.7
- Class colors for list + chat announce now use Blizzard `RAID_CLASS_COLORS` when present, else a built-in `CLASS_COLOR_FALLBACK` table (addon-defined RGB). Chat announce embeds `|cff…|r` so recipients see those colors without relying on each player’s “class colors in names” UI option.
- 목록·채팅 알림 직업색: `RAID_CLASS_COLORS` 우선, 없으면 애드온 내 `CLASS_COLOR_FALLBACK` 고정값. 채팅은 `|cff` 코드로 보내 상대 클라이언트의 이름 직업색 설정과 무관하게 표시.

## 1.1.6
- Displayed sequence numbers now start at **13** (first member = 13, then 14, …) for overlays, list panel, and chat announce. Change `SEQUENCE_NUMBER_START` in `SequenceHelper.lua` to adjust.
- 표시 순번이 **13**부터 시작하도록 변경(오버레이·목록·채팅 알림 동일). 숫자만 바꾸려면 `SequenceHelper.lua`의 `SEQUENCE_NUMBER_START` 를 수정하면 됩니다.

## 1.1.5
- Fixed chat text corruption/error by removing player hyperlink payload in announce; now sends safe plain text names with ASCII separator (` / `).
- 채팅 알림에서 발생하던 깨짐/에러를 수정: 플레이어 링크 전송을 제거하고 일반 텍스트 이름 + ASCII 구분자(` / `)로 전송.

## 1.1.4
- Chat announce now sends player hyperlinks (`|Hplayer:...|h[name]|h`) per member so non-addon party members can still see class-colored names when their chat settings support it.
- 채팅 알림을 플레이어 링크(`|Hplayer:...|h[name]|h`) 기반으로 전송하도록 변경하여, 애드온이 없는 파티원도(채팅 설정 허용 시) 직업색 이름을 볼 수 있게 개선.

## 1.1.3
- Character names now use class colors in the SequenceHelper list panel (`RAID_CLASS_COLORS` fallback to white).
- SequenceHelper 목록 창에서 캐릭터 이름을 직업 색상으로 표시하도록 변경(직업 정보 없으면 흰색).

## 1.1.2
- Fixed chat announce doing nothing: WoW treats `|` in `SendChatMessage` as escape for colors/links. Separators changed to middle dot `·`; names stripped of `|{ }`; long lists split into multiple lines under ~230 chars; errors surfaced via `pcall`.
- 채팅 알림 무반응 수정: 메시지에 포함된 `|` 가 WoW 채팅 제어 문자로 처리되던 문제. 구분자 `·` 로 변경, 이름 정제, 긴 목록 분할 전송, `pcall` 로 오류 표시.

## 1.1.1
- CurseForge listing art: forced **exactly 400×400 px, 1:1** (`Art/SequenceHelper-CurseForge-400.png` — center-crop from source, then resize).
- 커스포지 등록용 그림: **정확히 400×400 픽셀, 1:1 비율**로 재출력(중앙 정사각형 크롭 후 리사이즈).

## 1.1.0
- Minimap button: left-click toggles the list/settings panel; right-click toggles addon on/off (overlays & announce respect enabled state).
- Textures: `Textures/MinimapIcon.png` (minimap), `Art/SequenceHelper-CurseForge-400.png` (400×400 for CurseForge listing).
- README expanded; this CHANGELOG added; version policy noted.
- 미니맵 버튼: 좌클릭 목록/설정 창 토글, 우클릭 사용함·사용안함.
- 아이콘: 미니맵용·커스포지 400×400용 에셋 추가, README/CHANGELOG/버전 정책 반영.

## 1.0.0
- Initial release: party/raid order list, frame number badges, `/seq` announce, migration from `PSequenceHelperDB`.
- 최초 릴리스: 순서 목록, 프레임 번호, 채팅 알림, 구 PSequenceHelper 저장 이전.