diff --git a/README.md b/README.md index 393c1734..18bb57f1 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,7 @@ cargo install --git https://github.com/hykilpikonna/hyfetch **✨ Features & Enhancements** * Added `berrisexual` & `almondsexual` flags ([#545](https://github.com/hykilpikonna/hyfetch/issues/545)). +* Added 6-color lambda support for NixOS logo ([#543](https://github.com/hykilpikonna/hyfetch/issues/543)). * Published crate to crates.io with automated OIDC publishing ([#544](https://github.com/hykilpikonna/hyfetch/issues/544)). **🐛 Bug Fixes** diff --git a/crates/hyfetch/src/ascii.rs b/crates/hyfetch/src/ascii.rs index 6252d2b5..6d9061c9 100644 --- a/crates/hyfetch/src/ascii.rs +++ b/crates/hyfetch/src/ascii.rs @@ -1,4 +1,5 @@ use std::borrow::Cow; +use std::collections::BTreeSet; use std::fmt::Write as _; use std::ops::Range; @@ -107,10 +108,7 @@ pub fn get_random_alignment(preset: &ColorProfile, asc: &NormalizedAsciiArt) -> let mut rng = fastrand::Rng::new(); rng.shuffle(&mut preset_indices); - let colors = slots - .into_iter() - .zip(preset_indices) - .collect(); + let colors = slots.into_iter().zip(preset_indices).collect(); ColorAlignment::Custom { colors } } @@ -362,6 +360,21 @@ impl NormalizedAsciiArt { .fill_starting() .context("failed to fill in starting neofetch color codes")?; + let slots: BTreeSet = { + let asc = lines.join("\n"); + let ac = NEOFETCH_COLORS_AC + .get_or_init(|| AhoCorasick::new(NEOFETCH_COLOR_PATTERNS).unwrap()); + ac.find_iter(&asc) + .map(|m| { + let ai_start = m.start().checked_add(3).unwrap(); + let ai_end = m.end().checked_sub(1).unwrap(); + asc[ai_start..ai_end] + .parse() + .expect("neofetch ascii color index should not be invalid") + }) + .collect() + }; + let ColorProfile { colors } = color_profile.unique_colors(); // Apply colors @@ -371,13 +384,33 @@ impl NormalizedAsciiArt { .get_or_init(|| AhoCorasick::new(NEOFETCH_COLOR_PATTERNS).unwrap()); const N: usize = NEOFETCH_COLOR_PATTERNS.len(); let mut replacements = vec![Cow::from(""); N]; - for (&ai, &pi) in custom_colors { - let ai: u8 = ai.into(); - let pi: u8 = pi.into(); - replacements[usize::from(ai.checked_sub(1).unwrap())] = colors - [usize::from(pi)] - .to_ansi_string(color_mode, ForegroundBackground::Foreground) - .into(); + if !colors.is_empty() { + for (&ai, &pi) in custom_colors { + let ai: u8 = ai.into(); + let pi: u8 = pi.into(); + let color = &colors[usize::from(pi) % colors.len()]; + replacements[usize::from(ai.checked_sub(1).unwrap())] = color + .to_ansi_string(color_mode, ForegroundBackground::Foreground) + .into(); + } + // Fallback for slots in the art that aren't in custom_colors (e.g. backward compat) + for &ai in &slots { + let ai_u8: u8 = ai.into(); + let idx = usize::from(ai_u8.checked_sub(1).unwrap()); + if replacements[idx].is_empty() { + let fallback_slot = + NeofetchAsciiIndexedColor::try_from((ai_u8 - 1) % 2 + 1) + .unwrap(); + let pi = custom_colors.get(&fallback_slot).copied().unwrap_or_else( + || (((ai_u8 - 1) as usize % colors.len()) as u8).into(), + ); + let pi_u8: u8 = pi.into(); + let color = &colors[usize::from(pi_u8) % colors.len()]; + replacements[idx] = color + .to_ansi_string(color_mode, ForegroundBackground::Foreground) + .into(); + } + } } ac.replace_all(&asc, &replacements) }; @@ -406,37 +439,37 @@ impl NormalizedAsciiArt { NEOFETCH_COLORS_AC.get_or_init(|| AhoCorasick::new(NEOFETCH_COLOR_PATTERNS).unwrap()); let mut last = None; - let lines = - self.lines - .iter() - .map(|line| { - let line: &str = line.as_ref(); + let lines = self + .lines + .iter() + .map(|line| { + let line: &str = line.as_ref(); - let mut new = String::new(); - let mut matches = ac.find_iter(line).peekable(); + let mut new = String::new(); + let mut matches = ac.find_iter(line).peekable(); - match matches.peek() { - Some(m) - if m.start() == 0 - || line[0..m.start()].trim_end_matches(' ').is_empty() => - { - // Line starts with neofetch color code - last = Some(&line[m.span()]); - }, - _ => { - new.push_str(last.unwrap_or(NEOFETCH_COLOR_PATTERNS[0])); - }, - } - new.push_str(line); - - // Get the last placeholder for the next line - if let Some(m) = matches.last() { + match matches.peek() { + Some(m) + if m.start() == 0 + || line[0..m.start()].trim_end_matches(' ').is_empty() => + { + // Line starts with neofetch color code last = Some(&line[m.span()]); - } + }, + _ => { + new.push_str(last.unwrap_or(NEOFETCH_COLOR_PATTERNS[0])); + }, + } + new.push_str(line); - Ok(new) - }) - .collect::>()?; + // Get the last placeholder for the next line + if let Some(m) = matches.last() { + last = Some(&line[m.span()]); + } + + Ok(new) + }) + .collect::>()?; Ok(Self { lines, @@ -445,4 +478,3 @@ impl NormalizedAsciiArt { }) } } - diff --git a/crates/hyfetch/src/bin/hyfetch.rs b/crates/hyfetch/src/bin/hyfetch.rs index 1183f04d..c342ad85 100644 --- a/crates/hyfetch/src/bin/hyfetch.rs +++ b/crates/hyfetch/src/bin/hyfetch.rs @@ -1319,7 +1319,7 @@ fn create_config( let asc = asc.lines.join("\n"); let ac = NEOFETCH_COLORS_AC.get_or_init(|| AhoCorasick::new(NEOFETCH_COLOR_PATTERNS).unwrap()); - ac.find_iter(&asc) + let mut v: Vec = ac.find_iter(&asc) .map(|m| { let ai_start = m.start().checked_add(3).unwrap(); let ai_end = m.end().checked_sub(1).unwrap(); @@ -1327,7 +1327,9 @@ fn create_config( .parse() .expect("neofetch ascii color index should not be invalid") }) - .collect() + .collect(); + v.sort(); + v.into_iter().collect() }; // Loop for random rolling @@ -1340,23 +1342,25 @@ fn create_config( while preset_indices.len() < slots.len() { preset_indices.extend_from_within(0..); } + let ordered_p: Vec = preset_indices[..slots.len()].to_vec(); let preset_index_permutations: IndexSet> = preset_indices .into_iter() .permutations(slots.len()) .take(1000) .collect(); let random_count = (ascii_per_row as usize * ascii_rows as usize).saturating_sub(arrangements.len()).clamp(0, u8::MAX.into()) as u8; - let choices: IndexSet> = - if usize::from(random_count) > preset_index_permutations.len() { - preset_index_permutations - } else { - rng.choose_multiple( - preset_index_permutations.into_iter(), - usize::from(random_count), - ) - .into_iter() - .collect() - }; + let other_permutations: IndexSet> = preset_index_permutations + .into_iter() + .filter(|p| p != &ordered_p) + .collect(); + let mut choices: IndexSet> = IndexSet::new(); + choices.insert(ordered_p); + let sample_count = (usize::from(random_count)).saturating_sub(1); + if sample_count >= other_permutations.len() { + choices.extend(other_permutations); + } else { + choices.extend(rng.choose_multiple(other_permutations.into_iter(), sample_count)); + } let choices: Vec> = choices .into_iter() .map(|c| { diff --git a/hyfetch/data/distros/nixos.ascii b/hyfetch/data/distros/nixos.ascii index 8c27c54c..84d6ebf3 100644 --- a/hyfetch/data/distros/nixos.ascii +++ b/hyfetch/data/distros/nixos.ascii @@ -1,21 +1,21 @@ -{"match": "\"NixOS\"*", "color": "4 6"} -${c1} ▗▄▄▄ ${c2}▗▄▄▄▄ ▄▄▄▖ -${c1} ▜███▙ ${c2}▜███▙ ▟███▛ -${c1} ▜███▙ ${c2}▜███▙▟███▛ -${c1} ▜███▙ ${c2}▜██████▛ -${c1} ▟█████████████████▙ ${c2}▜████▛ ${c1}▟▙ -${c1} ▟███████████████████▙ ${c2}▜███▙ ${c1}▟██▙ -${c2} ▄▄▄▄▖ ▜███▙ ${c1}▟███▛ -${c2} ▟███▛ ▜██▛ ${c1}▟███▛ -${c2} ▟███▛ ▜▛ ${c1}▟███▛ -${c2}▟███████████▛ ${c1}▟██████████▙ -${c2}▜██████████▛ ${c1}▟███████████▛ -${c2} ▟███▛ ${c1}▟▙ ▟███▛ -${c2} ▟███▛ ${c1}▟██▙ ▟███▛ -${c2} ▟███▛ ${c1}▜███▙ ▝▀▀▀▀ -${c2} ▜██▛ ${c1}▜███▙ ${c2}▜██████████████████▛ -${c2} ▜▛ ${c1}▟████▙ ${c2}▜████████████████▛ -${c1} ▟██████▙ ${c2}▜███▙ -${c1} ▟███▛▜███▙ ${c2}▜███▙ -${c1} ▟███▛ ▜███▙ ${c2}▜███▙ -${c1} ▝▀▀▀ ▀▀▀▀▘ ${c2}▀▀▀▘ \ No newline at end of file +{"match": "\"NixOS\"*", "color": "4 6 4 6 4 6"} +${c3} ▗▄▄▄ ${c4}▗▄▄▄▄ ▄▄▄▖ +${c3} ▜███▙ ${c4}▜███▙ ▟███▛ +${c3} ▜███▙ ${c4}▜███▙▟███▛ +${c3} ▜███▙ ${c4}▜██████▛ +${c3} ▟█████████████████▙ ${c4}▜████▛ ${c5}▟▙ +${c3} ▟███████████████████▙ ${c4}▜███▙ ${c5}▟██▙ +${c2} ▄▄▄▄▖ ${c4}▜███▙ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜██▛ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜▛ ${c5}▟███▛ +${c2}▟███████████▛ ${c5}▟██████████▙ +${c2}▜██████████▛ ${c5}▟███████████▛ +${c2} ▟███▛ ${c1}▟▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▟██▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▜███▙ ${c5}▝▀▀▀▀ +${c2} ▜██▛ ${c1}▜███▙ ${c6}▜██████████████████▛ +${c2} ▜▛ ${c1}▟████▙ ${c6}▜████████████████▛ +${c1} ▟██████▙ ${c6}▜███▙ +${c1} ▟███▛▜███▙ ${c6}▜███▙ +${c1} ▟███▛ ▜███▙ ${c6}▜███▙ +${c1} ▝▀▀▀ ▀▀▀▀▘ ${c6}▀▀▀▘ \ No newline at end of file diff --git a/hyfetch/data/distros/nixos_colorful.ascii b/hyfetch/data/distros/nixos_colorful.ascii index ab549978..e82d9bd3 100644 --- a/hyfetch/data/distros/nixos_colorful.ascii +++ b/hyfetch/data/distros/nixos_colorful.ascii @@ -1,21 +1,21 @@ {"match": "\"nixos_colorful\"*", "color": "4 6 4 6 4 6"} -${c1} ▗▄▄▄ ${c2}▗▄▄▄▄ ▄▄▄▖ -${c1} ▜███▙ ${c2}▜███▙ ▟███▛ -${c1} ▜███▙ ${c2}▜███▙▟███▛ -${c1} ▜███▙ ${c2}▜██████▛ -${c1} ▟█████████████████▙ ${c2}▜████▛ ${c3}▟▙ -${c1} ▟███████████████████▙ ${c2}▜███▙ ${c3}▟██▙ -${c6} ▄▄▄▄▖ ${c2}▜███▙ ${c3}▟███▛ -${c6} ▟███▛ ${c2}▜██▛ ${c3}▟███▛ -${c6} ▟███▛ ${c2}▜▛ ${c3}▟███▛ -${c6}▟███████████▛ ${c3}▟██████████▙ -${c6}▜██████████▛ ${c3}▟███████████▛ -${c6} ▟███▛ ${c5}▟▙ ${c3}▟███▛ -${c6} ▟███▛ ${c5}▟██▙ ${c3}▟███▛ -${c6} ▟███▛ ${c5}▜███▙ ${c3}▝▀▀▀▀ -${c6} ▜██▛ ${c5}▜███▙ ${c4}▜██████████████████▛ -${c6} ▜▛ ${c5}▟████▙ ${c4}▜████████████████▛ -${c5} ▟██████▙ ${c4}▜███▙ -${c5} ▟███▛▜███▙ ${c4}▜███▙ -${c5} ▟███▛ ▜███▙ ${c4}▜███▙ -${c5} ▝▀▀▀ ▀▀▀▀▘ ${c4}▀▀▀▘ \ No newline at end of file +${c3} ▗▄▄▄ ${c4}▗▄▄▄▄ ▄▄▄▖ +${c3} ▜███▙ ${c4}▜███▙ ▟███▛ +${c3} ▜███▙ ${c4}▜███▙▟███▛ +${c3} ▜███▙ ${c4}▜██████▛ +${c3} ▟█████████████████▙ ${c4}▜████▛ ${c5}▟▙ +${c3} ▟███████████████████▙ ${c4}▜███▙ ${c5}▟██▙ +${c2} ▄▄▄▄▖ ${c4}▜███▙ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜██▛ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜▛ ${c5}▟███▛ +${c2}▟███████████▛ ${c5}▟██████████▙ +${c2}▜██████████▛ ${c5}▟███████████▛ +${c2} ▟███▛ ${c1}▟▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▟██▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▜███▙ ${c5}▝▀▀▀▀ +${c2} ▜██▛ ${c1}▜███▙ ${c6}▜██████████████████▛ +${c2} ▜▛ ${c1}▟████▙ ${c6}▜████████████████▛ +${c1} ▟██████▙ ${c6}▜███▙ +${c1} ▟███▛▜███▙ ${c6}▜███▙ +${c1} ▟███▛ ▜███▙ ${c6}▜███▙ +${c1} ▝▀▀▀ ▀▀▀▀▘ ${c6}▀▀▀▘ \ No newline at end of file diff --git a/hyfetch/main.py b/hyfetch/main.py index 00943a27..4c7ebc4e 100755 --- a/hyfetch/main.py +++ b/hyfetch/main.py @@ -441,6 +441,8 @@ def create_config() -> Config: ascii_per_row = max(1, term_size()[0] // (asc_width + 2)) ascii_rows = max(1, (term_size()[1] - 8) // asc_lines) + slots = sorted(set(map(int, re.findall(r'(?<=\${c)[0-9]+(?=})', asc)))) + # Displays horizontal and vertical arrangements in the first iteration, but hide them in # later iterations hv_arrangements = [ @@ -455,15 +457,18 @@ def create_config() -> Config: # Random color schemes pis = list(range(len(_prs.unique_colors().colors))) - slots = list(set(map(int, re.findall('(?<=\\${c)[0-9](?=})', asc)))) + slots = sorted(set(map(int, re.findall(r'(?<=\${c)[0-9]+(?=})', asc)))) while len(pis) < len(slots): pis += pis perm = {p[:len(slots)] for p in islice(permutations(pis), 1000)} + ordered_p = tuple(pis[:len(slots)]) + other_perms = [p for p in perm if p != ordered_p] random_count = max(0, ascii_per_row * ascii_rows - len(arrangements)) if random_count > len(perm): - choices = perm + choices = [ordered_p] + other_perms else: - choices = random.sample(sorted(perm), random_count) + sample_count = max(0, random_count - 1) + choices = [ordered_p] + random.sample(sorted(other_perms), min(sample_count, len(other_perms))) choices = [{slots[i]: n for i, n in enumerate(c)} for c in choices] arrangements += [(f'random{i}', ColorAlignment('custom', r)) for i, r in enumerate(choices)] asciis = [[*ca.recolor_ascii(asc, _prs).split('\n'), k.center(asc_width)] for k, ca in arrangements] diff --git a/hyfetch/neofetch_util.py b/hyfetch/neofetch_util.py index cc2548d8..e0656ec9 100644 --- a/hyfetch/neofetch_util.py +++ b/hyfetch/neofetch_util.py @@ -202,12 +202,21 @@ class ColorAlignment: asc = '\n'.join(preset.color_text(line) + color('&~&*') for line in lines) else: - preset = preset.unique_colors() + colors = preset.unique_colors().colors + if colors: + slots = sorted(set(map(int, re.findall(r'(?<=\${c)[0-9]+(?=})', asc)))) + color_map = {} + for s in slots: + if s in self.custom_colors: + pi = self.custom_colors[s] + elif ((s - 1) % 2 + 1) in self.custom_colors: + pi = self.custom_colors[(s - 1) % 2 + 1] + else: + pi = (s - 1) + color_map[s] = colors[pi % len(colors)].to_ansi() - # Apply colors - color_map = {ai: preset.colors[pi].to_ansi() for ai, pi in self.custom_colors.items()} - for ascii_i, c in color_map.items(): - asc = asc.replace(f'${{c{ascii_i}}}', c) + for ascii_i, c in color_map.items(): + asc = asc.replace(f'${{c{ascii_i}}}', c) return asc diff --git a/neofetch b/neofetch index 3663b4e4..a231ac5a 100755 --- a/neofetch +++ b/neofetch @@ -12888,52 +12888,52 @@ EOF "nixos_colorful"*) set_colors 4 6 4 6 4 6 read -rd '' ascii_data <<'EOF' -${c1} ▗▄▄▄ ${c2}▗▄▄▄▄ ▄▄▄▖ -${c1} ▜███▙ ${c2}▜███▙ ▟███▛ -${c1} ▜███▙ ${c2}▜███▙▟███▛ -${c1} ▜███▙ ${c2}▜██████▛ -${c1} ▟█████████████████▙ ${c2}▜████▛ ${c3}▟▙ -${c1} ▟███████████████████▙ ${c2}▜███▙ ${c3}▟██▙ -${c6} ▄▄▄▄▖ ${c2}▜███▙ ${c3}▟███▛ -${c6} ▟███▛ ${c2}▜██▛ ${c3}▟███▛ -${c6} ▟███▛ ${c2}▜▛ ${c3}▟███▛ -${c6}▟███████████▛ ${c3}▟██████████▙ -${c6}▜██████████▛ ${c3}▟███████████▛ -${c6} ▟███▛ ${c5}▟▙ ${c3}▟███▛ -${c6} ▟███▛ ${c5}▟██▙ ${c3}▟███▛ -${c6} ▟███▛ ${c5}▜███▙ ${c3}▝▀▀▀▀ -${c6} ▜██▛ ${c5}▜███▙ ${c4}▜██████████████████▛ -${c6} ▜▛ ${c5}▟████▙ ${c4}▜████████████████▛ -${c5} ▟██████▙ ${c4}▜███▙ -${c5} ▟███▛▜███▙ ${c4}▜███▙ -${c5} ▟███▛ ▜███▙ ${c4}▜███▙ -${c5} ▝▀▀▀ ▀▀▀▀▘ ${c4}▀▀▀▘ +${c3} ▗▄▄▄ ${c4}▗▄▄▄▄ ▄▄▄▖ +${c3} ▜███▙ ${c4}▜███▙ ▟███▛ +${c3} ▜███▙ ${c4}▜███▙▟███▛ +${c3} ▜███▙ ${c4}▜██████▛ +${c3} ▟█████████████████▙ ${c4}▜████▛ ${c5}▟▙ +${c3} ▟███████████████████▙ ${c4}▜███▙ ${c5}▟██▙ +${c2} ▄▄▄▄▖ ${c4}▜███▙ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜██▛ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜▛ ${c5}▟███▛ +${c2}▟███████████▛ ${c5}▟██████████▙ +${c2}▜██████████▛ ${c5}▟███████████▛ +${c2} ▟███▛ ${c1}▟▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▟██▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▜███▙ ${c5}▝▀▀▀▀ +${c2} ▜██▛ ${c1}▜███▙ ${c6}▜██████████████████▛ +${c2} ▜▛ ${c1}▟████▙ ${c6}▜████████████████▛ +${c1} ▟██████▙ ${c6}▜███▙ +${c1} ▟███▛▜███▙ ${c6}▜███▙ +${c1} ▟███▛ ▜███▙ ${c6}▜███▙ +${c1} ▝▀▀▀ ▀▀▀▀▘ ${c6}▀▀▀▘ EOF ;; "NixOS"*) - set_colors 4 6 + set_colors 4 6 4 6 4 6 read -rd '' ascii_data <<'EOF' -${c1} ▗▄▄▄ ${c2}▗▄▄▄▄ ▄▄▄▖ -${c1} ▜███▙ ${c2}▜███▙ ▟███▛ -${c1} ▜███▙ ${c2}▜███▙▟███▛ -${c1} ▜███▙ ${c2}▜██████▛ -${c1} ▟█████████████████▙ ${c2}▜████▛ ${c1}▟▙ -${c1} ▟███████████████████▙ ${c2}▜███▙ ${c1}▟██▙ -${c2} ▄▄▄▄▖ ▜███▙ ${c1}▟███▛ -${c2} ▟███▛ ▜██▛ ${c1}▟███▛ -${c2} ▟███▛ ▜▛ ${c1}▟███▛ -${c2}▟███████████▛ ${c1}▟██████████▙ -${c2}▜██████████▛ ${c1}▟███████████▛ -${c2} ▟███▛ ${c1}▟▙ ▟███▛ -${c2} ▟███▛ ${c1}▟██▙ ▟███▛ -${c2} ▟███▛ ${c1}▜███▙ ▝▀▀▀▀ -${c2} ▜██▛ ${c1}▜███▙ ${c2}▜██████████████████▛ -${c2} ▜▛ ${c1}▟████▙ ${c2}▜████████████████▛ -${c1} ▟██████▙ ${c2}▜███▙ -${c1} ▟███▛▜███▙ ${c2}▜███▙ -${c1} ▟███▛ ▜███▙ ${c2}▜███▙ -${c1} ▝▀▀▀ ▀▀▀▀▘ ${c2}▀▀▀▘ +${c3} ▗▄▄▄ ${c4}▗▄▄▄▄ ▄▄▄▖ +${c3} ▜███▙ ${c4}▜███▙ ▟███▛ +${c3} ▜███▙ ${c4}▜███▙▟███▛ +${c3} ▜███▙ ${c4}▜██████▛ +${c3} ▟█████████████████▙ ${c4}▜████▛ ${c5}▟▙ +${c3} ▟███████████████████▙ ${c4}▜███▙ ${c5}▟██▙ +${c2} ▄▄▄▄▖ ${c4}▜███▙ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜██▛ ${c5}▟███▛ +${c2} ▟███▛ ${c4}▜▛ ${c5}▟███▛ +${c2}▟███████████▛ ${c5}▟██████████▙ +${c2}▜██████████▛ ${c5}▟███████████▛ +${c2} ▟███▛ ${c1}▟▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▟██▙ ${c5}▟███▛ +${c2} ▟███▛ ${c1}▜███▙ ${c5}▝▀▀▀▀ +${c2} ▜██▛ ${c1}▜███▙ ${c6}▜██████████████████▛ +${c2} ▜▛ ${c1}▟████▙ ${c6}▜████████████████▛ +${c1} ▟██████▙ ${c6}▜███▙ +${c1} ▟███▛▜███▙ ${c6}▜███▙ +${c1} ▟███▛ ▜███▙ ${c6}▜███▙ +${c1} ▝▀▀▀ ▀▀▀▀▘ ${c6}▀▀▀▘ EOF ;;