diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/arabic/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/arabic/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/arabic/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/arabic/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese-traditional/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/chinese-traditional/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/chinese-traditional/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/chinese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/chinese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/chinese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/chinese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/espanol/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/espanol/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/espanol/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/espanol/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/german/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/german/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/german/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/german/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/italian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/italian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/italian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/italian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/japanese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/japanese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/japanese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/japanese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/portuguese/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/portuguese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/portuguese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/portuguese/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/swahili/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/swahili/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/swahili/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/swahili/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3
diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
new file mode 100644
index 00000000000..2685acd6967
--- /dev/null
+++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a608b7e7c75a04ccf0c23c.md
@@ -0,0 +1,644 @@
+---
+id: 65a608b7e7c75a04ccf0c23c
+title: Step 21
+challengeType: 0
+dashedName: step-21
+---
+
+# --description--
+
+Now that you have the list of songs displayed on the screen, it would be nice to sort them in alphabetical order by title. You could manually update the `allSongs` array, but JavaScript has an array method you can use called sort() .
+
+The `sort()` method converts elements of an array into strings and sorts them in place based on their values in the `UTF-16` encoding.
+
+```js
+const names = ["Tom", "Jessica", "Quincy", "Naomi"];
+names.sort() // ["Jessica", "Naomi", "Quincy", "Tom"]
+```
+
+Add the `sort()` method to `userData?.songs`.
+
+# --hints--
+
+You should add the `sort()` method to `userData?.songs`.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(*.\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
new file mode 100644
index 00000000000..c27642fe968
--- /dev/null
+++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a6098a3405f206312e28f5.md
@@ -0,0 +1,659 @@
+---
+id: 65a6098a3405f206312e28f5
+title: Step 22
+challengeType: 0
+dashedName: step-22
+---
+
+# --description--
+
+To sort the songs in alphabetical order by title, you will need to pass in a compare callback function into your `sort()` method.
+
+Here is an example of sorting a list of fruits by name.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+In the next few steps, you will learn what each of those `if` statements is doing inside that callback function. But for now, add an empty callback function to your `sort()` method and use `a` and `b` for the parameter names.
+
+# --hints--
+
+You should have an empty callback function `()=>{}` inside your `sort()` method with `a` and `b` for the parameter names.
+
+```js
+assert.match(code, /userData\?\.songs\.sort\(\s*\(\s*a\s*,\s*b\s*\)\s*=>\s*{\s*}\s*\);?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort();
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
new file mode 100644
index 00000000000..80fa8a91f63
--- /dev/null
+++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a609f6e23f3b06c608fb57.md
@@ -0,0 +1,677 @@
+---
+id: 65a609f6e23f3b06c608fb57
+title: Step 23
+challengeType: 0
+dashedName: step-23
+---
+
+# --description--
+
+The `sort()` method accepts a compare callback function that defines the sort order.
+
+In this example, the first condition `(a.name < b.name)` checks if the name of the first fruit is less than the name of the second fruit. If so, the first fruit is sorted before the second fruit.
+
+Strings are compared lexicographically which means they are compared character by character. For example, `"Apples"` is less than `"Bananas"` because `"A"` comes before `"B"` in the alphabet.
+
+The reason why this example is returning numbers is because the `sort()` method is expecting a number to be returned. If you return a negative number, the first item is sorted before the second item.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add an `if` statement to check if `a.title` is less than `b.title`. If so, return `-1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return `-1` if `a.title` is less than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*{\s*return\s*-1;?\s*}|if\s*\(\s*a\.title\s*<\s*b\.title\s*\)\s*return\s*-1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+--fcc-editable-region--
+userData?.songs.sort((a,b) => {
+
+});
+--fcc-editable-region--
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
new file mode 100644
index 00000000000..9e2709b718d
--- /dev/null
+++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60aa3efd8fa079c2d1537.md
@@ -0,0 +1,675 @@
+---
+id: 65a60aa3efd8fa079c2d1537
+title: Step 24
+challengeType: 0
+dashedName: step-24
+---
+
+# --description--
+
+The second condition in this example checks if `a.name > b.name`. If so, the function returns `1`, which sorts the first fruit after the second fruit.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Inside your callback function, add another `if` statement to check if `a.title` is greater than `b.title`. If so, return the number `1`.
+
+# --hints--
+
+You should have an `if` statement inside your callback function.
+
+```js
+assert.match(code, /if\s*\(/);
+```
+
+Your `if` statement should check if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)/);
+```
+
+Your `if` statement should return the number `1` if `a.title` is greater than `b.title`.
+
+```js
+assert.match(code, /if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*{\s*return\s*1;?\s*}|if\s*\(\s*a\.title\s*>\s*b\.title\s*\)\s*return\s*1;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ --fcc-editable-region--
+
+ --fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
new file mode 100644
index 00000000000..042fc880597
--- /dev/null
+++ b/curriculum/challenges/ukrainian/15-javascript-algorithms-and-data-structures-22/learn-basic-string-and-array-methods-by-building-a-music-player/65a60b0b8b4f96085ac23463.md
@@ -0,0 +1,669 @@
+---
+id: 65a60b0b8b4f96085ac23463
+title: Step 25
+challengeType: 0
+dashedName: step-25
+---
+
+# --description--
+
+In the example, if `a.name` is equal to `b.name`, then the function returns `0`. This means that nothing changes and the order of `a` and `b` remains the same.
+
+```js
+const fruits = [
+ { name: "Apples", price: 0.99 },
+ { name: "Blueberries", price: 1.49 },
+ { name: "Grapes", price: 2.99 },
+];
+
+fruits.sort((a, b) => {
+ if (a.name < b.name) {
+ return -1;
+ }
+
+ if (a.name > b.name) {
+ return 1;
+ }
+
+ return 0;
+});
+```
+
+Below your `if` statements, return the number `0` to leave the order of the two elements unchanged.
+
+Now you should see the songs in alphabetical order in the playlist.
+
+# --hints--
+
+You should return the number `0` below your `if` statements.
+
+```js
+assert.match(code, /return\s+0\s*;?/);
+```
+
+# --seed--
+
+## --seed-contents--
+
+```html
+
+
+
+
+
+
+
+
+
+ Learn Basic String and Array Methods by Building a Music Player App
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```css
+:root {
+ /* colors */
+ --primary-color: #dfdfe2;
+ --secondary-color: #ffffff;
+ --app-background-color: #4d4d62;
+ --background-color: #1b1b32;
+ --foreground-color: #3b3b4f;
+ --highlight-color: #f1be32;
+
+ /* font sizes */
+ --root-font-size: 16px;
+ font-size: var(--root-font-size);
+
+ /* font-families */
+ --font-headline: "Roboto Mono", monospace;
+ --font-family: "Lato", sans-serif;
+}
+
+*,
+*::after,
+*::before {
+ box-sizing: border-box;
+}
+
+body {
+ background-color: var(--app-background-color);
+ color: var(--primary-color);
+ font-family: var(--font-family);
+}
+
+h1 {
+ font-size: 1.125rem;
+ line-height: 1.6;
+}
+
+h2 {
+ font-size: var(--root-font-size);
+}
+
+ul {
+ margin: 0;
+}
+
+.container {
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ row-gap: 5px;
+}
+
+.player,
+.playlist {
+ width: 450px;
+ background-color: var(--background-color);
+ border: 3px solid var(--foreground-color);
+}
+
+.player {
+ height: 260px;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+.player-bar,
+.playlist-bar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0 5px;
+ width: 100%;
+ height: 30px;
+ background-color: var(--foreground-color);
+}
+
+.parallel-lines {
+ display: flex;
+ flex-wrap: wrap;
+ row-gap: 6px;
+ padding: 0 5px;
+}
+
+.parallel-lines > div {
+ height: 2px;
+ width: 100%;
+ min-width: 75px;
+ background-color: var(--highlight-color);
+}
+
+.fcc-title,
+.playlist-title {
+ color: var(--secondary-color);
+ margin: 0 10px;
+ font-family: var(--font-headline);
+}
+
+.player-content {
+ display: flex;
+ background-color: var(--foreground-color);
+ width: 430px;
+ height: 200px;
+ column-gap: 13px;
+ align-items: center;
+ justify-content: center;
+}
+
+#player-album-art {
+ background-color: var(--secondary-color);
+ border: 6px solid var(--background-color);
+}
+
+#player-album-art img {
+ width: 150px;
+ display: block;
+}
+
+.player-display {
+ display: flex;
+ flex-direction: column;
+ row-gap: 20px;
+ padding: 14px;
+ background-color: var(--background-color);
+ height: 153px;
+ width: 226px;
+}
+
+.player-display-song-artist {
+ height: 80px;
+}
+
+.player-buttons svg {
+ fill: var(--primary-color);
+}
+
+.playing > svg {
+ fill: var(--highlight-color);
+}
+
+.player-buttons {
+ display: flex;
+ justify-content: space-around;
+}
+
+button {
+ background: transparent;
+ border: none;
+ color: var(--primary-color);
+ cursor: pointer;
+ font-size: var(--root-font-size);
+ outline-color: var(--highlight-color);
+ text-align: center;
+}
+
+.playlist-song {
+ outline-color: var(--highlight-color);
+}
+
+.playlist li:not(:last-child) {
+ border-bottom: 1px solid var(--background-color);
+}
+
+button:focus,
+.playlist-song:focus {
+ outline-style: dashed;
+ outline-width: 2px;
+}
+
+/* Playlist */
+.playlist {
+ height: auto;
+ padding: 10px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ row-gap: 10px;
+}
+
+#playlist-songs {
+ width: 430px;
+ height: 100%;
+ background-color: var(--foreground-color);
+ display: flex;
+ flex-direction: column;
+ row-gap: 8px;
+ padding: 8px 9px;
+ visibility: visible;
+ justify-content: start;
+ list-style: none;
+}
+
+.playlist-song {
+ display: flex;
+ height: 55px;
+ justify-content: space-between;
+ align-items: center;
+ padding: 5px;
+}
+
+[aria-current="true"] {
+ background-color: var(--background-color);
+}
+
+[aria-current="true"] p {
+ color: var(--highlight-color);
+}
+
+.playlist-song-info {
+ height: 100%;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-around;
+ column-gap: 7px;
+ padding: 5px 0;
+ font-family: var(--font-family);
+}
+
+#player-song-title,
+#player-song-artist {
+ margin: 0;
+}
+
+#player-song-artist {
+ color: var(--highlight-color);
+ font-size: 0.75rem;
+}
+
+#player-song-title {
+ font-size: 1.125rem;
+}
+
+.playlist-song-title {
+ font-size: 0.85rem;
+ width: 241px;
+ text-align: left;
+}
+
+.playlist-song-artist {
+ font-size: 0.725rem;
+ width: 80px;
+}
+
+.playlist-song-duration {
+ font-size: 0.725rem;
+ margin: auto;
+ font-family: var(--font-headline);
+ width: 30px;
+}
+
+.playlist-song-delete {
+ padding: 0;
+ width: 20px;
+ height: 20px;
+}
+
+.playlist-song-delete,
+.playlist-song-delete {
+ fill: var(--foreground-color);
+}
+
+.playlist-song-delete:hover circle,
+.playlist-song-delete:focus circle {
+ fill: #ff0000;
+}
+
+@media (max-width: 700px) {
+ .player,
+ .playlist {
+ width: 300px;
+ }
+
+ .player {
+ height: 340px;
+ }
+
+ #playlist-songs {
+ height: 280px;
+ padding: 5px 6px;
+ overflow-y: scroll;
+ overflow-x: hidden;
+ scrollbar-color: var(--background-color) var(--secondary-color);
+ scrollbar-width: thin;
+ }
+
+ #playlist-songs::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ #playlist-songs::-webkit-scrollbar-track {
+ background: var(--background-color);
+ }
+
+ #playlist-songs::-webkit-scrollbar-thumb {
+ background: var(--secondary-color);
+ }
+
+ h1 {
+ font-size: 0.813rem;
+ }
+
+ h2 {
+ font-size: 0.75rem;
+ }
+
+ .player-bar,
+ .playlist-bar,
+ .player-content,
+ #playlist-songs {
+ width: 280px;
+ }
+
+ .playlist-song {
+ justify-content: space-between;
+ }
+
+ .playlist-song-title {
+ width: 140px;
+ }
+
+ .playlist-song-artist {
+ width: 40px;
+ }
+
+ .playlist-song-duration > button {
+ padding: 0;
+ }
+
+ .player-content {
+ display: inline;
+ position: relative;
+ justify-items: center;
+ height: 100%;
+ }
+
+ #player-album-art {
+ z-index: -100;
+ height: 280px;
+ box-shadow: none;
+ background: #000;
+ }
+
+ #player-album-art img {
+ width: 100%;
+ opacity: 0.6;
+ }
+
+ .player-display-song-artist {
+ padding: 0 10px;
+ }
+
+ .player-display-song-artist > p {
+ white-space: pre-wrap;
+ }
+
+ .player-display {
+ position: absolute;
+ width: 100%;
+ z-index: 1000;
+ background-color: transparent;
+ top: 0;
+ height: 280px;
+ justify-content: space-between;
+ text-align: center;
+ }
+}
+```
+
+```js
+const playlistSongs = document.getElementById("playlist-songs");
+const playButton = document.getElementById("play");
+const pauseButton = document.getElementById("pause");
+const nextButton = document.getElementById("next");
+const previousButton = document.getElementById("previous");
+const shuffleButton = document.getElementById("shuffle");
+
+const allSongs = [
+ {
+ id: 0,
+ title: "Scratching The Surface",
+ artist: "Quincy Larson",
+ duration: "4:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/scratching-the-surface.mp3",
+ },
+ {
+ id: 1,
+ title: "Can't Stay Down",
+ artist: "Quincy Larson",
+ duration: "4:15",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stay-down.mp3",
+ },
+ {
+ id: 2,
+ title: "Still Learning",
+ artist: "Quincy Larson",
+ duration: "3:51",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/still-learning.mp3",
+ },
+ {
+ id: 3,
+ title: "Cruising for a Musing",
+ artist: "Quincy Larson",
+ duration: "3:34",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cruising-for-a-musing.mp3",
+ },
+ {
+ id: 4,
+ title: "Never Not Favored",
+ artist: "Quincy Larson",
+ duration: "3:35",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/never-not-favored.mp3",
+ },
+ {
+ id: 5,
+ title: "From the Ground Up",
+ artist: "Quincy Larson",
+ duration: "3:12",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/from-the-ground-up.mp3",
+ },
+ {
+ id: 6,
+ title: "Walking on Air",
+ artist: "Quincy Larson",
+ duration: "3:25",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/walking-on-air.mp3",
+ },
+ {
+ id: 7,
+ title: "Can't Stop Me. Can't Even Slow Me Down.",
+ artist: "Quincy Larson",
+ duration: "3:52",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/cant-stop-me-cant-even-slow-me-down.mp3",
+ },
+ {
+ id: 8,
+ title: "The Surest Way Out is Through",
+ artist: "Quincy Larson",
+ duration: "3:10",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/the-surest-way-out-is-through.mp3",
+ },
+ {
+ id: 9,
+ title: "Chasing That Feeling",
+ artist: "Quincy Larson",
+ duration: "2:43",
+ src: "https://s3.amazonaws.com/org.freecodecamp.mp3-player-project/chasing-that-feeling.mp3",
+ },
+];
+
+const audio = new Audio();
+
+let userData = {
+ songs: [...allSongs],
+ currentSong: null,
+ songCurrentTime: 0,
+};
+
+const renderSongs = (array) => {
+ const songsHTML = array
+ .map((song)=> {
+ return `
+
+
+ ${song.title}
+ ${song.artist}
+ ${song.duration}
+
+
+
+
+
+
+ `;
+ })
+ .join("");
+
+ playlistSongs.innerHTML = songsHTML;
+};
+
+userData?.songs.sort((a,b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+
+ if (a.title > b.title) {
+ return 1;
+ }
+
+--fcc-editable-region--
+
+--fcc-editable-region--
+});
+
+renderSongs(userData?.songs);
+```
diff --git a/curriculum/challenges/ukrainian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md b/curriculum/challenges/ukrainian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
new file mode 100644
index 00000000000..2436aac925c
--- /dev/null
+++ b/curriculum/challenges/ukrainian/16-the-odin-project/top-introduction-to-flexbox/introduction-flexbox-question-k.md
@@ -0,0 +1,47 @@
+---
+id: 6597b43d854b3fa8e35d66d7
+title: Introduction to Flexbox Question K
+challengeType: 15
+dashedName: introduction-flexbox-question-k
+---
+# --description--
+
+
+
+To change the placement of items along the cross axis use `align-items`. Try getting the boxes to the center of the container by adding `align-items: center` to `.container`. The desired result looks like this:
+
+
+
+Because `justify-content` and `align-items` are based on the main and cross axis of your container, their behavior changes when you change the flex-direction of a flex-container. For example, when you change `flex-direction` to `column`, `justify-content` aligns vertically and `align-items` aligns horizontally. The most common behavior, however, is the default, i.e. `justify-content` aligns items horizontally (because the main axis defaults to horizontal), and `align-items` aligns them vertically. One of the biggest sticking points that beginners have with flexbox is confusion when this behavior changes.
+
+# --question--
+
+## --assignment--
+
+Before moving on to the next lesson, see if you can figure out how `align-items` behaves when you change the `flex-direction` property to `column`.
+
+## --text--
+
+When changing the `flex-direction` property to `column` in a flex container, how does `align-items` behave in relation to the flex items?
+
+## --answers--
+
+It distributes space between items evenly.
+
+---
+
+It aligns items horizontally along the main axis.
+
+---
+
+It centers items vertically along the cross axis.
+
+---
+
+It aligns items to the start of the container along the cross axis.
+
+## --video-solution--
+
+3