{"id":4584,"date":"2026-02-14T22:06:04","date_gmt":"2026-02-15T03:06:04","guid":{"rendered":"https:\/\/smartdsp.pro\/?page_id=4584"},"modified":"2026-10-28T17:19:07","modified_gmt":"2026-10-28T22:19:07","slug":"audio-metadata-editor","status":"publish","type":"page","link":"https:\/\/smartdsp.pro\/fr\/audio-metadata-editor\/","title":{"rendered":"\u00c9diteur de m\u00e9tadonn\u00e9es audio"},"content":{"rendered":"<p>[et_pb_section fb_built=&#8221;1&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; background_color=&#8221;#000000&#8243; background_image=&#8221;https:\/\/smartdsp.pro\/wp-content\/uploads\/2022\/10\/streamer-79.png&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_code _builder_version=&#8221;4.27.9&#8243; _module_preset=&#8221;default&#8221; hover_enabled=&#8221;0&#8243; global_colors_info=&#8221;{}&#8221; sticky_enabled=&#8221;0&#8243;]<!-- [et_pb_line_break_holder] --><\/p>\n<style><!-- [et_pb_line_break_holder] -->html.mde-lock, html.mde-lock body { overflow: hidden !important; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde {<!-- [et_pb_line_break_holder] -->  --bg-primary: #0f0f0f;<!-- [et_pb_line_break_holder] -->  --bg-secondary: #1a1a1a;<!-- [et_pb_line_break_holder] -->  --bg-tertiary: #242424;<!-- [et_pb_line_break_holder] -->  --bg-hover: #2a2a2a;<!-- [et_pb_line_break_holder] -->  --border-color: #333;<!-- [et_pb_line_break_holder] -->  --border-strong: #454545;<!-- [et_pb_line_break_holder] -->  --text-primary: #e4e4e4;<!-- [et_pb_line_break_holder] -->  --text-secondary: #a0a0a0;<!-- [et_pb_line_break_holder] -->  --text-dim: #6f6f6f;<!-- [et_pb_line_break_holder] -->  --accent: #f3be29;<!-- [et_pb_line_break_holder] -->  --accent-hover: #f99c06;<!-- [et_pb_line_break_holder] -->  --accent2: #cd3ba7;<!-- [et_pb_line_break_holder] -->  --success: #22c55e;<!-- [et_pb_line_break_holder] -->  --danger: #ef4444;<!-- [et_pb_line_break_holder] -->  --warning: #f59e0b;<!-- [et_pb_line_break_holder] -->  --mde-top: 200px;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  position: relative;<!-- [et_pb_line_break_holder] -->  color: var(--text-primary);<!-- [et_pb_line_break_holder] -->  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;<!-- [et_pb_line_break_holder] -->  font-size: 15px;<!-- [et_pb_line_break_holder] -->  line-height: 1.5;<!-- [et_pb_line_break_holder] -->  text-align: left;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde *, .mde *::before, .mde *::after { box-sizing: border-box; }<!-- [et_pb_line_break_holder] -->.mde button, .mde input, .mde textarea { font-family: inherit; }<!-- [et_pb_line_break_holder] -->.mde [hidden] { display: none !important; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Hero \/ drop zone (only when no files are loaded) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .hero { text-align: center; margin-bottom: 28px; }<!-- [et_pb_line_break_holder] -->.mde .hero h1 {<!-- [et_pb_line_break_holder] -->  margin: 0 0 8px; padding: 0; font-size: 2.3rem; font-weight: 700; line-height: 1.2;<!-- [et_pb_line_break_holder] -->  background: linear-gradient(135deg, var(--accent), var(--accent2));<!-- [et_pb_line_break_holder] -->  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .hero .subtitle { margin: 0; color: #fff; font-size: 1.1rem; font-weight: 700; }<!-- [et_pb_line_break_holder] -->.mde .features { display: flex; justify-content: center; gap: 8px 24px; flex-wrap: wrap; margin: 18px 0 0; color: #10b981; font-weight: 700; }<!-- [et_pb_line_break_holder] -->.mde .features span::before { content: \"\u2713 \"; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .drop-zone {<!-- [et_pb_line_break_holder] -->  background: var(--bg-secondary); border: 2px dashed var(--border-color); border-radius: 14px;<!-- [et_pb_line_break_holder] -->  padding: 56px 20px; text-align: center; cursor: pointer; transition: all .25s ease;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .drop-zone:hover, .mde.dragging .drop-zone { border-color: var(--accent); background: var(--bg-tertiary); }<!-- [et_pb_line_break_holder] -->.mde .dz-icon { font-size: 3rem; opacity: .5; margin-bottom: 14px; }<!-- [et_pb_line_break_holder] -->.mde .dz-text { font-size: 1.2rem; margin-bottom: 6px; }<!-- [et_pb_line_break_holder] -->.mde .dz-sub { color: var(--text-secondary); font-size: .9rem; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde.has-files .hero, .mde.has-files .drop-zone { display: none; }<!-- [et_pb_line_break_holder] -->.mde:not(.has-files) .app { display: none; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Buttons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .btn {<!-- [et_pb_line_break_holder] -->  display: inline-flex; align-items: center; justify-content: center; gap: 7px;<!-- [et_pb_line_break_holder] -->  margin: 0; padding: 9px 16px; border-radius: 8px; border: 1px solid transparent;<!-- [et_pb_line_break_holder] -->  font-size: .88rem; font-weight: 600; line-height: 1.2; cursor: pointer; white-space: nowrap;<!-- [et_pb_line_break_holder] -->  transition: all .18s; text-transform: none; letter-spacing: 0;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .btn:disabled { opacity: .4; cursor: not-allowed; transform: none !important; }<!-- [et_pb_line_break_holder] -->.mde .btn-primary { background: var(--accent); color: #0f0f0f; }<!-- [et_pb_line_break_holder] -->.mde .btn-primary:hover:not(:disabled) { background: var(--accent-hover); }<!-- [et_pb_line_break_holder] -->.mde .btn-success { background: var(--success); color: #fff; }<!-- [et_pb_line_break_holder] -->.mde .btn-success:hover:not(:disabled) { background: #16a34a; }<!-- [et_pb_line_break_holder] -->.mde .btn-ghost { background: var(--bg-secondary); color: var(--text-primary); border-color: var(--border-color); }<!-- [et_pb_line_break_holder] -->.mde .btn-ghost:hover:not(:disabled) { background: var(--bg-hover); border-color: var(--border-strong); }<!-- [et_pb_line_break_holder] -->.mde .btn-sm { padding: 6px 11px; font-size: .8rem; }<!-- [et_pb_line_break_holder] -->.mde .count {<!-- [et_pb_line_break_holder] -->  min-width: 20px; padding: 1px 7px; border-radius: 99px; background: rgba(0,0,0,.28);<!-- [et_pb_line_break_holder] -->  font-size: .75rem; font-weight: 800; text-align: center;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .count:empty, .mde .count.zero { display: none; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px 14px; flex-wrap: wrap; margin-bottom: 12px; }<!-- [et_pb_line_break_holder] -->.mde .tb-group { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }<!-- [et_pb_line_break_holder] -->.mde .seg { display: inline-flex; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 9px; padding: 3px; }<!-- [et_pb_line_break_holder] -->.mde .seg button {<!-- [et_pb_line_break_holder] -->  margin: 0; border: 0; background: none; color: var(--text-secondary); padding: 6px 13px;<!-- [et_pb_line_break_holder] -->  border-radius: 6px; font-size: .84rem; font-weight: 600; cursor: pointer; transition: all .15s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .seg button:hover { color: var(--text-primary); }<!-- [et_pb_line_break_holder] -->.mde .seg button.on { background: var(--bg-hover); color: var(--accent); box-shadow: inset 0 0 0 1px rgba(243,190,41,.35); }<!-- [et_pb_line_break_holder] -->.mde .search { position: relative; }<!-- [et_pb_line_break_holder] -->.mde .search input {<!-- [et_pb_line_break_holder] -->  width: 220px; max-width: 100%; margin: 0; padding: 8px 32px 8px 12px; height: auto;<!-- [et_pb_line_break_holder] -->  background: var(--bg-secondary); color: var(--text-primary); border: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  border-radius: 8px; font-size: .86rem; box-shadow: none;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .search input:focus { outline: none; border-color: var(--accent); }<!-- [et_pb_line_break_holder] -->.mde .search span { position: absolute; right: 10px; top: 50%; transform: translateY(-50%); opacity: .5; pointer-events: none; font-size: .8rem; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Workspace (fixed height \u2192 controls never scroll away) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .workspace {<!-- [et_pb_line_break_holder] -->  display: grid; grid-template-columns: 290px minmax(0, 1fr); gap: 14px;<!-- [et_pb_line_break_holder] -->  height: calc(100vh - var(--mde-top)); min-height: 460px;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .workspace.view-table { grid-template-columns: minmax(0, 1fr); }<!-- [et_pb_line_break_holder] -->.mde .workspace.view-table .sidebar { display: none; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .sidebar {<!-- [et_pb_line_break_holder] -->  display: flex; flex-direction: column; min-height: 0; min-width: 0;<!-- [et_pb_line_break_holder] -->  background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 12px; overflow: hidden;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .sb-head {<!-- [et_pb_line_break_holder] -->  display: flex; align-items: center; justify-content: space-between; padding: 11px 14px;<!-- [et_pb_line_break_holder] -->  background: var(--bg-tertiary); border-bottom: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  font-size: .72rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--text-secondary);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .file-list { position: relative; flex: 1; min-height: 0; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 6px; }<!-- [et_pb_line_break_holder] -->.mde .file-item {<!-- [et_pb_line_break_holder] -->  position: relative; padding: 9px 10px 9px 12px; border: 1px solid transparent; border-radius: 9px;<!-- [et_pb_line_break_holder] -->  background: var(--bg-primary); cursor: pointer; transition: all .15s; outline: none;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .file-item:hover { background: var(--bg-hover); }<!-- [et_pb_line_break_holder] -->.mde .file-item:focus-visible { border-color: var(--accent); }<!-- [et_pb_line_break_holder] -->.mde .file-item.active { border-color: rgba(243,190,41,.55); background: rgba(243,190,41,.07); }<!-- [et_pb_line_break_holder] -->.mde .fi-row { display: flex; align-items: center; gap: 8px; min-width: 0; }<!-- [et_pb_line_break_holder] -->.mde .fi-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; font-size: .88rem; }<!-- [et_pb_line_break_holder] -->.mde .file-item.active .fi-name { color: var(--accent); }<!-- [et_pb_line_break_holder] -->.mde .fi-sub { margin-top: 3px; font-size: .74rem; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }<!-- [et_pb_line_break_holder] -->.mde .fi-dot { display: none; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex-shrink: 0; box-shadow: 0 0 0 3px rgba(243,190,41,.2); }<!-- [et_pb_line_break_holder] -->.mde .file-item.dirty .fi-dot { display: block; }<!-- [et_pb_line_break_holder] -->.mde .fi-rm {<!-- [et_pb_line_break_holder] -->  margin: 0; padding: 2px 6px; border: 0; background: none; color: var(--text-dim); cursor: pointer;<!-- [et_pb_line_break_holder] -->  border-radius: 5px; font-size: .8rem; opacity: 0; transition: all .15s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .file-item:hover .fi-rm, .mde .file-item:focus-within .fi-rm { opacity: 1; }<!-- [et_pb_line_break_holder] -->.mde .fi-rm:hover { color: var(--danger); background: rgba(239,68,68,.12); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .badge {<!-- [et_pb_line_break_holder] -->  display: inline-block; flex-shrink: 0; padding: 2px 7px; border-radius: 4px;<!-- [et_pb_line_break_holder] -->  font-size: .66rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;<!-- [et_pb_line_break_holder] -->  background: var(--bg-tertiary); color: var(--text-secondary);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .badge-mp3  { background: rgba(236,72,153,.2);  color: #ec4899; }<!-- [et_pb_line_break_holder] -->.mde .badge-wav  { background: rgba(34,197,94,.2);   color: #22c55e; }<!-- [et_pb_line_break_holder] -->.mde .badge-aiff { background: rgba(59,130,246,.2);  color: #3b82f6; }<!-- [et_pb_line_break_holder] -->.mde .badge-ogg  { background: rgba(245,158,11,.2);  color: #f59e0b; }<!-- [et_pb_line_break_holder] -->.mde .badge-flac { background: rgba(139,92,246,.2);  color: #8b5cf6; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Main panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .main {<!-- [et_pb_line_break_holder] -->  min-width: 0; min-height: 0; overflow-y: auto; overflow-x: hidden;<!-- [et_pb_line_break_holder] -->  background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 12px;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .workspace.view-table .main { overflow: hidden; background: none; border: 0; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .ed-head {<!-- [et_pb_line_break_holder] -->  position: sticky; top: 0; z-index: 5; padding: 14px 18px 12px;<!-- [et_pb_line_break_holder] -->  background: rgba(26,26,26,.96); backdrop-filter: blur(8px); border-bottom: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .ed-top { display: flex; align-items: center; justify-content: space-between; gap: 10px 16px; flex-wrap: wrap; }<!-- [et_pb_line_break_holder] -->.mde .ed-title { display: flex; align-items: center; gap: 10px; min-width: 0; flex: 1 1 260px; }<!-- [et_pb_line_break_holder] -->.mde .ed-title h2 { margin: 0; padding: 0; font-size: 1.1rem; font-weight: 700; color: var(--accent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: 0; text-transform: none; }<!-- [et_pb_line_break_holder] -->.mde .ed-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }<!-- [et_pb_line_break_holder] -->.mde .ed-nav { display: inline-flex; align-items: center; gap: 4px; margin-right: 4px; color: var(--text-secondary); font-size: .8rem; }<!-- [et_pb_line_break_holder] -->.mde .nav-btn {<!-- [et_pb_line_break_holder] -->  margin: 0; width: 30px; height: 30px; padding: 0; border-radius: 7px; border: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  background: var(--bg-primary); color: var(--text-primary); cursor: pointer; font-size: .75rem; transition: all .15s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .nav-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }<!-- [et_pb_line_break_holder] -->.mde .nav-btn:disabled { opacity: .35; cursor: not-allowed; }<!-- [et_pb_line_break_holder] -->.mde .ed-meta { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: 9px; }<!-- [et_pb_line_break_holder] -->.mde .tech-pill {<!-- [et_pb_line_break_holder] -->  display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 5px;<!-- [et_pb_line_break_holder] -->  background: var(--bg-primary); border: 1px solid var(--border-color); font-size: .74rem;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .tech-pill i { font-style: normal; color: var(--text-dim); font-size: .62rem; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }<!-- [et_pb_line_break_holder] -->.mde .tech-pill b { font-weight: 600; }<!-- [et_pb_line_break_holder] -->.mde .ed-chg { margin-left: auto; font-size: .78rem; font-weight: 700; color: var(--accent); display: none; }<!-- [et_pb_line_break_holder] -->.mde .ed-chg.show { display: inline; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .ed-body { padding: 6px 18px 22px; }<!-- [et_pb_line_break_holder] -->.mde .ro-banner {<!-- [et_pb_line_break_holder] -->  margin: 14px 0 0; padding: 10px 14px; border-radius: 9px; font-size: .86rem;<!-- [et_pb_line_break_holder] -->  background: rgba(245,158,11,.1); border: 1px solid rgba(245,158,11,.3); color: #fbbf24;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .group { margin-top: 20px; }<!-- [et_pb_line_break_holder] -->.mde .group h3 {<!-- [et_pb_line_break_holder] -->  display: flex; align-items: center; gap: 8px; margin: 0 0 12px; padding: 0 0 8px; border-bottom: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  font-size: .76rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-secondary);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 14px 16px; }<!-- [et_pb_line_break_holder] -->.mde .field { min-width: 0; }<!-- [et_pb_line_break_holder] -->.mde .field.wide { grid-column: 1 \/ -1; }<!-- [et_pb_line_break_holder] -->.mde .fl-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 5px; min-height: 22px; }<!-- [et_pb_line_break_holder] -->.mde .fl-head label { margin: 0; padding: 0; font-size: .78rem; font-weight: 600; color: var(--text-secondary); cursor: pointer; }<!-- [et_pb_line_break_holder] -->.mde .field.modified .fl-head label { color: var(--accent); }<!-- [et_pb_line_break_holder] -->.mde .field.modified .fl-head label::after { content: \" \u25cf\"; font-size: .6rem; vertical-align: middle; }<!-- [et_pb_line_break_holder] -->.mde .fl-tools { display: inline-flex; align-items: center; gap: 2px; }<!-- [et_pb_line_break_holder] -->.mde .fl-count { font-size: .7rem; color: var(--text-dim); font-variant-numeric: tabular-nums; margin-right: 4px; }<!-- [et_pb_line_break_holder] -->.mde .fl-count.over { color: var(--danger); font-weight: 700; }<!-- [et_pb_line_break_holder] -->.mde .fl-btn {<!-- [et_pb_line_break_holder] -->  margin: 0; padding: 1px 7px; border: 1px solid transparent; border-radius: 5px; background: none;<!-- [et_pb_line_break_holder] -->  color: var(--text-secondary); font-size: .74rem; font-weight: 600; cursor: pointer; opacity: 0; transition: all .15s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .field:hover .fl-btn, .mde .field:focus-within .fl-btn { opacity: 1; }<!-- [et_pb_line_break_holder] -->.mde .fl-btn:hover { background: var(--bg-hover); color: var(--text-primary); border-color: var(--border-color); }<!-- [et_pb_line_break_holder] -->.mde .field:not(.modified) .fl-btn[data-action=\"revert\"] { display: none; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .fl-input, .mde .cell {<!-- [et_pb_line_break_holder] -->  display: block; width: 100%; height: auto; margin: 0; padding: 10px 12px;<!-- [et_pb_line_break_holder] -->  background: var(--bg-primary); color: var(--text-primary); border: 1px solid #3c3c3c; border-radius: 8px;<!-- [et_pb_line_break_holder] -->  font-size: .92rem; line-height: 1.4; box-shadow: none; -webkit-appearance: none; appearance: none;<!-- [et_pb_line_break_holder] -->  transition: border-color .15s, box-shadow .15s, background .15s;<!-- [et_pb_line_break_holder] -->  color: #fff !important;<!-- [et_pb_line_break_holder] -->-webkit-text-fill-color: #fff !important;<!-- [et_pb_line_break_holder] -->caret-color: var(--accent);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .fl-input::placeholder, .mde .cell::placeholder {<!-- [et_pb_line_break_holder] -->  color: #565656 !important;<!-- [et_pb_line_break_holder] -->  -webkit-text-fill-color: #565656 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .fl-input:disabled, .mde .cell:disabled {<!-- [et_pb_line_break_holder] -->  color: #a0a0a0 !important;<!-- [et_pb_line_break_holder] -->  -webkit-text-fill-color: #a0a0a0 !important;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde textarea.fl-input { resize: vertical; min-height: 84px; }<!-- [et_pb_line_break_holder] -->.mde .fl-input:hover:not(:disabled), .mde .cell:hover:not(:disabled) { border-color: #5a5a5a; }<!-- [et_pb_line_break_holder] -->.mde .fl-input:focus, .mde .cell:focus {<!-- [et_pb_line_break_holder] -->  outline: none; border-color: var(--accent); background: #141414; box-shadow: 0 0 0 3px rgba(243,190,41,.18);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .fl-input::placeholder, .mde .cell::placeholder { color: #565656; }<!-- [et_pb_line_break_holder] -->.mde .field.modified .fl-input, .mde .cell.modified { border-color: rgba(243,190,41,.7); background: rgba(243,190,41,.06); }<!-- [et_pb_line_break_holder] -->.mde .fl-input:disabled, .mde .cell:disabled { opacity: .5; cursor: not-allowed; border-style: dashed; }<!-- [et_pb_line_break_holder] -->.mde .empty { padding: 50px 20px; text-align: center; color: var(--text-secondary); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Table view \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .tbl-wrap { height: 100%; overflow: auto; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 12px; }<!-- [et_pb_line_break_holder] -->.mde .tbl { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; margin: 0; font-size: .88rem; }<!-- [et_pb_line_break_holder] -->.mde .tbl th {<!-- [et_pb_line_break_holder] -->  position: sticky; top: 0; z-index: 2; padding: 12px 10px; text-align: left; white-space: nowrap;<!-- [et_pb_line_break_holder] -->  background: var(--bg-tertiary); color: var(--text-secondary); border: 0; border-bottom: 2px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .tbl td { padding: 6px; min-width: 190px; border: 0; border-bottom: 1px solid var(--border-color); background: transparent; vertical-align: middle; }<!-- [et_pb_line_break_holder] -->.mde .tbl tr:hover td { background: rgba(255,255,255,.02); }<!-- [et_pb_line_break_holder] -->.mde .tbl tr.active td { background: rgba(243,190,41,.05); }<!-- [et_pb_line_break_holder] -->.mde .tbl td.na { color: var(--text-dim); text-align: center; min-width: 120px; }<!-- [et_pb_line_break_holder] -->.mde .tbl .sticky-col { position: sticky; left: 0; z-index: 1; min-width: 270px; max-width: 270px; background: var(--bg-secondary); border-right: 1px solid var(--border-color); }<!-- [et_pb_line_break_holder] -->.mde .tbl th.sticky-col { z-index: 3; background: var(--bg-tertiary); }<!-- [et_pb_line_break_holder] -->.mde .tbl tr:hover td.sticky-col { background: var(--bg-hover); }<!-- [et_pb_line_break_holder] -->.mde .fc { display: flex; align-items: center; gap: 8px; padding: 2px 4px; }<!-- [et_pb_line_break_holder] -->.mde .fc-name {<!-- [et_pb_line_break_holder] -->  flex: 1; min-width: 0; margin: 0; padding: 0; border: 0; background: none; text-align: left; cursor: pointer;<!-- [et_pb_line_break_holder] -->  color: var(--accent); font-weight: 600; font-size: .86rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .fc-name:hover { text-decoration: underline; }<!-- [et_pb_line_break_holder] -->.mde .fc-sub { padding: 0 4px; font-size: .72rem; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }<!-- [et_pb_line_break_holder] -->.mde .ic {<!-- [et_pb_line_break_holder] -->  margin: 0; padding: 3px 6px; border: 0; background: none; border-radius: 5px; cursor: pointer; font-size: .95rem; transition: all .15s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .ic:hover { background: var(--bg-hover); }<!-- [et_pb_line_break_holder] -->.mde .ic:disabled { opacity: .3; cursor: not-allowed; }<!-- [et_pb_line_break_holder] -->.mde .tr-dirty .fc-name::after { content: \" \u25cf\"; color: var(--accent); font-size: .6rem; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Footer hints \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .hints { margin-top: 8px; font-size: .74rem; color: var(--text-dim); display: flex; flex-wrap: wrap; gap: 4px 16px; }<!-- [et_pb_line_break_holder] -->.mde kbd {<!-- [et_pb_line_break_holder] -->  padding: 1px 6px; border-radius: 4px; background: var(--bg-tertiary); border: 1px solid var(--border-color);<!-- [et_pb_line_break_holder] -->  font-family: inherit; font-size: .7rem; color: var(--text-secondary);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Context menu \/ modal \/ status \/ drop overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde .ctx {<!-- [et_pb_line_break_holder] -->  position: fixed; z-index: 100002; display: none; min-width: 190px; padding: 6px;<!-- [et_pb_line_break_holder] -->  background: var(--bg-tertiary); border: 1px solid var(--border-color); border-radius: 9px; box-shadow: 0 10px 40px rgba(0,0,0,.55);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .ctx.show { display: block; }<!-- [et_pb_line_break_holder] -->.mde .ctx div { padding: 9px 12px; border-radius: 5px; cursor: pointer; font-size: .86rem; }<!-- [et_pb_line_break_holder] -->.mde .ctx div:hover { background: var(--bg-hover); }<!-- [et_pb_line_break_holder] -->.mde .ctx hr { border: 0; height: 1px; background: var(--border-color); margin: 5px 0; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .modal-ov {<!-- [et_pb_line_break_holder] -->  position: fixed; inset: 0; z-index: 100001; display: none; align-items: center; justify-content: center; padding: 16px;<!-- [et_pb_line_break_holder] -->  background: rgba(0,0,0,.85); backdrop-filter: blur(4px);<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .modal-ov.show { display: flex; }<!-- [et_pb_line_break_holder] -->.mde .modal { width: 100%; max-width: 480px; max-height: 88vh; overflow: auto; padding: 24px; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 14px; box-shadow: 0 20px 60px rgba(0,0,0,.8); }<!-- [et_pb_line_break_holder] -->.mde .modal h3 { margin: 0 0 12px; padding: 0; font-size: 1.3rem; color: var(--text-primary); }<!-- [et_pb_line_break_holder] -->.mde .modal p { margin: 0 0 12px; color: var(--text-secondary); font-size: .9rem; }<!-- [et_pb_line_break_holder] -->.mde .modal ul { margin: 0 0 14px; padding: 0; list-style: none; max-height: 160px; overflow: auto; font-size: .84rem; }<!-- [et_pb_line_break_holder] -->.mde .modal li { padding: 4px 0; color: var(--accent); word-break: break-all; }<!-- [et_pb_line_break_holder] -->.mde .modal .note { font-size: .78rem; color: var(--text-dim); }<!-- [et_pb_line_break_holder] -->.mde .modal-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 18px; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .status {<!-- [et_pb_line_break_holder] -->  position: fixed; left: 50%; bottom: 24px; z-index: 100003; transform: translate(-50%, 20px); opacity: 0; pointer-events: none;<!-- [et_pb_line_break_holder] -->  max-width: calc(100vw - 32px); padding: 11px 20px; border-radius: 9px; background: var(--success); color: #fff;<!-- [et_pb_line_break_holder] -->  font-size: .88rem; font-weight: 600; box-shadow: 0 10px 40px rgba(0,0,0,.4); transition: all .25s;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde .status.show { opacity: 1; transform: translate(-50%, 0); }<!-- [et_pb_line_break_holder] -->.mde .status.error { background: var(--danger); }<!-- [et_pb_line_break_holder] -->.mde .status.warning { background: var(--warning); color: #000; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->.mde .drop-ov {<!-- [et_pb_line_break_holder] -->  position: absolute; inset: 0; z-index: 50; display: none; align-items: center; justify-content: center;<!-- [et_pb_line_break_holder] -->  background: rgba(15,15,15,.85); border: 2px dashed var(--accent); border-radius: 14px;<!-- [et_pb_line_break_holder] -->  font-size: 1.2rem; font-weight: 700; color: var(--accent); pointer-events: none;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde.has-files.dragging .drop-ov { display: flex; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Fullscreen (whole app, not just the table) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->.mde.is-fs {<!-- [et_pb_line_break_holder] -->  position: fixed; inset: 0; z-index: 99999; display: flex; flex-direction: column;<!-- [et_pb_line_break_holder] -->  padding: 14px 18px; background: var(--bg-primary); overflow: hidden;<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->.mde.is-fs .app { flex: 1; display: flex; flex-direction: column; min-height: 0; }<!-- [et_pb_line_break_holder] -->.mde.is-fs .workspace { flex: 1; height: auto; min-height: 0; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->\/* \u2500\u2500 Mobile \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/<!-- [et_pb_line_break_holder] -->@media (max-width: 820px) {<!-- [et_pb_line_break_holder] -->  .mde { font-size: 14px; }<!-- [et_pb_line_break_holder] -->  .mde .hero h1 { font-size: 1.7rem; }<!-- [et_pb_line_break_holder] -->  .mde .drop-zone { padding: 40px 14px; }<!-- [et_pb_line_break_holder] -->  .mde .toolbar { flex-direction: column; align-items: stretch; }<!-- [et_pb_line_break_holder] -->  .mde .tb-group { justify-content: space-between; }<!-- [et_pb_line_break_holder] -->  .mde .tb-group.tb-right .btn { flex: 1 1 auto; }<!-- [et_pb_line_break_holder] -->  .mde .tb-group.tb-right .hide-sm { display: none; }<!-- [et_pb_line_break_holder] -->  .mde .tb-group.tb-right #saveAllBtn .hide-sm { display: inline; }<!-- [et_pb_line_break_holder] -->  .mde .search { flex: 1; }<!-- [et_pb_line_break_holder] -->  .mde .search input { width: 100%; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  .mde .workspace { display: block; height: auto; min-height: 0; }<!-- [et_pb_line_break_holder] -->  .mde .sidebar { margin-bottom: 12px; }<!-- [et_pb_line_break_holder] -->  .mde .file-list { flex-direction: row; overflow-x: auto; overflow-y: hidden; padding: 8px; }<!-- [et_pb_line_break_holder] -->  .mde .file-item { flex: 0 0 210px; }<!-- [et_pb_line_break_holder] -->  .mde .fi-rm { opacity: 1; }<!-- [et_pb_line_break_holder] -->  .mde .main { overflow: visible; }<!-- [et_pb_line_break_holder] -->  .mde .workspace.view-table .main { overflow: visible; }<!-- [et_pb_line_break_holder] -->  .mde .tbl-wrap { height: 70vh; }<!-- [et_pb_line_break_holder] -->  .mde .ed-head { position: static; padding: 12px; }<!-- [et_pb_line_break_holder] -->  .mde .ed-body { padding: 4px 12px 18px; }<!-- [et_pb_line_break_holder] -->  .mde .fields { grid-template-columns: 1fr; }<!-- [et_pb_line_break_holder] -->  .mde .fl-btn { opacity: 1; }<!-- [et_pb_line_break_holder] -->  .mde .ed-actions { width: 100%; }<!-- [et_pb_line_break_holder] -->  .mde .ed-actions .btn { flex: 1; }<!-- [et_pb_line_break_holder] -->  .mde .hints { display: none; }<!-- [et_pb_line_break_holder] -->  .mde .modal-actions .btn { flex: 1; }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  .mde.is-fs { padding: 10px; }<!-- [et_pb_line_break_holder] -->  .mde.is-fs .workspace { display: flex; flex-direction: column; }<!-- [et_pb_line_break_holder] -->  .mde.is-fs .sidebar { flex: 0 0 auto; }<!-- [et_pb_line_break_holder] -->  .mde.is-fs .main { flex: 1; min-height: 0; overflow: auto; }<!-- [et_pb_line_break_holder] -->  .mde.is-fs .workspace.view-table .main { overflow: hidden; }<!-- [et_pb_line_break_holder] -->  .mde.is-fs .tbl-wrap { height: 100%; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] -->@media (hover: none) {<!-- [et_pb_line_break_holder] -->  .mde .fl-btn, .mde .fi-rm { opacity: 1; }<!-- [et_pb_line_break_holder] -->}<!-- [et_pb_line_break_holder] --><\/style>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><\/p>\n<div class=\"mde\" id=\"mde\"><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"hero\"><!-- [et_pb_line_break_holder] -->    <\/p>\n<h1>Audio Metadata Editor<\/h1>\n<p><!-- [et_pb_line_break_holder] -->    <pee class=\"subtitle\">Professional metadata viewer and editor for audio files<\/pee><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"features\"><!-- [et_pb_line_break_holder] -->      <span>100% Local Processing<\/span><span>Completely Free<\/span><span>No Account Required<\/span><span>No Ads<\/span><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"drop-zone\" id=\"dropZone\"><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"dz-icon\">\ud83c\udfb5<\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"dz-text\">Drag &#038; drop audio files here<\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"dz-sub\">or click to browse \u2022 Reads MP3, WAV, AIFF, OGG, FLAC (Writes MP3\/WAV)<\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] -->  <input type=\"file\" id=\"fileInput\" multiple accept=\"audio\/*\" hidden><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"app\"><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"toolbar\"><!-- [et_pb_line_break_holder] -->      <\/p>\n<div class=\"tb-group\"><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"seg\" id=\"viewSeg\"><!-- [et_pb_line_break_holder] -->          <button type=\"button\" data-view=\"editor\" class=\"on\">\u270f\ufe0f Editor<\/button><!-- [et_pb_line_break_holder] -->          <button type=\"button\" data-view=\"table\">\u25a6 Table<\/button><!-- [et_pb_line_break_holder] -->        <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"search\"><!-- [et_pb_line_break_holder] -->          <input type=\"text\" id=\"searchInput\" placeholder=\"Filter fields\u2026\" autocomplete=\"off\"><!-- [et_pb_line_break_holder] -->          <span>\ud83d\udd0d<\/span><!-- [et_pb_line_break_holder] -->        <\/div>\n<p><!-- [et_pb_line_break_holder] -->      <\/div>\n<p><!-- [et_pb_line_break_holder] -->      <\/p>\n<div class=\"tb-group tb-right\"><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-ghost btn-sm\" id=\"addFilesBtn\">\u2795 <span class=\"hide-sm\">Add files<\/span><\/button><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-ghost btn-sm\" id=\"resetBtn\">\ud83d\udd04 <span class=\"hide-sm\">Reset<\/span><\/button><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-ghost btn-sm\" id=\"fullscreenBtn\">\u26f6 <span class=\"hide-sm\">Fullscreen<\/span><\/button><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-success\" id=\"saveAllBtn\" disabled>\ud83d\udcbe <span class=\"hide-sm\">Save all changes<\/span> <span class=\"count zero\" id=\"modCount\"><\/span><\/button><!-- [et_pb_line_break_holder] -->      <\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"workspace\" id=\"workspace\"><!-- [et_pb_line_break_holder] -->      <\/p>\n<aside class=\"sidebar\"><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"sb-head\"><span>Files<\/span><span id=\"fileCount\"><\/span><\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"file-list\" id=\"fileList\"><\/div>\n<p><!-- [et_pb_line_break_holder] -->      <\/aside>\n<p><!-- [et_pb_line_break_holder] -->      <main class=\"main\" id=\"main\"><\/main><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"hints\"><!-- [et_pb_line_break_holder] -->      <span><kbd>Alt<\/kbd>+<kbd>\u2191<\/kbd>\/<kbd>\u2193<\/kbd> previous \/ next file<\/span><!-- [et_pb_line_break_holder] -->      <span><kbd>Ctrl<\/kbd>\/<kbd>\u2318<\/kbd>+<kbd>S<\/kbd> save current file<\/span><!-- [et_pb_line_break_holder] -->      <span><kbd>F<\/kbd> fullscreen<\/span><!-- [et_pb_line_break_holder] -->      <span>Right-click a field for more actions<\/span><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"drop-ov\">Drop audio files to add them<\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"ctx\" id=\"ctxMenu\"><!-- [et_pb_line_break_holder] -->    <\/p>\n<div data-ctx=\"revert\">\u21ba Revert to original<\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/p>\n<div data-ctx=\"clear\">\ud83d\uddd1\ufe0f Clear value<\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/p>\n<hr>\n<p><!-- [et_pb_line_break_holder] -->    <\/p>\n<div data-ctx=\"apply\">\u21c9 Copy to all files<\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"modal-ov\" id=\"saveModal\"><!-- [et_pb_line_break_holder] -->    <\/p>\n<div class=\"modal\"><!-- [et_pb_line_break_holder] -->      <\/p>\n<h3>Save file(s)<\/h3>\n<p><!-- [et_pb_line_break_holder] -->      <\/p>\n<div id=\"saveModalBody\"><\/div>\n<p><!-- [et_pb_line_break_holder] -->      <\/p>\n<div class=\"modal-actions\"><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-ghost\" id=\"cancelSaveBtn\">Cancel<\/button><!-- [et_pb_line_break_holder] -->        <button type=\"button\" class=\"btn btn-success\" id=\"confirmSaveBtn\">\ud83d\udcbe Save<\/button><!-- [et_pb_line_break_holder] -->      <\/div>\n<p><!-- [et_pb_line_break_holder] -->    <\/div>\n<p><!-- [et_pb_line_break_holder] -->  <\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  <\/p>\n<div class=\"status\" id=\"statusMessage\"><\/div>\n<p><!-- [et_pb_line_break_holder] --><\/div>\n<p><!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] --><script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jsmediatags\/3.9.5\/jsmediatags.min.js\"><\/script><!-- [et_pb_line_break_holder] --><script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/FileSaver.js\/2.0.5\/FileSaver.min.js\"><\/script><!-- [et_pb_line_break_holder] --><script><!-- [et_pb_line_break_holder] -->(function () {<!-- [et_pb_line_break_holder] -->  \/\/ \u2500\u2500 Field layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->  const FIELD_GROUPS = [<!-- [et_pb_line_break_holder] -->    { id: 'main',   icon: '\ud83c\udfb5', title: 'Track info',           fields: ['Title','Artist','Album','Album Artist','Composer','Genre','Year','Track','BPM'] },<!-- [et_pb_line_break_holder] -->    { id: 'notes',  icon: '\ud83d\udcdd', title: 'Notes',                fields: ['Comment','Description','Subject'] },<!-- [et_pb_line_break_holder] -->    { id: 'rights', icon: '\u00a9',  title: 'Rights & identifiers', fields: ['Copyright','Publisher','ISRC\/Source Code','Software','Creation Date'] },<!-- [et_pb_line_break_holder] -->    { id: 'bwf',    icon: '\ud83d\udcfb', title: 'Broadcast WAV (BWF)',  fields: ['Originator','Originator Reference','Origination Date','Origination Time'] },<!-- [et_pb_line_break_holder] -->  ];<!-- [et_pb_line_break_holder] -->  const GROUP_FIELDS = new Set(FIELD_GROUPS.flatMap(g => g.fields));<!-- [et_pb_line_break_holder] -->  const FIELD_ORDER  = FIELD_GROUPS.flatMap(g => g.fields);<!-- [et_pb_line_break_holder] -->  const WIDE         = new Set(['Comment', 'Description']);<!-- [et_pb_line_break_holder] -->  const WAV_LIMITS   = { 'Description': 256, 'Originator': 32, 'Originator Reference': 32, 'Origination Date': 10, 'Origination Time': 8 };<!-- [et_pb_line_break_holder] -->  const PLACEHOLDERS = { 'Year': 'YYYY', 'Track': 'e.g. 3\/12', 'BPM': 'e.g. 128', 'Origination Date': 'YYYY-MM-DD', 'Origination Time': 'HH:MM:SS', 'Creation Date': 'YYYY-MM-DD', 'ISRC\/Source Code': 'CC-XXX-YY-NNNNN' };<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  const esc = s => String(s ?? '').replace(\/[&<>\"']\/g, c => ({ '&': '&', '<': '<', '>': '>', '\"': '\"', \"'\": '&#39;' }[c]));<!-- [et_pb_line_break_holder] -->  const byteLen = s => new TextEncoder().encode(s).length;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  class AudioMetadataEditor {<!-- [et_pb_line_break_holder] -->    constructor(root) {<!-- [et_pb_line_break_holder] -->      this.root = root;<!-- [et_pb_line_break_holder] -->      this.$ = s => root.querySelector(s);<!-- [et_pb_line_break_holder] -->      this.metas = [];<!-- [et_pb_line_break_holder] -->      this.activeId = null;<!-- [et_pb_line_break_holder] -->      this.view = 'editor';<!-- [et_pb_line_break_holder] -->      this.query = '';<!-- [et_pb_line_break_holder] -->      this.isFullscreen = false;<!-- [et_pb_line_break_holder] -->      this.pendingSave = null;<!-- [et_pb_line_break_holder] -->      this.ctx = null;<!-- [et_pb_line_break_holder] -->      this.statusTimer = null;<!-- [et_pb_line_break_holder] -->      this.uid = 0;<!-- [et_pb_line_break_holder] -->      this.dragDepth = 0;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      this.dropZone  = this.$('#dropZone');<!-- [et_pb_line_break_holder] -->      this.fileInput = this.$('#fileInput');<!-- [et_pb_line_break_holder] -->      this.workspace = this.$('#workspace');<!-- [et_pb_line_break_holder] -->      this.fileList  = this.$('#fileList');<!-- [et_pb_line_break_holder] -->      this.main      = this.$('#main');<!-- [et_pb_line_break_holder] -->      this.search    = this.$('#searchInput');<!-- [et_pb_line_break_holder] -->      this.saveModal = this.$('#saveModal');<!-- [et_pb_line_break_holder] -->      this.ctxMenu   = this.$('#ctxMenu');<!-- [et_pb_line_break_holder] -->      this.statusEl  = this.$('#statusMessage');<!-- [et_pb_line_break_holder] -->      this.bind();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Events<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    bind() {<!-- [et_pb_line_break_holder] -->      this.dropZone.addEventListener('click', () => this.fileInput.click());<!-- [et_pb_line_break_holder] -->      this.fileInput.addEventListener('change', e => { this.handleFiles(e.target.files); e.target.value = ''; });<!-- [et_pb_line_break_holder] -->      this.$('#addFilesBtn').addEventListener('click', () => this.fileInput.click());<!-- [et_pb_line_break_holder] -->      this.$('#resetBtn').addEventListener('click', () => this.reset());<!-- [et_pb_line_break_holder] -->      this.$('#fullscreenBtn').addEventListener('click', () => this.toggleFullscreen());<!-- [et_pb_line_break_holder] -->      this.$('#saveAllBtn').addEventListener('click', () => this.showSaveModal('all'));<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      this.$('#viewSeg').addEventListener('click', e => {<!-- [et_pb_line_break_holder] -->        const b = e.target.closest('[data-view]'); if (b) this.setView(b.dataset.view);<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->      this.search.addEventListener('input', () => { this.query = this.search.value.trim().toLowerCase(); this.renderMain(true); });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      \/\/ Sidebar<!-- [et_pb_line_break_holder] -->      this.fileList.addEventListener('click', e => {<!-- [et_pb_line_break_holder] -->        const item = e.target.closest('.file-item'); if (!item) return;<!-- [et_pb_line_break_holder] -->        if (e.target.closest('.fi-rm')) { e.stopPropagation(); this.removeFile(item.dataset.id); return; }<!-- [et_pb_line_break_holder] -->        this.select(item.dataset.id);<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->      this.fileList.addEventListener('keydown', e => {<!-- [et_pb_line_break_holder] -->        if (e.key !== 'Enter' && e.key !== ' ') return;<!-- [et_pb_line_break_holder] -->        const item = e.target.closest('.file-item'); if (!item) return;<!-- [et_pb_line_break_holder] -->        e.preventDefault(); this.select(item.dataset.id);<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      \/\/ Main panel (delegated)<!-- [et_pb_line_break_holder] -->      this.main.addEventListener('click', e => this.onMainClick(e));<!-- [et_pb_line_break_holder] -->      this.main.addEventListener('input', e => this.onInput(e));<!-- [et_pb_line_break_holder] -->      this.main.addEventListener('contextmenu', e => this.onContext(e));<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      \/\/ Context menu<!-- [et_pb_line_break_holder] -->      this.ctxMenu.addEventListener('click', e => {<!-- [et_pb_line_break_holder] -->        const it = e.target.closest('[data-ctx]'); if (!it || !this.ctx) return;<!-- [et_pb_line_break_holder] -->        const { id, field } = this.ctx;<!-- [et_pb_line_break_holder] -->        if (it.dataset.ctx === 'revert') this.revertField(id, field);<!-- [et_pb_line_break_holder] -->        if (it.dataset.ctx === 'clear')  this.setField(id, field, '');<!-- [et_pb_line_break_holder] -->        if (it.dataset.ctx === 'apply')  this.applyToAll(id, field);<!-- [et_pb_line_break_holder] -->        this.closeContext();<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->      document.addEventListener('click', e => { if (!this.ctxMenu.contains(e.target)) this.closeContext(); });<!-- [et_pb_line_break_holder] -->      window.addEventListener('scroll', () => this.closeContext(), true);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      \/\/ Modal<!-- [et_pb_line_break_holder] -->      this.$('#cancelSaveBtn').addEventListener('click', () => this.closeSaveModal());<!-- [et_pb_line_break_holder] -->      this.$('#confirmSaveBtn').addEventListener('click', () => this.executeSave());<!-- [et_pb_line_break_holder] -->      this.saveModal.addEventListener('click', e => { if (e.target === this.saveModal) this.closeSaveModal(); });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      \/\/ Drag & drop anywhere on the tool<!-- [et_pb_line_break_holder] -->      const hasFiles = e => e.dataTransfer && Array.from(e.dataTransfer.types || []).includes('Files');<!-- [et_pb_line_break_holder] -->      this.root.addEventListener('dragenter', e => { if (!hasFiles(e)) return; e.preventDefault(); this.dragDepth++; this.root.classList.add('dragging'); });<!-- [et_pb_line_break_holder] -->      this.root.addEventListener('dragover',  e => { if (hasFiles(e)) e.preventDefault(); });<!-- [et_pb_line_break_holder] -->      this.root.addEventListener('dragleave', e => { if (!hasFiles(e)) return; this.dragDepth = Math.max(0, this.dragDepth - 1); if (!this.dragDepth) this.root.classList.remove('dragging'); });<!-- [et_pb_line_break_holder] -->      this.root.addEventListener('drop', e => {<!-- [et_pb_line_break_holder] -->        if (!hasFiles(e)) return;<!-- [et_pb_line_break_holder] -->        e.preventDefault(); this.dragDepth = 0; this.root.classList.remove('dragging');<!-- [et_pb_line_break_holder] -->        this.handleFiles(e.dataTransfer.files);<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      document.addEventListener('keydown', e => this.onKey(e));<!-- [et_pb_line_break_holder] -->      document.addEventListener('fullscreenchange', () => { if (this.isFullscreen && !document.fullscreenElement) this.exitFullscreen(); });<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    onKey(e) {<!-- [et_pb_line_break_holder] -->      if (e.key === 'Escape') {<!-- [et_pb_line_break_holder] -->        if (this.saveModal.classList.contains('show')) { this.closeSaveModal(); return; }<!-- [et_pb_line_break_holder] -->        if (this.ctxMenu.classList.contains('show')) { this.closeContext(); return; }<!-- [et_pb_line_break_holder] -->        if (this.isFullscreen) { this.exitFullscreen(); }<!-- [et_pb_line_break_holder] -->        return;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      if (!this.metas.length) return;<!-- [et_pb_line_break_holder] -->      const t = e.target;<!-- [et_pb_line_break_holder] -->      const inside = this.root.contains(t) || t === document.body;<!-- [et_pb_line_break_holder] -->      if (!inside) return;<!-- [et_pb_line_break_holder] -->      const typing = \/^(INPUT|TEXTAREA|SELECT)$\/.test(t.tagName) || t.isContentEditable;<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 's') {<!-- [et_pb_line_break_holder] -->        e.preventDefault();<!-- [et_pb_line_break_holder] -->        const id = (t.dataset && t.dataset.id) || this.activeId;<!-- [et_pb_line_break_holder] -->        const m = this.byId(id);<!-- [et_pb_line_break_holder] -->        if (m && this.isEditable(m)) this.showSaveModal(id);<!-- [et_pb_line_break_holder] -->        return;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      if (e.altKey && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {<!-- [et_pb_line_break_holder] -->        e.preventDefault(); this.step(e.key === 'ArrowDown' ? 1 : -1); return;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      if (!typing && !e.ctrlKey && !e.metaKey && !e.altKey && e.key.toLowerCase() === 'f' && !this.saveModal.classList.contains('show')) {<!-- [et_pb_line_break_holder] -->        this.toggleFullscreen();<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    onMainClick(e) {<!-- [et_pb_line_break_holder] -->      const btn = e.target.closest('[data-action]');<!-- [et_pb_line_break_holder] -->      if (!btn || !this.main.contains(btn)) return;<!-- [et_pb_line_break_holder] -->      const id = btn.dataset.id || this.activeId;<!-- [et_pb_line_break_holder] -->      const field = btn.dataset.field;<!-- [et_pb_line_break_holder] -->      switch (btn.dataset.action) {<!-- [et_pb_line_break_holder] -->        case 'prev':        this.step(-1); break;<!-- [et_pb_line_break_holder] -->        case 'next':        this.step(1); break;<!-- [et_pb_line_break_holder] -->        case 'save-file':   this.showSaveModal(id); break;<!-- [et_pb_line_break_holder] -->        case 'revert-file': this.revertFile(id); break;<!-- [et_pb_line_break_holder] -->        case 'revert':      this.revertField(id, field); break;<!-- [et_pb_line_break_holder] -->        case 'apply-all':   this.applyToAll(id, field); break;<!-- [et_pb_line_break_holder] -->        case 'open':        this.activeId = id; this.setView('editor'); break;<!-- [et_pb_line_break_holder] -->        case 'remove':      this.removeFile(id); break;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    onInput(e) {<!-- [et_pb_line_break_holder] -->      const t = e.target;<!-- [et_pb_line_break_holder] -->      if (!t.classList || !(t.classList.contains('fl-input') || t.classList.contains('cell'))) return;<!-- [et_pb_line_break_holder] -->      const meta = this.byId(t.dataset.id); if (!meta) return;<!-- [et_pb_line_break_holder] -->      const field = t.dataset.field;<!-- [et_pb_line_break_holder] -->      this.setValue(meta, field, t.value);<!-- [et_pb_line_break_holder] -->      const mod = this.isModified(meta, field);<!-- [et_pb_line_break_holder] -->      const wrap = t.closest('.field');<!-- [et_pb_line_break_holder] -->      if (wrap) {<!-- [et_pb_line_break_holder] -->        wrap.classList.toggle('modified', mod);<!-- [et_pb_line_break_holder] -->        const c = wrap.querySelector('[data-count]');<!-- [et_pb_line_break_holder] -->        if (c) { const n = byteLen(t.value); c.textContent = `${n}\/${WAV_LIMITS[field]}`; c.classList.toggle('over', n > WAV_LIMITS[field]); }<!-- [et_pb_line_break_holder] -->      } else {<!-- [et_pb_line_break_holder] -->        t.classList.toggle('modified', mod);<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      this.refreshDirty(meta);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    onContext(e) {<!-- [et_pb_line_break_holder] -->      const t = e.target.closest('.fl-input, .cell');<!-- [et_pb_line_break_holder] -->      if (!t || t.disabled) return;<!-- [et_pb_line_break_holder] -->      e.preventDefault();<!-- [et_pb_line_break_holder] -->      this.ctx = { id: t.dataset.id, field: t.dataset.field };<!-- [et_pb_line_break_holder] -->      const m = this.ctxMenu;<!-- [et_pb_line_break_holder] -->      m.classList.add('show');<!-- [et_pb_line_break_holder] -->      const w = m.offsetWidth, h = m.offsetHeight;<!-- [et_pb_line_break_holder] -->      m.style.left = Math.max(8, Math.min(e.clientX, window.innerWidth - w - 8)) + 'px';<!-- [et_pb_line_break_holder] -->      m.style.top  = Math.max(8, Math.min(e.clientY, window.innerHeight - h - 8)) + 'px';<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    closeContext() { this.ctxMenu.classList.remove('show'); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Data helpers<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    byId(id)       { return this.metas.find(m => m.id === id) || null; }<!-- [et_pb_line_break_holder] -->    active()       { return this.byId(this.activeId); }<!-- [et_pb_line_break_holder] -->    isEditable(m)  { return m.fileType === 'mp3' || m.fileType === 'wav'; }<!-- [et_pb_line_break_holder] -->    dirtyCount(m)  { return Object.keys(m.edits).length; }<!-- [et_pb_line_break_holder] -->    getValue(m, f) { return f in m.edits ? m.edits[f] : (m.tags[f] ?? ''); }<!-- [et_pb_line_break_holder] -->    isModified(m, f) { return f in m.edits; }<!-- [et_pb_line_break_holder] -->    setValue(m, f, v) {<!-- [et_pb_line_break_holder] -->      v = String(v ?? '');<!-- [et_pb_line_break_holder] -->      if (v === (m.tags[f] ?? '')) delete m.edits[f]; else m.edits[f] = v;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    setField(id, field, value) {<!-- [et_pb_line_break_holder] -->      const m = this.byId(id); if (!m) return;<!-- [et_pb_line_break_holder] -->      this.setValue(m, field, value);<!-- [et_pb_line_break_holder] -->      this.renderMain(true); this.refreshDirty(m);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    revertField(id, field) {<!-- [et_pb_line_break_holder] -->      const m = this.byId(id); if (!m) return;<!-- [et_pb_line_break_holder] -->      delete m.edits[field];<!-- [et_pb_line_break_holder] -->      this.renderMain(true); this.refreshDirty(m);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    revertFile(id) {<!-- [et_pb_line_break_holder] -->      const m = this.byId(id); if (!m || !this.dirtyCount(m)) return;<!-- [et_pb_line_break_holder] -->      m.edits = {};<!-- [et_pb_line_break_holder] -->      this.renderMain(true); this.refreshDirty(m);<!-- [et_pb_line_break_holder] -->      this.showStatus('Changes reverted');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    applyToAll(id, field) {<!-- [et_pb_line_break_holder] -->      const src = this.byId(id); if (!src) return;<!-- [et_pb_line_break_holder] -->      const value = this.getValue(src, field);<!-- [et_pb_line_break_holder] -->      let n = 0;<!-- [et_pb_line_break_holder] -->      this.metas.forEach(m => {<!-- [et_pb_line_break_holder] -->        if (m.id === id || !this.isEditable(m) || !(field in m.tags)) return;<!-- [et_pb_line_break_holder] -->        this.setValue(m, field, value); n++;<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->      this.renderMain(true); this.renderSidebar(); this.refreshChrome();<!-- [et_pb_line_break_holder] -->      this.showStatus(n ? `\u201c${field}\u201d copied to ${n} other file${n > 1 ? 's' : ''}` : 'No other compatible file for this field', n ? 'success' : 'warning');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Loading files<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    async handleFiles(fileList) {<!-- [et_pb_line_break_holder] -->      const exts = ['.mp3', '.wav', '.aiff', '.aif', '.ogg', '.flac', '.m4a'];<!-- [et_pb_line_break_holder] -->      const files = Array.from(fileList).filter(f => f.type.startsWith('audio\/') || exts.some(x => f.name.toLowerCase().endsWith(x)));<!-- [et_pb_line_break_holder] -->      if (!files.length) { this.showStatus('No valid audio files selected', 'error'); return; }<!-- [et_pb_line_break_holder] -->      this.showStatus(`Loading ${files.length} file(s)\u2026`);<!-- [et_pb_line_break_holder] -->      for (const file of files) {<!-- [et_pb_line_break_holder] -->        let meta;<!-- [et_pb_line_break_holder] -->        try { meta = await this.readMetadata(file); }<!-- [et_pb_line_break_holder] -->        catch (err) { console.error(err); this.showStatus(`Could not read ${file.name}`, 'error'); continue; }<!-- [et_pb_line_break_holder] -->        this.metas.push(meta);<!-- [et_pb_line_break_holder] -->        if (!this.activeId) this.activeId = meta.id;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      this.renderAll();<!-- [et_pb_line_break_holder] -->      this.showStatus(`Loaded ${files.length} file(s) successfully!`);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readMetadata(file) {<!-- [et_pb_line_break_holder] -->      const fileType = this.getFileType(file.name);<!-- [et_pb_line_break_holder] -->      const meta = { id: 'm' + (++this.uid), file, fileName: file.name, fileType, techInfo: {}, tags: {}, edits: {} };<!-- [et_pb_line_break_holder] -->      try {<!-- [et_pb_line_break_holder] -->        if (fileType === 'mp3')       { await this.readID3Tags(file, meta); await this.readMP3TechInfo(file, meta); }<!-- [et_pb_line_break_holder] -->        else if (fileType === 'wav')  await this.readWAVMetadata(file, meta);<!-- [et_pb_line_break_holder] -->        else if (fileType === 'aiff') await this.readAIFFMetadata(file, meta);<!-- [et_pb_line_break_holder] -->        else if (fileType === 'flac') await this.readFLACMetadata(file, meta);<!-- [et_pb_line_break_holder] -->        else if (fileType === 'ogg')  await this.readOGGMetadata(file, meta);<!-- [et_pb_line_break_holder] -->      } catch (err) { console.warn('Partial read for', file.name, err); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      this.getDefaultFields(fileType).forEach(f => { if (!(f in meta.tags)) meta.tags[f] = ''; });<!-- [et_pb_line_break_holder] -->      Object.keys(meta.tags).forEach(k => { const v = meta.tags[k]; meta.tags[k] = (v && typeof v === 'object') ? String(v.text ?? v.data ?? '') : String(v ?? ''); });<!-- [et_pb_line_break_holder] -->      meta.techInfo['File Size'] = this.formatFileSize(file.size);<!-- [et_pb_line_break_holder] -->      return meta;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    getDefaultFields(fileType) {<!-- [et_pb_line_break_holder] -->      const common = ['Title', 'Artist', 'Album', 'Year', 'Genre', 'Track', 'Comment', 'Copyright'];<!-- [et_pb_line_break_holder] -->      const byType = {<!-- [et_pb_line_break_holder] -->        wav:  [...common, 'Creation Date', 'Software', 'Subject', 'ISRC\/Source Code', 'Description', 'Originator', 'Originator Reference', 'Origination Date', 'Origination Time'],<!-- [et_pb_line_break_holder] -->        mp3:  [...common, 'Album Artist', 'Composer', 'Publisher', 'BPM', 'ISRC\/Source Code'],<!-- [et_pb_line_break_holder] -->        aiff: [...common, 'Album Artist', 'Composer'],<!-- [et_pb_line_break_holder] -->        flac: [...common, 'Album Artist', 'Composer', 'ISRC\/Source Code'],<!-- [et_pb_line_break_holder] -->        ogg:  [...common, 'Album Artist', 'Composer', 'ISRC\/Source Code'],<!-- [et_pb_line_break_holder] -->        m4a:  [...common, 'Album Artist', 'Composer'],<!-- [et_pb_line_break_holder] -->      };<!-- [et_pb_line_break_holder] -->      return byType[fileType] || common;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 Format readers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    async readID3Tags(file, meta) {<!-- [et_pb_line_break_holder] -->      return new Promise(resolve => {<!-- [et_pb_line_break_holder] -->        jsmediatags.read(file, {<!-- [et_pb_line_break_holder] -->          onSuccess: tag => {<!-- [et_pb_line_break_holder] -->            const t = tag.tags;<!-- [et_pb_line_break_holder] -->            if (t.title)        meta.tags['Title']        = t.title;<!-- [et_pb_line_break_holder] -->            if (t.artist)       meta.tags['Artist']       = t.artist;<!-- [et_pb_line_break_holder] -->            if (t.album)        meta.tags['Album']        = t.album;<!-- [et_pb_line_break_holder] -->            if (t.year)         meta.tags['Year']         = t.year;<!-- [et_pb_line_break_holder] -->            if (t.genre)        meta.tags['Genre']        = t.genre;<!-- [et_pb_line_break_holder] -->            if (t.track)        meta.tags['Track']        = t.track;<!-- [et_pb_line_break_holder] -->            if (t.comment)      meta.tags['Comment']      = t.comment?.text || t.comment;<!-- [et_pb_line_break_holder] -->            if (t.album_artist) meta.tags['Album Artist'] = t.album_artist;<!-- [et_pb_line_break_holder] -->            if (t.composer)     meta.tags['Composer']     = t.composer;<!-- [et_pb_line_break_holder] -->            if (t.copyright)    meta.tags['Copyright']    = t.copyright;<!-- [et_pb_line_break_holder] -->            if (t.publisher)    meta.tags['Publisher']    = t.publisher;<!-- [et_pb_line_break_holder] -->            if (t.bpm)          meta.tags['BPM']          = t.bpm;<!-- [et_pb_line_break_holder] -->            if (t.ISRC)         meta.tags['ISRC\/Source Code'] = t.ISRC;<!-- [et_pb_line_break_holder] -->            resolve();<!-- [et_pb_line_break_holder] -->          },<!-- [et_pb_line_break_holder] -->          onError: () => resolve()<!-- [et_pb_line_break_holder] -->        });<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readMP3TechInfo(file, meta) {<!-- [et_pb_line_break_holder] -->      meta.techInfo['Format'] = 'MP3';<!-- [et_pb_line_break_holder] -->      const slice = await file.slice(0, Math.min(65536, file.size)).arrayBuffer();<!-- [et_pb_line_break_holder] -->      const bytes = new Uint8Array(slice);<!-- [et_pb_line_break_holder] -->      let start = 0;<!-- [et_pb_line_break_holder] -->      if (bytes[0] === 0x49 && bytes[1] === 0x44 && bytes[2] === 0x33) {<!-- [et_pb_line_break_holder] -->        start = 10 + ((bytes[6] & 0x7F) << 21 | (bytes[7] &#038; 0x7F) << 14 | (bytes[8] &#038; 0x7F) << 7 | (bytes[9] &#038; 0x7F));<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      for (let i = start; i < bytes.length - 4; i++) {<!-- [et_pb_line_break_holder] -->        if (bytes[i] === 0xFF && (bytes[i + 1] & 0xE0) === 0xE0) {<!-- [et_pb_line_break_holder] -->          const b1 = bytes[i + 1], b2 = bytes[i + 2], b3 = bytes[i + 3];<!-- [et_pb_line_break_holder] -->          const mpegVer = (b1 >> 3) & 0x3, layerIdx = (b1 >> 1) & 0x3;<!-- [et_pb_line_break_holder] -->          if (mpegVer === 3 && layerIdx === 1) {<!-- [et_pb_line_break_holder] -->            const bitrates = [0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0];<!-- [et_pb_line_break_holder] -->            const sampleRates = [44100, 48000, 32000, 0];<!-- [et_pb_line_break_holder] -->            const br = bitrates[(b2 >> 4) & 0xF], sr = sampleRates[(b2 >> 2) & 0x3], ch = (b3 >> 6) & 0x3;<!-- [et_pb_line_break_holder] -->            if (br > 0 && sr > 0) {<!-- [et_pb_line_break_holder] -->              meta.techInfo['Bitrate']     = `${br} kbps`;<!-- [et_pb_line_break_holder] -->              meta.techInfo['Sample Rate'] = `${sr \/ 1000} kHz`;<!-- [et_pb_line_break_holder] -->              meta.techInfo['Channels']    = ch === 3 ? 'Mono' : 'Stereo';<!-- [et_pb_line_break_holder] -->              meta.techInfo['Duration']    = this.formatDuration((file.size - start) * 8 \/ (br * 1000));<!-- [et_pb_line_break_holder] -->            }<!-- [et_pb_line_break_holder] -->          }<!-- [et_pb_line_break_holder] -->          break;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readWAVMetadata(file, meta) {<!-- [et_pb_line_break_holder] -->      const buffer = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const view = new DataView(buffer);<!-- [et_pb_line_break_holder] -->      let offset = 12, dataSize = 0;<!-- [et_pb_line_break_holder] -->      while (offset < buffer.byteLength - 8) {<!-- [et_pb_line_break_holder] -->        const chunkId = this.readString(view, offset, 4);<!-- [et_pb_line_break_holder] -->        const chunkSize = view.getUint32(offset + 4, true);<!-- [et_pb_line_break_holder] -->        offset += 8;<!-- [et_pb_line_break_holder] -->        if (chunkId === 'fmt ') {<!-- [et_pb_line_break_holder] -->          const audioFormat = view.getUint16(offset, true);<!-- [et_pb_line_break_holder] -->          const numChannels = view.getUint16(offset + 2, true);<!-- [et_pb_line_break_holder] -->          const sampleRate = view.getUint32(offset + 4, true);<!-- [et_pb_line_break_holder] -->          const byteRate = view.getUint32(offset + 8, true);<!-- [et_pb_line_break_holder] -->          const bitsPerSample = view.getUint16(offset + 14, true);<!-- [et_pb_line_break_holder] -->          const fmtNames = { 1: 'PCM', 3: 'IEEE Float', 6: 'A-law', 7: '\u00b5-law', 65534: 'Extensible' };<!-- [et_pb_line_break_holder] -->          const chNames = { 1: 'Mono', 2: 'Stereo', 4: 'Quad', 6: '5.1', 8: '7.1' };<!-- [et_pb_line_break_holder] -->          meta.techInfo['Format']      = fmtNames[audioFormat] || `0x${audioFormat.toString(16)}`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Channels']    = chNames[numChannels] || `${numChannels} ch`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Sample Rate'] = `${(sampleRate \/ 1000).toFixed(sampleRate % 1000 ? 3 : 0)} kHz`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bit Depth']   = `${bitsPerSample}-bit`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bitrate']     = `${Math.round(byteRate * 8 \/ 1000)} kbps`;<!-- [et_pb_line_break_holder] -->        } else if (chunkId === 'data') {<!-- [et_pb_line_break_holder] -->          dataSize = chunkSize;<!-- [et_pb_line_break_holder] -->        } else if (chunkId === 'bext') {<!-- [et_pb_line_break_holder] -->          meta.tags['Description']          = this.readString(view, offset, 256).trim();<!-- [et_pb_line_break_holder] -->          meta.tags['Originator']           = this.readString(view, offset + 256, 32).trim();<!-- [et_pb_line_break_holder] -->          meta.tags['Originator Reference'] = this.readString(view, offset + 288, 32).trim();<!-- [et_pb_line_break_holder] -->          meta.tags['Origination Date']     = this.readString(view, offset + 320, 10).trim();<!-- [et_pb_line_break_holder] -->          meta.tags['Origination Time']     = this.readString(view, offset + 330, 8).trim();<!-- [et_pb_line_break_holder] -->        } else if (chunkId === 'LIST') {<!-- [et_pb_line_break_holder] -->          if (this.readString(view, offset, 4) === 'INFO') this.parseINFOChunk(view, offset + 4, chunkSize - 4, meta);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        offset += chunkSize;<!-- [et_pb_line_break_holder] -->        if (chunkSize % 2 === 1) offset++;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      if (dataSize > 0 && meta.techInfo['Bitrate']) {<!-- [et_pb_line_break_holder] -->        const byteRate = parseInt(meta.techInfo['Bitrate']) * 1000 \/ 8;<!-- [et_pb_line_break_holder] -->        meta.techInfo['Duration'] = this.formatDuration(dataSize \/ byteRate);<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    parseINFOChunk(view, offset, size, meta) {<!-- [et_pb_line_break_holder] -->      const end = offset + size;<!-- [et_pb_line_break_holder] -->      const fieldMap = { INAM: 'Title', IART: 'Artist', IPRD: 'Album', ICMT: 'Comment', ICRD: 'Creation Date', IGNR: 'Genre', ICOP: 'Copyright', ISFT: 'Software', ISBJ: 'Subject', ISRC: 'ISRC\/Source Code' };<!-- [et_pb_line_break_holder] -->      while (offset < end - 8) {<!-- [et_pb_line_break_holder] -->        const id = this.readString(view, offset, 4);<!-- [et_pb_line_break_holder] -->        const sz = view.getUint32(offset + 4, true);<!-- [et_pb_line_break_holder] -->        offset += 8;<!-- [et_pb_line_break_holder] -->        const value = this.readString(view, offset, sz).trim();<!-- [et_pb_line_break_holder] -->        if (fieldMap[id] && value) meta.tags[fieldMap[id]] = value;<!-- [et_pb_line_break_holder] -->        offset += sz;<!-- [et_pb_line_break_holder] -->        if (sz % 2 === 1) offset++;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readAIFFMetadata(file, meta) {<!-- [et_pb_line_break_holder] -->      const buffer = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const view = new DataView(buffer);<!-- [et_pb_line_break_holder] -->      let offset = 12;<!-- [et_pb_line_break_holder] -->      while (offset < buffer.byteLength - 8) {<!-- [et_pb_line_break_holder] -->        const chunkId = this.readString(view, offset, 4);<!-- [et_pb_line_break_holder] -->        const chunkSize = view.getInt32(offset + 4, false);<!-- [et_pb_line_break_holder] -->        offset += 8;<!-- [et_pb_line_break_holder] -->        if (chunkId === 'COMM') {<!-- [et_pb_line_break_holder] -->          const numCh = view.getInt16(offset, false);<!-- [et_pb_line_break_holder] -->          const numFrames = view.getUint32(offset + 2, false);<!-- [et_pb_line_break_holder] -->          const bitDepth = view.getInt16(offset + 6, false);<!-- [et_pb_line_break_holder] -->          const exp = (view.getUint16(offset + 8, false) & 0x7FFF) - 16383;<!-- [et_pb_line_break_holder] -->          const mant = (view.getUint32(offset + 10, false) \/ Math.pow(2, 32) + view.getUint32(offset + 14, false) \/ Math.pow(2, 64)) * Math.pow(2, 32);<!-- [et_pb_line_break_holder] -->          const sr = mant * Math.pow(2, exp - 31);<!-- [et_pb_line_break_holder] -->          const chNames = { 1: 'Mono', 2: 'Stereo', 4: 'Quad', 6: '5.1' };<!-- [et_pb_line_break_holder] -->          meta.techInfo['Format']      = 'AIFF PCM';<!-- [et_pb_line_break_holder] -->          meta.techInfo['Channels']    = chNames[numCh] || `${numCh} ch`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Sample Rate'] = `${(sr \/ 1000).toFixed(sr % 1000 ? 3 : 0)} kHz`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bit Depth']   = `${bitDepth}-bit`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bitrate']     = `${Math.round(sr * numCh * bitDepth \/ 1000)} kbps`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Duration']    = this.formatDuration(numFrames \/ sr);<!-- [et_pb_line_break_holder] -->        } else if (chunkId === 'NAME') meta.tags['Title']     = this.readString(view, offset, chunkSize).trim();<!-- [et_pb_line_break_holder] -->        else if (chunkId === 'AUTH')   meta.tags['Artist']    = this.readString(view, offset, chunkSize).trim();<!-- [et_pb_line_break_holder] -->        else if (chunkId === '(c) ')   meta.tags['Copyright'] = this.readString(view, offset, chunkSize).trim();<!-- [et_pb_line_break_holder] -->        else if (chunkId === 'ANNO')   meta.tags['Comment']   = this.readString(view, offset, chunkSize).trim();<!-- [et_pb_line_break_holder] -->        offset += chunkSize + (chunkSize % 2);<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readFLACMetadata(file, meta) {<!-- [et_pb_line_break_holder] -->      const buffer = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const bytes = new Uint8Array(buffer);<!-- [et_pb_line_break_holder] -->      const view = new DataView(buffer);<!-- [et_pb_line_break_holder] -->      meta.techInfo['Format'] = 'FLAC';<!-- [et_pb_line_break_holder] -->      if (bytes[0] !== 0x66 || bytes[1] !== 0x4C || bytes[2] !== 0x61 || bytes[3] !== 0x43) return;<!-- [et_pb_line_break_holder] -->      let offset = 4;<!-- [et_pb_line_break_holder] -->      while (offset < buffer.byteLength - 4) {<!-- [et_pb_line_break_holder] -->        const blockByte = bytes[offset];<!-- [et_pb_line_break_holder] -->        const isLast = (blockByte & 0x80) !== 0;<!-- [et_pb_line_break_holder] -->        const blockType = blockByte & 0x7F;<!-- [et_pb_line_break_holder] -->        const blockLen = (bytes[offset + 1] << 16) | (bytes[offset + 2] << 8) | bytes[offset + 3];<!-- [et_pb_line_break_holder] -->        offset += 4;<!-- [et_pb_line_break_holder] -->        if (blockType === 0) {<!-- [et_pb_line_break_holder] -->          const sr = ((bytes[offset] << 12) | (bytes[offset + 1] << 4) | (bytes[offset + 2] >> 4)) & 0xFFFFF;<!-- [et_pb_line_break_holder] -->          const numCh = ((bytes[offset + 2] >> 1) & 0x7) + 1;<!-- [et_pb_line_break_holder] -->          const bitDepth = (((bytes[offset + 2] & 0x1) << 4) | (bytes[offset + 3] >> 4)) + 1;<!-- [et_pb_line_break_holder] -->          const samples = ((bytes[offset + 3] & 0xF) * Math.pow(2, 32)) + (bytes[offset + 4] * 16777216) + (bytes[offset + 5] << 16) + (bytes[offset + 6] << 8) + bytes[offset + 7];<!-- [et_pb_line_break_holder] -->          const dur = samples \/ sr;<!-- [et_pb_line_break_holder] -->          const chNames = { 1: 'Mono', 2: 'Stereo', 4: 'Quad', 6: '5.1', 8: '7.1' };<!-- [et_pb_line_break_holder] -->          meta.techInfo['Channels']    = chNames[numCh] || `${numCh} ch`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Sample Rate'] = `${(sr \/ 1000).toFixed(sr % 1000 ? 3 : 0)} kHz`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bit Depth']   = `${bitDepth}-bit`;<!-- [et_pb_line_break_holder] -->          meta.techInfo['Duration']    = this.formatDuration(dur);<!-- [et_pb_line_break_holder] -->          meta.techInfo['Bitrate']     = `${Math.round(file.size * 8 \/ (dur * 1000))} kbps`;<!-- [et_pb_line_break_holder] -->        } else if (blockType === 4) {<!-- [et_pb_line_break_holder] -->          this.parseVorbisComments(view, bytes, offset, meta, true);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->        offset += blockLen;<!-- [et_pb_line_break_holder] -->        if (isLast) break;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async readOGGMetadata(file, meta) {<!-- [et_pb_line_break_holder] -->      const buffer = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const bytes = new Uint8Array(buffer);<!-- [et_pb_line_break_holder] -->      const view = new DataView(buffer);<!-- [et_pb_line_break_holder] -->      meta.techInfo['Format'] = 'OGG Vorbis';<!-- [et_pb_line_break_holder] -->      const isVorbis = (i, type) => bytes[i] === type && bytes[i+1] === 0x76 && bytes[i+2] === 0x6F && bytes[i+3] === 0x72 && bytes[i+4] === 0x62 && bytes[i+5] === 0x69 && bytes[i+6] === 0x73;<!-- [et_pb_line_break_holder] -->      for (let i = 0; i < Math.min(bytes.length - 7, 8192); i++) {<!-- [et_pb_line_break_holder] -->        if (isVorbis(i, 0x01)) {<!-- [et_pb_line_break_holder] -->          const ch = bytes[i + 11], sr = view.getUint32(i + 12, true), nomBR = view.getInt32(i + 20, true);<!-- [et_pb_line_break_holder] -->          meta.techInfo['Channels']    = ch === 1 ? 'Mono' : 'Stereo';<!-- [et_pb_line_break_holder] -->          meta.techInfo['Sample Rate'] = `${(sr \/ 1000).toFixed(sr % 1000 ? 3 : 0)} kHz`;<!-- [et_pb_line_break_holder] -->          if (nomBR > 0) meta.techInfo['Bitrate'] = `${Math.round(nomBR \/ 1000)} kbps`;<!-- [et_pb_line_break_holder] -->          break;<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      for (let i = 0; i < bytes.length - 7; i++) {<!-- [et_pb_line_break_holder] -->        if (isVorbis(i, 0x03)) { this.parseVorbisComments(view, bytes, i + 7, meta, false); break; }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    parseVorbisComments(view, bytes, pos, meta, withBPM) {<!-- [et_pb_line_break_holder] -->      const vendorLen = view.getUint32(pos, true); pos += 4 + vendorLen;<!-- [et_pb_line_break_holder] -->      const count = view.getUint32(pos, true); pos += 4;<!-- [et_pb_line_break_holder] -->      const km = { TITLE: 'Title', ARTIST: 'Artist', ALBUM: 'Album', DATE: 'Year', GENRE: 'Genre', TRACKNUMBER: 'Track', COMMENT: 'Comment', ALBUMARTIST: 'Album Artist', COMPOSER: 'Composer', COPYRIGHT: 'Copyright', ISRC: 'ISRC\/Source Code' };<!-- [et_pb_line_break_holder] -->      if (withBPM) km.BPM = 'BPM';<!-- [et_pb_line_break_holder] -->      for (let c = 0; c < count &#038;&#038; pos < bytes.length - 4; c++) {<!-- [et_pb_line_break_holder] -->        const len = view.getUint32(pos, true); pos += 4;<!-- [et_pb_line_break_holder] -->        const comment = new TextDecoder().decode(bytes.slice(pos, pos + len)); pos += len;<!-- [et_pb_line_break_holder] -->        const eq = comment.indexOf('=');<!-- [et_pb_line_break_holder] -->        if (eq > 0) { const k = comment.substring(0, eq).toUpperCase(); if (km[k]) meta.tags[km[k]] = comment.substring(eq + 1); }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 Utilities \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    formatDuration(sec) {<!-- [et_pb_line_break_holder] -->      if (!isFinite(sec) || sec < 0) return '\u2014';<!-- [et_pb_line_break_holder] -->      const h = Math.floor(sec \/ 3600), m = Math.floor((sec % 3600) \/ 60), s = Math.floor(sec % 60);<!-- [et_pb_line_break_holder] -->      return h > 0 ? `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}` : `${m}:${String(s).padStart(2, '0')}`;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    formatFileSize(b) {<!-- [et_pb_line_break_holder] -->      if (b < 1024) return `${b} B`;<!-- [et_pb_line_break_holder] -->      if (b < 1048576) return `${(b \/ 1024).toFixed(1)} KB`;<!-- [et_pb_line_break_holder] -->      return `${(b \/ 1048576).toFixed(2)} MB`;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    \/\/ Reads a null-terminated string; UTF-8 first (so accents round-trip), Windows-1252 fallback<!-- [et_pb_line_break_holder] -->    readString(view, offset, length) {<!-- [et_pb_line_break_holder] -->      length = Math.min(length, view.byteLength - offset);<!-- [et_pb_line_break_holder] -->      if (length <= 0) return '';<!-- [et_pb_line_break_holder] -->      let bytes = new Uint8Array(view.buffer, view.byteOffset + offset, length);<!-- [et_pb_line_break_holder] -->      const z = bytes.indexOf(0);<!-- [et_pb_line_break_holder] -->      if (z >= 0) bytes = bytes.subarray(0, z);<!-- [et_pb_line_break_holder] -->      try { return new TextDecoder('utf-8', { fatal: true }).decode(bytes); }<!-- [et_pb_line_break_holder] -->      catch (e) { return new TextDecoder('windows-1252').decode(bytes); }<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    getFileType(name) {<!-- [et_pb_line_break_holder] -->      const ext = name.split('.').pop().toLowerCase();<!-- [et_pb_line_break_holder] -->      return { mp3: 'mp3', wav: 'wav', aiff: 'aiff', aif: 'aiff', ogg: 'ogg', flac: 'flac', m4a: 'm4a' }[ext] || 'unknown';<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    techSummary(m) {<!-- [et_pb_line_break_holder] -->      const t = m.techInfo;<!-- [et_pb_line_break_holder] -->      return ['Sample Rate', 'Bit Depth', 'Channels', 'Duration'].map(k => t[k]).filter(Boolean).join(' \u00b7 ');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    techPills(m) {<!-- [et_pb_line_break_holder] -->      return ['Format', 'Sample Rate', 'Bit Depth', 'Channels', 'Bitrate', 'Duration', 'File Size']<!-- [et_pb_line_break_holder] -->        .filter(k => m.techInfo[k])<!-- [et_pb_line_break_holder] -->        .map(k => `<span class=\"tech-pill\"><i>${k}<\/i><b>${esc(m.techInfo[k])}<\/b><\/span>`).join('');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Rendering<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    renderAll() { this.renderSidebar(); this.renderMain(false); this.refreshChrome(); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    refreshChrome() {<!-- [et_pb_line_break_holder] -->      this.root.classList.toggle('has-files', this.metas.length > 0);<!-- [et_pb_line_break_holder] -->      this.$('#fileCount').textContent = this.metas.length;<!-- [et_pb_line_break_holder] -->      const dirty = this.metas.filter(m => this.isEditable(m) && this.dirtyCount(m)).length;<!-- [et_pb_line_break_holder] -->      const c = this.$('#modCount');<!-- [et_pb_line_break_holder] -->      c.textContent = dirty || ''; c.classList.toggle('zero', !dirty);<!-- [et_pb_line_break_holder] -->      this.$('#saveAllBtn').disabled = !dirty;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    refreshDirty(meta) {<!-- [et_pb_line_break_holder] -->      const n = this.dirtyCount(meta);<!-- [et_pb_line_break_holder] -->      const it = this.fileList.querySelector(`.file-item[data-id=\"${meta.id}\"]`);<!-- [et_pb_line_break_holder] -->      if (it) it.classList.toggle('dirty', n > 0);<!-- [et_pb_line_break_holder] -->      const row = this.main.querySelector(`tr[data-id=\"${meta.id}\"]`);<!-- [et_pb_line_break_holder] -->      if (row) row.classList.toggle('tr-dirty', n > 0);<!-- [et_pb_line_break_holder] -->      if (meta.id === this.activeId) {<!-- [et_pb_line_break_holder] -->        const chg = this.main.querySelector('.ed-chg');<!-- [et_pb_line_break_holder] -->        if (chg) { chg.textContent = `\u25cf ${n} unsaved change${n > 1 ? 's' : ''}`; chg.classList.toggle('show', n > 0); }<!-- [et_pb_line_break_holder] -->        const rv = this.main.querySelector('[data-action=\"revert-file\"]');<!-- [et_pb_line_break_holder] -->        if (rv) rv.disabled = n === 0;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      this.refreshChrome();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    renderSidebar() {<!-- [et_pb_line_break_holder] -->      this.fileList.innerHTML = this.metas.map(m => {<!-- [et_pb_line_break_holder] -->        const ro = !this.isEditable(m);<!-- [et_pb_line_break_holder] -->        return `<\/p>\n<div class=\"file-item${m.id === this.activeId ? ' active' : ''}${this.dirtyCount(m) ? ' dirty' : ''}\" data-id=\"${m.id}\" role=\"button\" tabindex=\"0\"><!-- [et_pb_line_break_holder] -->          <\/p>\n<div class=\"fi-row\"><!-- [et_pb_line_break_holder] -->            <span class=\"badge badge-${esc(m.fileType)}\">${esc(m.fileType)}<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"fi-name\" title=\"${esc(m.fileName)}\">${esc(m.fileName)}<\/span><!-- [et_pb_line_break_holder] -->            <span class=\"fi-dot\" title=\"Unsaved changes\"><\/span><!-- [et_pb_line_break_holder] -->            <button type=\"button\" class=\"fi-rm\" title=\"Remove from list\" aria-label=\"Remove\">\u2715<\/button><!-- [et_pb_line_break_holder] -->          <\/div>\n<p><!-- [et_pb_line_break_holder] -->          <\/p>\n<div class=\"fi-sub\">${esc(this.techSummary(m))}${ro ? (this.techSummary(m) ? ' \u00b7 ' : '') + 'read-only' : ''}<\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/div>\n<p>`;<!-- [et_pb_line_break_holder] -->      }).join('');<!-- [et_pb_line_break_holder] -->      this.ensureVisible();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    ensureVisible() {<!-- [et_pb_line_break_holder] -->      const it = this.fileList.querySelector('.file-item.active'); if (!it) return;<!-- [et_pb_line_break_holder] -->      const l = this.fileList;<!-- [et_pb_line_break_holder] -->      if (it.offsetTop < l.scrollTop) l.scrollTop = it.offsetTop - 8;<!-- [et_pb_line_break_holder] -->      else if (it.offsetTop + it.offsetHeight > l.scrollTop + l.clientHeight) l.scrollTop = it.offsetTop + it.offsetHeight - l.clientHeight + 8;<!-- [et_pb_line_break_holder] -->      if (it.offsetLeft < l.scrollLeft) l.scrollLeft = it.offsetLeft - 8;<!-- [et_pb_line_break_holder] -->      else if (it.offsetLeft + it.offsetWidth > l.scrollLeft + l.clientWidth) l.scrollLeft = it.offsetLeft + it.offsetWidth - l.clientWidth + 8;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    renderMain(keepScroll) {<!-- [et_pb_line_break_holder] -->      const st = this.main.scrollTop;<!-- [et_pb_line_break_holder] -->      const tblWrap = this.main.querySelector('.tbl-wrap');<!-- [et_pb_line_break_holder] -->      const tl = tblWrap ? tblWrap.scrollLeft : 0, tt = tblWrap ? tblWrap.scrollTop : 0;<!-- [et_pb_line_break_holder] -->      if (this.view === 'table') this.renderTable(); else this.renderEditor();<!-- [et_pb_line_break_holder] -->      if (keepScroll) {<!-- [et_pb_line_break_holder] -->        this.main.scrollTop = st;<!-- [et_pb_line_break_holder] -->        const w = this.main.querySelector('.tbl-wrap'); if (w) { w.scrollLeft = tl; w.scrollTop = tt; }<!-- [et_pb_line_break_holder] -->      } else this.main.scrollTop = 0;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    fieldHTML(meta, field, editable) {<!-- [et_pb_line_break_holder] -->      const val = this.getValue(meta, field);<!-- [et_pb_line_break_holder] -->      const mod = this.isModified(meta, field);<!-- [et_pb_line_break_holder] -->      const wide = WIDE.has(field);<!-- [et_pb_line_break_holder] -->      const limit = meta.fileType === 'wav' ? WAV_LIMITS[field] : null;<!-- [et_pb_line_break_holder] -->      const inputId = `in-${meta.id}-${field.replace(\/[^a-z0-9]\/gi, '-')}`;<!-- [et_pb_line_break_holder] -->      const attrs = `class=\"fl-input\" id=\"${inputId}\" data-id=\"${meta.id}\" data-field=\"${esc(field)}\" placeholder=\"${esc(PLACEHOLDERS[field] || '')}\"${editable ? '' : ' disabled'}`;<!-- [et_pb_line_break_holder] -->      const n = limit ? byteLen(val) : 0;<!-- [et_pb_line_break_holder] -->      return `<\/p>\n<div class=\"field${wide ? ' wide' : ''}${mod ? ' modified' : ''}\"><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"fl-head\"><!-- [et_pb_line_break_holder] -->          <label for=\"${inputId}\">${esc(field)}<\/label><!-- [et_pb_line_break_holder] -->          <span class=\"fl-tools\"><!-- [et_pb_line_break_holder] -->            ${limit ? `<span class=\"fl-count${n > limit ? ' over' : ''}\" data-count title=\"Max ${limit} bytes in this BWF field\">${n}\/${limit}<\/span>` : ''}<!-- [et_pb_line_break_holder] -->            ${editable ? `<button type=\"button\" class=\"fl-btn\" data-action=\"revert\" data-field=\"${esc(field)}\" title=\"Revert to original\">\u21ba<\/button><!-- [et_pb_line_break_holder] -->            <button type=\"button\" class=\"fl-btn\" data-action=\"apply-all\" data-field=\"${esc(field)}\" title=\"Copy this value to all files\">\u21c9 All<\/button>` : ''}<!-- [et_pb_line_break_holder] -->          <\/span><!-- [et_pb_line_break_holder] -->        <\/div>\n<p><!-- [et_pb_line_break_holder] -->        ${wide ? `<textarea ${attrs} rows=\"3\">${esc(val)}<\/textarea>` : `<input type=\"text\" ${attrs} value=\"${esc(val)}\">`}<!-- [et_pb_line_break_holder] -->      <\/div>\n<p>`;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    renderEditor() {<!-- [et_pb_line_break_holder] -->      const meta = this.active();<!-- [et_pb_line_break_holder] -->      if (!meta) { this.main.innerHTML = ''; return; }<!-- [et_pb_line_break_holder] -->      const editable = this.isEditable(meta);<!-- [et_pb_line_break_holder] -->      const idx = this.metas.indexOf(meta), n = this.metas.length;<!-- [et_pb_line_break_holder] -->      const q = this.query;<!-- [et_pb_line_break_holder] -->      const fields = Object.keys(meta.tags);<!-- [et_pb_line_break_holder] -->      const groups = [...FIELD_GROUPS, { id: 'other', icon: '\ud83e\udde9', title: 'Other', fields: fields.filter(f => !GROUP_FIELDS.has(f)) }];<!-- [et_pb_line_break_holder] -->      let sections = '';<!-- [et_pb_line_break_holder] -->      groups.forEach(g => {<!-- [et_pb_line_break_holder] -->        const list = g.fields.filter(f => f in meta.tags && (!q || f.toLowerCase().includes(q)));<!-- [et_pb_line_break_holder] -->        if (!list.length) return;<!-- [et_pb_line_break_holder] -->        sections += `<\/p>\n<section class=\"group\">\n<h3><span>${g.icon}<\/span>${g.title}<\/h3>\n<div class=\"fields\">${list.map(f => this.fieldHTML(meta, f, editable)).join('')}<\/div>\n<\/section>\n<p>`;<!-- [et_pb_line_break_holder] -->      });<!-- [et_pb_line_break_holder] -->      if (!sections) sections = `<\/p>\n<div class=\"empty\">No field matches \u201c${esc(this.search.value)}\u201d.<\/div>\n<p>`;<!-- [et_pb_line_break_holder] -->      const dirty = this.dirtyCount(meta);<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->      this.main.innerHTML = `<!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"ed-head\"><!-- [et_pb_line_break_holder] -->          <\/p>\n<div class=\"ed-top\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"ed-title\"><span class=\"badge badge-${esc(meta.fileType)}\">${esc(meta.fileType)}<\/span><\/p>\n<h2 title=\"${esc(meta.fileName)}\">${esc(meta.fileName)}<\/h2>\n<\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"ed-actions\"><!-- [et_pb_line_break_holder] -->              <span class=\"ed-nav\"><!-- [et_pb_line_break_holder] -->                <button type=\"button\" class=\"nav-btn\" data-action=\"prev\" title=\"Previous file (Alt+\u2191)\" ${idx <= 0 ? 'disabled' : ''}>\u25c0<\/button><!-- [et_pb_line_break_holder] -->                <span>${idx + 1} \/ ${n}<\/span><!-- [et_pb_line_break_holder] -->                <button type=\"button\" class=\"nav-btn\" data-action=\"next\" title=\"Next file (Alt+\u2193)\" ${idx >= n - 1 ? 'disabled' : ''}>\u25b6<\/button><!-- [et_pb_line_break_holder] -->              <\/span><!-- [et_pb_line_break_holder] -->              ${editable ? `<button type=\"button\" class=\"btn btn-ghost btn-sm\" data-action=\"revert-file\" ${dirty ? '' : 'disabled'}>\u21ba Revert<\/button><!-- [et_pb_line_break_holder] -->              <button type=\"button\" class=\"btn btn-primary btn-sm\" data-action=\"save-file\">\ud83d\udcbe Save file<\/button>` : ''}<!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->          <\/div>\n<p><!-- [et_pb_line_break_holder] -->          <\/p>\n<div class=\"ed-meta\">${this.techPills(meta)}<span class=\"ed-chg${dirty ? ' show' : ''}\">\u25cf ${dirty} unsaved change${dirty > 1 ? 's' : ''}<\/span><\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/div>\n<p><!-- [et_pb_line_break_holder] -->        <\/p>\n<div class=\"ed-body\"><!-- [et_pb_line_break_holder] -->          ${editable ? '' : `<\/p>\n<div class=\"ro-banner\">\ud83d\udd12 ${esc(meta.fileType.toUpperCase())} files are view-only here: tags can be read but not written in the browser. Editing is available for MP3 and WAV.<\/div>\n<p>`}<!-- [et_pb_line_break_holder] -->          ${sections}<!-- [et_pb_line_break_holder] -->        <\/div>\n<p>`;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    visibleFields() {<!-- [et_pb_line_break_holder] -->      const set = new Set();<!-- [et_pb_line_break_holder] -->      this.metas.forEach(m => Object.keys(m.tags).forEach(k => set.add(k)));<!-- [et_pb_line_break_holder] -->      const ordered = [...FIELD_ORDER.filter(f => set.has(f)), ...Array.from(set).filter(f => !GROUP_FIELDS.has(f)).sort()];<!-- [et_pb_line_break_holder] -->      return this.query ? ordered.filter(f => f.toLowerCase().includes(this.query)) : ordered;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    renderTable() {<!-- [et_pb_line_break_holder] -->      const fields = this.visibleFields();<!-- [et_pb_line_break_holder] -->      const head = `<\/p>\n<th class=\"sticky-col\">File<\/th>\n<p>` + fields.map(f => `<\/p>\n<th>${esc(f)}<\/th>\n<p>`).join('');<!-- [et_pb_line_break_holder] -->      const rows = this.metas.map(m => {<!-- [et_pb_line_break_holder] -->        const editable = this.isEditable(m);<!-- [et_pb_line_break_holder] -->        const cells = fields.map(f => {<!-- [et_pb_line_break_holder] -->          if (!(f in m.tags)) return `<\/p>\n<td class=\"na\" title=\"Not supported by ${esc(m.fileType.toUpperCase())}\">\u2014<\/td>\n<p>`;<!-- [et_pb_line_break_holder] -->          const mod = this.isModified(m, f);<!-- [et_pb_line_break_holder] -->          return `<\/p>\n<td><input type=\"text\" class=\"cell${mod ? ' modified' : ''}\" data-id=\"${m.id}\" data-field=\"${esc(f)}\" value=\"${esc(this.getValue(m, f))}\" placeholder=\"${esc(PLACEHOLDERS[f] || '')}\"${editable ? '' : ' disabled title=\"Read-only format\"'}><\/td>\n<p>`;<!-- [et_pb_line_break_holder] -->        }).join('');<!-- [et_pb_line_break_holder] -->        return `<\/p>\n<tr data-id=\"${m.id}\" class=\"${m.id === this.activeId ? 'active' : ''}${this.dirtyCount(m) ? ' tr-dirty' : ''}\"><!-- [et_pb_line_break_holder] -->          <\/p>\n<td class=\"sticky-col\"><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"fc\"><!-- [et_pb_line_break_holder] -->              <span class=\"badge badge-${esc(m.fileType)}\">${esc(m.fileType)}<\/span><!-- [et_pb_line_break_holder] -->              <button type=\"button\" class=\"fc-name\" data-action=\"open\" data-id=\"${m.id}\" title=\"Open ${esc(m.fileName)} in the editor\">${esc(m.fileName)}<\/button><!-- [et_pb_line_break_holder] -->              <button type=\"button\" class=\"ic\" data-action=\"save-file\" data-id=\"${m.id}\" title=\"Save this file\" ${editable ? '' : 'disabled'}>\ud83d\udcbe<\/button><!-- [et_pb_line_break_holder] -->              <button type=\"button\" class=\"ic\" data-action=\"remove\" data-id=\"${m.id}\" title=\"Remove from list\">\u274c<\/button><!-- [et_pb_line_break_holder] -->            <\/div>\n<p><!-- [et_pb_line_break_holder] -->            <\/p>\n<div class=\"fc-sub\">${esc(this.techSummary(m))}<\/div>\n<p><!-- [et_pb_line_break_holder] -->          <\/td>\n<p>${cells}<\/tr>\n<p>`;<!-- [et_pb_line_break_holder] -->      }).join('');<!-- [et_pb_line_break_holder] -->      this.main.innerHTML = `<\/p>\n<div class=\"tbl-wrap\">\n<table class=\"tbl\">\n<thead>\n<tr>${head}<\/tr>\n<\/thead>\n<tbody>${rows}<\/tbody>\n<\/table>\n<\/div>\n<p>`;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Navigation \/ view<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    select(id) {<!-- [et_pb_line_break_holder] -->      if (id === this.activeId) return;<!-- [et_pb_line_break_holder] -->      this.activeId = id;<!-- [et_pb_line_break_holder] -->      this.renderSidebar(); this.renderMain(false);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    step(dir) {<!-- [et_pb_line_break_holder] -->      const i = this.metas.findIndex(m => m.id === this.activeId);<!-- [et_pb_line_break_holder] -->      const j = Math.max(0, Math.min(this.metas.length - 1, i + dir));<!-- [et_pb_line_break_holder] -->      if (j !== i && this.metas[j]) this.select(this.metas[j].id);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    setView(v) {<!-- [et_pb_line_break_holder] -->      this.view = v;<!-- [et_pb_line_break_holder] -->      this.workspace.classList.toggle('view-table', v === 'table');<!-- [et_pb_line_break_holder] -->      this.root.querySelectorAll('#viewSeg button').forEach(b => b.classList.toggle('on', b.dataset.view === v));<!-- [et_pb_line_break_holder] -->      this.renderSidebar(); this.renderMain(false);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    removeFile(id) {<!-- [et_pb_line_break_holder] -->      const m = this.byId(id); if (!m) return;<!-- [et_pb_line_break_holder] -->      if (!confirm(`Remove \"${m.fileName}\" from the list?` + (this.dirtyCount(m) ? '\\n\\nIts unsaved changes will be lost.' : ''))) return;<!-- [et_pb_line_break_holder] -->      const i = this.metas.indexOf(m);<!-- [et_pb_line_break_holder] -->      this.metas.splice(i, 1);<!-- [et_pb_line_break_holder] -->      if (!this.metas.length) { this.resetState(); this.showStatus('File removed from list'); return; }<!-- [et_pb_line_break_holder] -->      if (this.activeId === id) this.activeId = this.metas[Math.max(0, i - 1)].id;<!-- [et_pb_line_break_holder] -->      this.renderAll();<!-- [et_pb_line_break_holder] -->      this.showStatus('File removed from list');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    reset() {<!-- [et_pb_line_break_holder] -->      if (this.metas.length && !confirm('Reset session? All unsaved changes will be lost.')) return;<!-- [et_pb_line_break_holder] -->      this.resetState(); this.showStatus('Session reset successfully');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    resetState() {<!-- [et_pb_line_break_holder] -->      if (this.isFullscreen) this.exitFullscreen();<!-- [et_pb_line_break_holder] -->      this.metas = []; this.activeId = null; this.query = ''; this.search.value = '';<!-- [et_pb_line_break_holder] -->      this.fileInput.value = ''; this.main.innerHTML = ''; this.fileList.innerHTML = '';<!-- [et_pb_line_break_holder] -->      this.setView('editor'); this.refreshChrome();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 Fullscreen (whole app) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    toggleFullscreen() { this.isFullscreen ? this.exitFullscreen() : this.enterFullscreen(); }<!-- [et_pb_line_break_holder] -->    enterFullscreen() {<!-- [et_pb_line_break_holder] -->      if (this.isFullscreen || !this.metas.length) return;<!-- [et_pb_line_break_holder] -->      this.isFullscreen = true;<!-- [et_pb_line_break_holder] -->      this.root.classList.add('is-fs');<!-- [et_pb_line_break_holder] -->      document.documentElement.classList.add('mde-lock');<!-- [et_pb_line_break_holder] -->      try { const p = this.root.requestFullscreen && this.root.requestFullscreen(); if (p && p.catch) p.catch(() => {}); } catch (e) {}<!-- [et_pb_line_break_holder] -->      this.updateFsBtn();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    exitFullscreen() {<!-- [et_pb_line_break_holder] -->      if (!this.isFullscreen) return;<!-- [et_pb_line_break_holder] -->      this.isFullscreen = false;<!-- [et_pb_line_break_holder] -->      this.root.classList.remove('is-fs');<!-- [et_pb_line_break_holder] -->      document.documentElement.classList.remove('mde-lock');<!-- [et_pb_line_break_holder] -->      try { if (document.fullscreenElement) { const p = document.exitFullscreen(); if (p && p.catch) p.catch(() => {}); } } catch (e) {}<!-- [et_pb_line_break_holder] -->      this.updateFsBtn();<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    updateFsBtn() {<!-- [et_pb_line_break_holder] -->      this.$('#fullscreenBtn').innerHTML = this.isFullscreen ? '\u2715 <span class=\"hide-sm\">Exit fullscreen<\/span>' : '\u26f6 <span class=\"hide-sm\">Fullscreen<\/span>';<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    \/\/  Saving<!-- [et_pb_line_break_holder] -->    \/\/ \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550<!-- [et_pb_line_break_holder] -->    showSaveModal(target) {<!-- [et_pb_line_break_holder] -->      const body = this.$('#saveModalBody');<!-- [et_pb_line_break_holder] -->      const nameOf = n => { const p = n.split('.'); const e = p.pop(); return `${p.join('.')}_me.${e}`; };<!-- [et_pb_line_break_holder] -->      let list;<!-- [et_pb_line_break_holder] -->      if (target === 'all') {<!-- [et_pb_line_break_holder] -->        list = this.metas.filter(m => this.isEditable(m) && this.dirtyCount(m));<!-- [et_pb_line_break_holder] -->        if (!list.length) { this.showStatus('No unsaved changes to export', 'warning'); return; }<!-- [et_pb_line_break_holder] -->      } else {<!-- [et_pb_line_break_holder] -->        const m = this.byId(target); if (!m || !this.isEditable(m)) return;<!-- [et_pb_line_break_holder] -->        list = [m];<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      this.pendingSave = target;<!-- [et_pb_line_break_holder] -->      const hasMp3 = list.some(m => m.fileType === 'mp3');<!-- [et_pb_line_break_holder] -->      body.innerHTML = `<!-- [et_pb_line_break_holder] -->        <pee>${list.length === 1 ? 'This file' : `These ${list.length} files`} will be downloaded with the updated metadata. Your originals are never modified.<\/pee><!-- [et_pb_line_break_holder] -->        <\/p>\n<ul>${list.map(m => `<\/p>\n<li>${esc(nameOf(m.fileName))}<\/li>\n<p>`).join('')}<\/ul>\n<p><!-- [et_pb_line_break_holder] -->        ${list.length > 1 ? '<pee class=\"note\">Your browser may ask permission to download multiple files.<\/pee>' : ''}<!-- [et_pb_line_break_holder] -->        ${hasMp3 ? '<pee class=\"note\">MP3: the ID3 tag is rewritten from the fields shown here (embedded artwork and other custom frames are not preserved).<\/pee>' : ''}`;<!-- [et_pb_line_break_holder] -->      this.saveModal.classList.add('show');<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    closeSaveModal() { this.saveModal.classList.remove('show'); }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async executeSave() {<!-- [et_pb_line_break_holder] -->      const target = this.pendingSave;<!-- [et_pb_line_break_holder] -->      this.closeSaveModal();<!-- [et_pb_line_break_holder] -->      const list = target === 'all'<!-- [et_pb_line_break_holder] -->        ? this.metas.filter(m => this.isEditable(m) && this.dirtyCount(m))<!-- [et_pb_line_break_holder] -->        : [this.byId(target)].filter(Boolean);<!-- [et_pb_line_break_holder] -->      if (!list.length) return;<!-- [et_pb_line_break_holder] -->      this.showStatus('Compiling\u2026');<!-- [et_pb_line_break_holder] -->      let ok = 0;<!-- [et_pb_line_break_holder] -->      for (const m of list) {<!-- [et_pb_line_break_holder] -->        if (await this.saveFile(m)) ok++;<!-- [et_pb_line_break_holder] -->        if (list.length > 1) await new Promise(r => setTimeout(r, 250));<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      this.renderMain(true); this.renderSidebar(); this.refreshChrome();<!-- [et_pb_line_break_holder] -->      if (ok) this.showStatus(ok === 1 ? 'File exported successfully!' : `Successfully exported ${ok} files!`);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    async saveFile(meta) {<!-- [et_pb_line_break_holder] -->      const updated = { ...meta.tags, ...meta.edits };<!-- [et_pb_line_break_holder] -->      let blob;<!-- [et_pb_line_break_holder] -->      try {<!-- [et_pb_line_break_holder] -->        blob = meta.fileType === 'mp3' ? await this.writeMP3Metadata(meta.file, updated) : await this.writeWAVMetadata(meta.file, updated);<!-- [et_pb_line_break_holder] -->      } catch (err) {<!-- [et_pb_line_break_holder] -->        this.showStatus(`Error saving ${meta.fileName}: ${err.message}`, 'error');<!-- [et_pb_line_break_holder] -->        return false;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      const parts = meta.fileName.split('.'); const ext = parts.pop();<!-- [et_pb_line_break_holder] -->      saveAs(blob, `${parts.join('.')}_me.${ext}`);<!-- [et_pb_line_break_holder] -->      meta.tags = updated; meta.edits = {};<!-- [et_pb_line_break_holder] -->      return true;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 MP3 \/ ID3v2.4 writer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    async writeMP3Metadata(file, tags) {<!-- [et_pb_line_break_holder] -->      const buf = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const view = new DataView(buf);<!-- [et_pb_line_break_holder] -->      let audioStart = 0;<!-- [et_pb_line_break_holder] -->      if (this.readString(view, 0, 3) === 'ID3') audioStart = 10 + this.readID3Size(view, 6);<!-- [et_pb_line_break_holder] -->      const audioData = new Uint8Array(buf.slice(audioStart));<!-- [et_pb_line_break_holder] -->      const id3Tag = this.createID3v2Tag(tags);<!-- [et_pb_line_break_holder] -->      const result = new Uint8Array(id3Tag.length + audioData.length);<!-- [et_pb_line_break_holder] -->      result.set(id3Tag, 0); result.set(audioData, id3Tag.length);<!-- [et_pb_line_break_holder] -->      return new Blob([result], { type: 'audio\/mpeg' });<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    createID3v2Tag(tags) {<!-- [et_pb_line_break_holder] -->      const frames = [];<!-- [et_pb_line_break_holder] -->      const mapping = { 'Title': 'TIT2', 'Artist': 'TPE1', 'Album': 'TALB', 'Year': 'TDRC', 'Genre': 'TCON', 'Track': 'TRCK', 'Comment': 'COMM', 'Album Artist': 'TPE2', 'Composer': 'TCOM', 'Copyright': 'TCOP', 'Publisher': 'TPUB', 'BPM': 'TBPM', 'ISRC\/Source Code': 'TSRC' };<!-- [et_pb_line_break_holder] -->      for (const [name, id] of Object.entries(mapping)) {<!-- [et_pb_line_break_holder] -->        if (tags[name] && tags[name].trim()) frames.push(id === 'COMM' ? this.createCOMMFrame(tags[name]) : this.createTextFrame(id, tags[name]));<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      let framesSize = 0; frames.forEach(f => framesSize += f.length);<!-- [et_pb_line_break_holder] -->      const header = new Uint8Array(10);<!-- [et_pb_line_break_holder] -->      header.set([0x49, 0x44, 0x33, 0x04, 0x00, 0x00], 0);<!-- [et_pb_line_break_holder] -->      this.writeSyncSafeInt(header, 6, framesSize);<!-- [et_pb_line_break_holder] -->      const tag = new Uint8Array(10 + framesSize);<!-- [et_pb_line_break_holder] -->      tag.set(header, 0);<!-- [et_pb_line_break_holder] -->      let off = 10; frames.forEach(f => { tag.set(f, off); off += f.length; });<!-- [et_pb_line_break_holder] -->      return tag;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    createTextFrame(id, text) {<!-- [et_pb_line_break_holder] -->      const tb = new TextEncoder().encode(text);<!-- [et_pb_line_break_holder] -->      const size = 1 + tb.length + 1;<!-- [et_pb_line_break_holder] -->      const frame = new Uint8Array(10 + size);<!-- [et_pb_line_break_holder] -->      frame.set([...id].map(c => c.charCodeAt(0)), 0);<!-- [et_pb_line_break_holder] -->      this.writeSyncSafeInt(frame, 4, size);<!-- [et_pb_line_break_holder] -->      frame[8] = 0; frame[9] = 0; frame[10] = 0x03;<!-- [et_pb_line_break_holder] -->      frame.set(tb, 11); frame[11 + tb.length] = 0;<!-- [et_pb_line_break_holder] -->      return frame;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    createCOMMFrame(text) {<!-- [et_pb_line_break_holder] -->      const tb = new TextEncoder().encode(text);<!-- [et_pb_line_break_holder] -->      const size = 1 + 3 + 1 + tb.length + 1;<!-- [et_pb_line_break_holder] -->      const frame = new Uint8Array(10 + size);<!-- [et_pb_line_break_holder] -->      frame.set([0x43, 0x4F, 0x4D, 0x4D], 0);<!-- [et_pb_line_break_holder] -->      this.writeSyncSafeInt(frame, 4, size);<!-- [et_pb_line_break_holder] -->      frame[8] = 0; frame[9] = 0; frame[10] = 0x03;<!-- [et_pb_line_break_holder] -->      frame.set([0x65, 0x6E, 0x67], 11); frame[14] = 0;<!-- [et_pb_line_break_holder] -->      frame.set(tb, 15); frame[15 + tb.length] = 0;<!-- [et_pb_line_break_holder] -->      return frame;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    readID3Size(view, o) {<!-- [et_pb_line_break_holder] -->      return ((view.getUint8(o) & 0x7F) << 21) | ((view.getUint8(o + 1) &#038; 0x7F) << 14) | ((view.getUint8(o + 2) &#038; 0x7F) << 7) | (view.getUint8(o + 3) &#038; 0x7F);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    writeSyncSafeInt(arr, off, val) {<!-- [et_pb_line_break_holder] -->      arr[off] = (val >> 21) & 0x7F; arr[off + 1] = (val >> 14) & 0x7F; arr[off + 2] = (val >> 7) & 0x7F; arr[off + 3] = val & 0x7F;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 WAV writer (BWF MetaEdit style) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    async writeWAVMetadata(file, tags) {<!-- [et_pb_line_break_holder] -->      const buf = await file.arrayBuffer();<!-- [et_pb_line_break_holder] -->      const view = new DataView(buf);<!-- [et_pb_line_break_holder] -->      const keep = [];<!-- [et_pb_line_break_holder] -->      let offset = 12;<!-- [et_pb_line_break_holder] -->      while (offset < buf.byteLength - 8) {<!-- [et_pb_line_break_holder] -->        const chunkId = this.readString(view, offset, 4);<!-- [et_pb_line_break_holder] -->        const chunkSize = view.getUint32(offset + 4, true);<!-- [et_pb_line_break_holder] -->        const padded = chunkSize + (chunkSize % 2);<!-- [et_pb_line_break_holder] -->        let k = true;<!-- [et_pb_line_break_holder] -->        if (chunkId === 'bext') k = false;<!-- [et_pb_line_break_holder] -->        if (chunkId === 'LIST' && this.readString(view, offset + 8, 4) === 'INFO') k = false;<!-- [et_pb_line_break_holder] -->        if (k) keep.push(new Uint8Array(buf.slice(offset, offset + 8 + padded)));<!-- [et_pb_line_break_holder] -->        offset += 8 + padded;<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      const info = this.createWAVINFOChunk(tags);<!-- [et_pb_line_break_holder] -->      const bext = this.createWAVBextChunk(tags);<!-- [et_pb_line_break_holder] -->      let total = 4;<!-- [et_pb_line_break_holder] -->      keep.forEach(c => total += c.length);<!-- [et_pb_line_break_holder] -->      if (info) total += info.length;<!-- [et_pb_line_break_holder] -->      if (bext) total += bext.length;<!-- [et_pb_line_break_holder] -->      const out = new Uint8Array(8 + total);<!-- [et_pb_line_break_holder] -->      const ov = new DataView(out.buffer);<!-- [et_pb_line_break_holder] -->      out.set([0x52, 0x49, 0x46, 0x46], 0); ov.setUint32(4, total, true);<!-- [et_pb_line_break_holder] -->      out.set([0x57, 0x41, 0x56, 0x45], 8);<!-- [et_pb_line_break_holder] -->      let w = 12;<!-- [et_pb_line_break_holder] -->      if (bext) { out.set(bext, w); w += bext.length; }<!-- [et_pb_line_break_holder] -->      keep.forEach(c => { out.set(c, w); w += c.length; });<!-- [et_pb_line_break_holder] -->      if (info) out.set(info, w);<!-- [et_pb_line_break_holder] -->      return new Blob([out], { type: 'audio\/wav' });<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    createWAVINFOChunk(tags) {<!-- [et_pb_line_break_holder] -->      const mapping = { 'Title': 'INAM', 'Artist': 'IART', 'Album': 'IPRD', 'Comment': 'ICMT', 'Creation Date': 'ICRD', 'Genre': 'IGNR', 'Copyright': 'ICOP', 'Software': 'ISFT', 'Subject': 'ISBJ', 'ISRC\/Source Code': 'ISRC' };<!-- [et_pb_line_break_holder] -->      const subs = [];<!-- [et_pb_line_break_holder] -->      for (const [name, id] of Object.entries(mapping)) {<!-- [et_pb_line_break_holder] -->        if (tags[name] && tags[name].trim()) {<!-- [et_pb_line_break_holder] -->          const tb = new TextEncoder().encode(tags[name]);<!-- [et_pb_line_break_holder] -->          const sz = tb.length + 1, pad = sz + (sz % 2);<!-- [et_pb_line_break_holder] -->          const c = new Uint8Array(8 + pad);<!-- [et_pb_line_break_holder] -->          c.set([...id].map(x => x.charCodeAt(0)), 0);<!-- [et_pb_line_break_holder] -->          new DataView(c.buffer).setUint32(4, sz, true);<!-- [et_pb_line_break_holder] -->          c.set(tb, 8); c[8 + tb.length] = 0;<!-- [et_pb_line_break_holder] -->          subs.push(c);<!-- [et_pb_line_break_holder] -->        }<!-- [et_pb_line_break_holder] -->      }<!-- [et_pb_line_break_holder] -->      if (!subs.length) return null;<!-- [et_pb_line_break_holder] -->      let listSz = 4; subs.forEach(c => listSz += c.length);<!-- [et_pb_line_break_holder] -->      const list = new Uint8Array(8 + listSz);<!-- [et_pb_line_break_holder] -->      list.set([0x4C, 0x49, 0x53, 0x54], 0);<!-- [et_pb_line_break_holder] -->      new DataView(list.buffer).setUint32(4, listSz, true);<!-- [et_pb_line_break_holder] -->      list.set([0x49, 0x4E, 0x46, 0x4F], 8);<!-- [et_pb_line_break_holder] -->      let off = 12; subs.forEach(c => { list.set(c, off); off += c.length; });<!-- [et_pb_line_break_holder] -->      return list;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->    createWAVBextChunk(tags) {<!-- [et_pb_line_break_holder] -->      const bwf = ['Description', 'Originator', 'Originator Reference', 'Origination Date', 'Origination Time'];<!-- [et_pb_line_break_holder] -->      if (!bwf.some(f => tags[f] && tags[f].trim())) return null;<!-- [et_pb_line_break_holder] -->      const sz = 602;<!-- [et_pb_line_break_holder] -->      const chunk = new Uint8Array(8 + sz);<!-- [et_pb_line_break_holder] -->      chunk.set([0x62, 0x65, 0x78, 0x74], 0);<!-- [et_pb_line_break_holder] -->      new DataView(chunk.buffer).setUint32(4, sz, true);<!-- [et_pb_line_break_holder] -->      const write = (str, off, len) => { const b = new TextEncoder().encode(str || ''); for (let i = 0; i < len; i++) chunk[8 + off + i] = i < b.length ? b[i] : 0; };<!-- [et_pb_line_break_holder] -->      write(tags['Description'], 0, 256);<!-- [et_pb_line_break_holder] -->      write(tags['Originator'], 256, 32);<!-- [et_pb_line_break_holder] -->      write(tags['Originator Reference'], 288, 32);<!-- [et_pb_line_break_holder] -->      write(tags['Origination Date'], 320, 10);<!-- [et_pb_line_break_holder] -->      write(tags['Origination Time'], 330, 8);<!-- [et_pb_line_break_holder] -->      new DataView(chunk.buffer).setUint16(8 + 346, 1, true);<!-- [et_pb_line_break_holder] -->      return chunk;<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->    \/\/ \u2500\u2500 Status toast \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500<!-- [et_pb_line_break_holder] -->    showStatus(message, type = 'success') {<!-- [et_pb_line_break_holder] -->      clearTimeout(this.statusTimer);<!-- [et_pb_line_break_holder] -->      this.statusEl.textContent = message;<!-- [et_pb_line_break_holder] -->      this.statusEl.className = 'status show' + (type === 'error' ? ' error' : type === 'warning' ? ' warning' : '');<!-- [et_pb_line_break_holder] -->      this.statusTimer = setTimeout(() => this.statusEl.classList.remove('show'), 3500);<!-- [et_pb_line_break_holder] -->    }<!-- [et_pb_line_break_holder] -->  }<!-- [et_pb_line_break_holder] --><!-- [et_pb_line_break_holder] -->  window.audioMetadataEditor = new AudioMetadataEditor(document.getElementById('mde'));<!-- [et_pb_line_break_holder] -->})();<!-- [et_pb_line_break_holder] --><\/script>[\/et_pb_code][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Hero Section&#8221; _builder_version=&#8221;4.27.5&#8243; background_color=&#8221;#000000&#8243; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_stops=&#8221;#000000 0%|rgba(0,0,0,0) 20%|rgba(0,0,0,0) 80%|#000000 100%&#8221; background_color_gradient_overlays_image=&#8221;on&#8221; background_image=&#8221;https:\/\/smartdsp.pro\/wp-content\/uploads\/2022\/10\/streamer-79.png&#8221; custom_padding=&#8221;9px|||1px||&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row _builder_version=&#8221;4.27.5&#8243; background_size=&#8221;initial&#8221; background_position=&#8221;top_left&#8221; background_repeat=&#8221;repeat&#8221; module_alignment=&#8221;center&#8221; custom_margin=&#8221;4vw||||false|false&#8221; custom_width_px=&#8221;700px&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_text _builder_version=&#8221;4.16&#8243; text_font=&#8221;||||||||&#8221; text_font_size=&#8221;18px&#8221; text_line_height=&#8221;2em&#8221; header_font=&#8221;Titillium Web||||||||&#8221; header_font_size=&#8221;66px&#8221; header_line_height=&#8221;1.5em&#8221; header_2_font=&#8221;Titillium Web||||||||&#8221; header_2_font_size=&#8221;66px&#8221; header_2_line_height=&#8221;1.5em&#8221; header_3_font=&#8221;Titillium Web||||||||&#8221; header_3_font_size=&#8221;66px&#8221; header_3_line_height=&#8221;1.5em&#8221; header_4_font=&#8221;Titillium Web||||||||&#8221; header_4_font_size=&#8221;66px&#8221; header_4_line_height=&#8221;1.5em&#8221; header_5_font=&#8221;Titillium Web||||||||&#8221; header_5_font_size=&#8221;66px&#8221; header_5_line_height=&#8221;1.5em&#8221; header_6_font=&#8221;Titillium Web||||||||&#8221; header_6_font_size=&#8221;66px&#8221; header_6_line_height=&#8221;1.5em&#8221; text_orientation=&#8221;center&#8221; background_layout=&#8221;dark&#8221; max_width=&#8221;700px&#8221; module_alignment=&#8221;center&#8221; header_font_size_tablet=&#8221;40px&#8221; header_font_size_phone=&#8221;&#8221; header_font_size_last_edited=&#8221;on|phone&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h1>Frequently Asked<\/h1>\n<p>[\/et_pb_text][et_pb_code _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_code][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_2,1_2&#8243; custom_padding_last_edited=&#8221;on|desktop&#8221; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;default&#8221; background_color=&#8221;rgba(79,79,79,0.16)&#8221; overflow-x=&#8221;visible&#8221; overflow-y=&#8221;visible&#8221; custom_padding=&#8221;80px|80px|80px|80px|true|true&#8221; custom_padding_tablet=&#8221;30px|30px|30px|30px|true|true&#8221; custom_padding_phone=&#8221;20px|20px|20px|20px|true|true&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_horizontal=&#8221;-1px&#8221; box_shadow_vertical=&#8221;-1px&#8221; box_shadow_blur=&#8221;0px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.21)&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding_tablet=&#8221;||||false|false&#8221; custom_padding_phone=&#8221;||30px||false|false&#8221; custom_padding_last_edited=&#8221;off|phone&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;How to view\/EDIT Metadata of audio file(s) with this tool?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<div class=\"faq-item\">\n<ol>\n<li class=\"faq-answer\">Drag &amp; Drop (or click to Browse) to import audio file(s)<\/li>\n<li class=\"faq-answer\">You&#8217;ll instantly see the metadata for each file loaded.<\/li>\n<li class=\"faq-answer\">Edit if desired (see how below)<\/li>\n<li class=\"faq-answer\">Save edited metadata (either overwrite file(s) or to a new one)<\/li>\n<\/ol>\n<p><strong>Options:<\/strong><\/p>\n<ul>\n<li class=\"faq-answer\">Double click a field to edit it<\/li>\n<li class=\"faq-answer\">Right click a field to Clear value OR Paste value to all other files<\/li>\n<li class=\"faq-answer\">Add\/remove files with the dedicated icons and buttons.<\/li>\n<li class=\"faq-answer\">Filter fields with the search bar<\/li>\n<\/ul>\n<\/div>\n<div class=\"faq-item\"><\/div>\n<p>[\/et_pb_blurb][et_pb_blurb title=&#8221;Is this Metadata Editor safe to use?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; animation_delay=&#8221;100ms&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<div class=\"faq-item\">\n<div class=\"faq-answer\">\n<p>Absolutely. Your audio files never leave your device. Everything happens 100% locally in your browser. Your files remain completely private and secure on your computer. We don&#8217;t collect, store, or have any access to your audio files whatsoever.<\/p>\n<p>Additionally this tool does not process the audio data of your files in any way when you save edited metadata, making the process not only 100% transparent but also faster.<\/p>\n<\/div>\n<\/div>\n<div class=\"faq-item\"><\/div>\n<p>[\/et_pb_blurb][et_pb_blurb title=&#8221;Do I need to install any software to use this Metadata Viewer\/Editor?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; animation_delay=&#8221;100ms&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<div class=\"faq-item\">\n<div class=\"faq-answer\"><span>No installation required (and no account neither!)<br \/>This is a completely free and web-based tool that runs directly in your browser. <\/span><\/div>\n<div class=\"faq-answer\"><span><\/span><\/div>\n<div class=\"faq-answer\">It works on any modern browser (Chrome, Firefox, Safari, Edge) on Windows, Mac, Linux, and even mobile devices. Just open the page and import audio files to view and eventually edit their metadata, no downloads, no plugins, no registration needed.<span><\/span><\/div>\n<\/div>\n<div class=\"faq-item\"><\/div>\n<p>[\/et_pb_blurb][\/et_pb_column][et_pb_column type=&#8221;1_2&#8243; _builder_version=&#8221;4.17.4&#8243; _module_preset=&#8221;default&#8221; custom_padding_tablet=&#8221;|||0%|false|false&#8221; custom_padding_phone=&#8221;|||0%|false|false&#8221; custom_padding_last_edited=&#8221;off|desktop&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_blurb title=&#8221;What are Metadata?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; animation_delay=&#8221;250ms&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<div class=\"faq-item\">\n<div class=\"faq-answer\">\n<p>Metadata are different information embedded within a file either a picture, video, audio file or else. They allow to store various information about the file such as its date of creation, creator name, length, name and more directly within the file.<\/p>\n<p>In the music industry context, they allow to track artist &amp; copyright information by tagging directly into the audio files informations such as Artist, Track, Album, Genre, Involved People, ISRC code\u2026<\/p>\n<p>The most common<strong><span>\u00a0<\/span>types of metadata retained in audio formats<\/strong><span>\u00a0<\/span>are: IDv3, ID3v2, Riff, Bwf, Cart, AXML, IXML, XMP.<\/p>\n<p>For more information read <a href=\"https:\/\/smartdsp.pro\/mastering-metadata\/\" target=\"_blank\" rel=\"noopener\">this article I wrote about Audio Metadata<\/a>. <a href=\"https:\/\/smartdsp.pro\/mastering-metadata\/\"><\/a>\u00a0<\/p>\n<\/div>\n<\/div>\n<p>[\/et_pb_blurb][et_pb_blurb title=&#8221;How long is it to save edited metadata?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; animation_delay=&#8221;150ms&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>Under a few seconds, pretty much instantly after you click the save button.<\/p>\n<p>[\/et_pb_blurb][et_pb_blurb title=&#8221;METADATA IN WAV FILE?&#8221; use_icon=&#8221;on&#8221; font_icon=&#8221;&#x75;||divi||400&#8243; icon_color=&#8221;#f3be29&#8243; icon_placement=&#8221;left&#8221; _builder_version=&#8221;4.27.5&#8243; header_font=&#8221;&#8211;et_global_heading_font|700||on|||||&#8221; header_font_size=&#8221;14px&#8221; header_letter_spacing=&#8221;2px&#8221; header_line_height=&#8221;1.8em&#8221; body_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; body_text_color=&#8221;#FFFFFF&#8221; body_font_size=&#8221;16px&#8221; body_line_height=&#8221;1.8em&#8221; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_direction=&#8221;164deg&#8221; background_color_gradient_stops=&#8221;rgba(243,190,41,0.17) 0%|rgba(205,59,167,0.17) 100%&#8221; background_layout=&#8221;dark&#8221; custom_margin=&#8221;||12%|&#8221; custom_margin_tablet=&#8221;70px|||&#8221; custom_margin_last_edited=&#8221;off|desktop&#8221; custom_padding=&#8221;30px|16px|30px|16px&#8221; animation_style=&#8221;fold&#8221; animation_delay=&#8221;100ms&#8221; border_radii=&#8221;on|20px|20px|20px|20px&#8221; box_shadow_style=&#8221;preset1&#8243; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<div class=\"faq-item\">\n<div class=\"faq-answer\">\n<p><span>Contrary to the common belief, it is possible to embed metadata in Wav files thanks to the Bradcast Wav File (Bwf) extension. ISRC code can also be embedded in to the AXML chunk of the file.<\/span><br \/><span>This data isn\u2019t read by all media players, but it might tomorrow. <\/span><\/p>\n<p>At\u00a0<a href=\"https:\/\/smartdsp.pro\/\">Smart DSP<\/a><span> we ensure proper embedding of all your information, including artwork and are happy to future proof your wav files by being able to tag the data into them as well.<\/span><\/p>\n<\/div>\n<\/div>\n<p>[\/et_pb_blurb][\/et_pb_column][\/et_pb_row][et_pb_row _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;4_4&#8243; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_heading title=&#8221;We&#8217;ve much more for you to explore:&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;default&#8221; title_level=&#8221;h2&#8243; title_font=&#8221;&#8211;et_global_heading_font||||||||&#8221; title_text_color=&#8221;#FFFFFF&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_heading][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_4,1_4,1_4,1_4&#8243; _builder_version=&#8221;4.18.0&#8243; custom_margin=&#8221;1vw|auto||auto|false|false&#8221; animation_style=&#8221;flip&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.18.0&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/smartdsp.pro\/mastering-services&#8221; button_text=&#8221;Mastering&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;3117bc07-6a8a-4679-b3bb-b6ed74b48a2f&#8221; custom_button=&#8221;on&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_bg_enable_color__hover=&#8221;on&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_border_radius__hover=&#8221;15px&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.18.0&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/smartdsp.pro\/smart-dsp-products\/&#8221; button_text=&#8221;Audio Effects&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.4&#8243; _module_preset=&#8221;3117bc07-6a8a-4679-b3bb-b6ed74b48a2f&#8221; custom_button=&#8221;on&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_bg_enable_color__hover=&#8221;on&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_border_radius__hover=&#8221;15px&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.18.0&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/www.patreon.com\/posts\/how-to-get-most-96445637&#8243; url_new_window=&#8221;on&#8221; button_text=&#8221;Learning&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;3117bc07-6a8a-4679-b3bb-b6ed74b48a2f&#8221; custom_button=&#8221;on&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_bg_enable_color__hover=&#8221;on&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_border_radius__hover=&#8221;15px&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.18.0&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/smartdsp.pro\/tools&#8221; button_text=&#8221;Online Tools&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.5&#8243; _module_preset=&#8221;3117bc07-6a8a-4679-b3bb-b6ed74b48a2f&#8221; custom_button=&#8221;on&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_bg_enable_color__hover=&#8221;on&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_border_radius__hover=&#8221;15px&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221;][\/et_pb_button][\/et_pb_column][\/et_pb_row][\/et_pb_section][et_pb_section fb_built=&#8221;1&#8243; admin_label=&#8221;Support&#8221; _builder_version=&#8221;4.18.0&#8243; background_enable_color=&#8221;off&#8221; use_background_color_gradient=&#8221;on&#8221; background_color_gradient_stops=&#8221;#000000 0%|rgba(41,196,169,0) 100%&#8221; background_color_gradient_overlays_image=&#8221;on&#8221; background_image=&#8221;https:\/\/smartdsp.pro\/wp-content\/uploads\/2022\/10\/footer-background-scaled-1.jpg&#8221; custom_padding=&#8221;100px|0px|100px|0px&#8221; locked=&#8221;off&#8221; global_colors_info=&#8221;{}&#8221;][et_pb_row column_structure=&#8221;3_5,2_5&#8243; _builder_version=&#8221;4.16&#8243; global_colors_info=&#8221;{}&#8221;][et_pb_column type=&#8221;3_5&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;40px||40px|&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_text _builder_version=&#8221;4.18.0&#8243; text_font=&#8221;PT Sans|700|||||||&#8221; text_text_color=&#8221;#00B22D&#8221; text_font_size=&#8221;22px&#8221; header_font=&#8221;||||||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<p>FEEDBACK, ANSWERS, HELP WITH TROUBLESHOOTING<\/p>\n<p>[\/et_pb_text][et_pb_text _builder_version=&#8221;4.18.0&#8243; text_font=&#8221;PT Sans|700|||||||&#8221; text_text_color=&#8221;#FFFFFF&#8221; text_font_size=&#8221;18px&#8221; text_line_height=&#8221;1.8em&#8221; header_font=&#8221;||||||||&#8221; header_2_font=&#8221;Poppins|500|||||||&#8221; header_2_text_color=&#8221;#ffffff&#8221; header_2_font_size=&#8221;38px&#8221; header_2_line_height=&#8221;1.3em&#8221; header_3_font=&#8221;||||||||&#8221; header_4_font=&#8221;||||||||&#8221; global_colors_info=&#8221;{}&#8221;]<\/p>\n<h2>Available 7\/7<\/h2>\n<p>You want some feedback on your project, you have some audio related question or even need some help troubleshooting something?<br \/>Don&#8217;t wait any longer, hit us up!<\/p>\n<p>[\/et_pb_text][\/et_pb_column][et_pb_column type=&#8221;2_5&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_image src=&#8221;https:\/\/smartdsp.pro\/wp-content\/uploads\/2020\/07\/finance-illustration-03.png&#8221; title_text=&#8221;finance-illustration-03&#8243; align=&#8221;center&#8221; align_tablet=&#8221;center&#8221; align_phone=&#8221;&#8221; align_last_edited=&#8221;on|desktop&#8221; disabled_on=&#8221;on|on|off&#8221; _builder_version=&#8221;4.16&#8243; width=&#8221;40%&#8221; custom_margin=&#8221;45px|||||&#8221; animation_style=&#8221;slide&#8221; animation_direction=&#8221;bottom&#8221; animation_intensity_slide=&#8221;10%&#8221; global_colors_info=&#8221;{}&#8221;][\/et_pb_image][\/et_pb_column][\/et_pb_row][et_pb_row column_structure=&#8221;1_4,1_4,1_4,1_4&#8243; _builder_version=&#8221;4.27.4&#8243; global_colors_info=&#8221;{}&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_border_radius__hover=&#8221;15px&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221;][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;40px||40px|&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/smartdsp.pro\/get-feedback&#8221; url_new_window=&#8221;on&#8221; button_text=&#8221;Get some feedback&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.4&#8243; custom_button=&#8221;on&#8221; button_text_size=&#8221;18px&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_one_text_size__hover_enabled=&#8221;off&#8221; button_two_text_size__hover_enabled=&#8221;off&#8221; button_text_color__hover_enabled=&#8221;off&#8221; button_one_text_color__hover_enabled=&#8221;off&#8221; button_two_text_color__hover_enabled=&#8221;off&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_one_border_width__hover_enabled=&#8221;off&#8221; button_two_border_width__hover_enabled=&#8221;off&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_one_border_color__hover_enabled=&#8221;off&#8221; button_two_border_color__hover_enabled=&#8221;off&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; button_one_border_radius__hover_enabled=&#8221;off&#8221; button_two_border_radius__hover_enabled=&#8221;off&#8221; button_letter_spacing__hover_enabled=&#8221;off&#8221; button_one_letter_spacing__hover_enabled=&#8221;off&#8221; button_two_letter_spacing__hover_enabled=&#8221;off&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_one_bg_color__hover_enabled=&#8221;off&#8221; button_two_bg_color__hover_enabled=&#8221;off&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_radius__hover=&#8221;15px&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover=&#8221;18px&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][et_pb_button button_url=&#8221;https:\/\/smartdsp.pro\/contact&#8221; url_new_window=&#8221;on&#8221; button_text=&#8221;I have a question&#8221; button_alignment=&#8221;center&#8221; _builder_version=&#8221;4.27.4&#8243; custom_button=&#8221;on&#8221; button_text_size=&#8221;18px&#8221; button_text_color=&#8221;#FFFFFF&#8221; button_bg_use_color_gradient=&#8221;on&#8221; button_bg_color_gradient_direction=&#8221;229deg&#8221; button_bg_color_gradient_stops=&#8221;rgba(189,22,179,0.8) 0%|rgba(253,202,65,0.8) 100%&#8221; button_border_width=&#8221;0px&#8221; button_border_radius=&#8221;15px&#8221; button_font=&#8221;Be Vietnam Pro|600|||||||&#8221; button_use_icon=&#8221;off&#8221; box_shadow_style=&#8221;preset1&#8243; box_shadow_blur=&#8221;35px&#8221; box_shadow_spread=&#8221;-11px&#8221; box_shadow_color=&#8221;rgba(255,255,255,0.28)&#8221; global_colors_info=&#8221;{}&#8221; button_text_size__hover_enabled=&#8221;on|desktop&#8221; button_one_text_size__hover_enabled=&#8221;off&#8221; button_two_text_size__hover_enabled=&#8221;off&#8221; button_text_color__hover_enabled=&#8221;off&#8221; button_one_text_color__hover_enabled=&#8221;off&#8221; button_two_text_color__hover_enabled=&#8221;off&#8221; button_border_width__hover_enabled=&#8221;on|desktop&#8221; button_one_border_width__hover_enabled=&#8221;off&#8221; button_two_border_width__hover_enabled=&#8221;off&#8221; button_border_color__hover_enabled=&#8221;on|hover&#8221; button_one_border_color__hover_enabled=&#8221;off&#8221; button_two_border_color__hover_enabled=&#8221;off&#8221; button_border_radius__hover_enabled=&#8221;on|desktop&#8221; button_one_border_radius__hover_enabled=&#8221;off&#8221; button_two_border_radius__hover_enabled=&#8221;off&#8221; button_letter_spacing__hover_enabled=&#8221;off&#8221; button_one_letter_spacing__hover_enabled=&#8221;off&#8221; button_two_letter_spacing__hover_enabled=&#8221;off&#8221; button_bg_color__hover_enabled=&#8221;on|desktop&#8221; button_one_bg_color__hover_enabled=&#8221;off&#8221; button_two_bg_color__hover_enabled=&#8221;off&#8221; button_bg_color__hover=&#8221;rgba(0,127,31,0.7)&#8221; button_border_width__hover=&#8221;0px&#8221; button_border_radius__hover=&#8221;15px&#8221; box_shadow_color__hover=&#8221;rgba(255,255,255,0.49)&#8221; box_shadow_color__hover_enabled=&#8221;on|hover&#8221; button_border_color__hover=&#8221;rgba(255,255,255,0.02)&#8221; button_icon_color__hover=&#8221;#FFFFFF&#8221; button_icon_color__hover_enabled=&#8221;on|hover&#8221; button_text_size__hover=&#8221;18px&#8221;][\/et_pb_button][\/et_pb_column][et_pb_column type=&#8221;1_4&#8243; _builder_version=&#8221;4.16&#8243; custom_padding=&#8221;|||&#8221; global_colors_info=&#8221;{}&#8221; custom_padding__hover=&#8221;|||&#8221;][\/et_pb_column][\/et_pb_row][\/et_pb_section]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>View and Edit Metadata of Audio Files for Free, in your browser. Ad-free, No Account Required, No Data Shared. Edit WAV metadata, Edit MP3 metadata.<\/p>","protected":false},"author":392,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_et_pb_use_builder":"on","_et_pb_old_content":"","_et_gb_content_width":"","footnotes":""},"class_list":["post-4584","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/pages\/4584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/users\/392"}],"replies":[{"embeddable":true,"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/comments?post=4584"}],"version-history":[{"count":19,"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/pages\/4584\/revisions"}],"predecessor-version":[{"id":5213,"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/pages\/4584\/revisions\/5213"}],"wp:attachment":[{"href":"https:\/\/smartdsp.pro\/fr\/wp-json\/wp\/v2\/media?parent=4584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}