# [JavaScript (Node.js)], <s>131</s> 128 bytes <!-- language-all: lang-javascript --> s=>unescape(s.replace(/B.(D.)?/g,(f,s)=>(-~g(f[1])*4*!!s+g((s||f)[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&')) [Try it online!][TIO-jlf4b63g] Link includes test cases. Alternative version, also 131 bytes: <!-- language-all: lang-javascript --> s=>unescape(s.replace(/B.(D.)?/g,s=>(-~g(s[1])*4*!!s[3]+g(s[3]||s[1])).toString(16),g=c=>'IAOU'.search(c)).replace(/../g,'%$&')) [Try it online!][TIO-jlf4bnbh] Link includes test cases. Edit: Saves 3 bytes thanks to @Shaggy. [JavaScript (Node.js)]: https://nodejs.org [TIO-jlf4b63g]: https://tio.run/##fVJBb4MgFL7vX7TZJnSWpsmyS6MLphdOHBZOyw6Goeti1Ijbqdlfd2AFoVYPgDy/977vfbzv9DeVvDnV7basPkWXRZ2M4p9SSJ7WAkjUiLpIuQC7BIEjgq@7PARZKGEUg@1fDrL3/QfcPG9WK/mUAyDP5wzqEERt9dY2pzIH@xcY5hGP4oBgygIkRdrwL8AVxhZHSNUNHu4fAwi7A69KWRUCFZUiAOuEHLFaRC06fLOE9buKriG8m8lgTgZN6FCBDTdzYotSu6lqMTqm98syzBqLZ5hJgj2tIzP16urbhXHsDtuMa1UG0yvSSKe/eSbjA9V6baWRxbho/vka3RMPXhgHRndGDczRQZ2T9YyLjnlZxDrDFrWSiVaaGB3Mq3Kti0z88WbKOnxbE7GeEO8tDIIM/RJnxnzvsNcbnqjz54NOJnLOGeYgiKPP1FmO6Pc5dP8 "JavaScript (Node.js) – Try It Online" [TIO-jlf4bnbh]: https://tio.run/##fVJBb4MgFL7vX7TZJnQtTdNll8YumF44cVg4NR4Mo66LUSNup2Z/3YEVhFo9APL83ve@9/G@k99E8upc1qu8@BTNKWxkuP/JheRJKYBElSizhAuwjhA4IPi@TpcKAFZ/KZDHTQwXr4vZTB638YsObOPLpQ1DVBcfdXXOU7B5g8s05OE@IJiyAEmRVPwLcIWx5Agp3uDp8TmAsNnxIpdFJlBWpOAE5hE5YLWIWrT7ZhFrdxWdQ/gwksGcDBrRjoF1N3Nii1K7YbUYHdP7dZnKGotHKpMIe1r7ytTj1bdrxb47bDNuVRlMq0gjnf7GKxkfqNZrmfoqxkXzz9fonrjzwjjQu9NrYI4O6pysrTjpmJdFrDNsUisZaKWR0cE8lltdZOCPN1PW4fuaiPWEeG9hEKTrlzgz5nuHvd7wQJ0/H3QwkWPOMAdBHH2GZzqi32fX/AM "JavaScript (Node.js) – Try It Online"