<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Playgrounds on choieastsea.github.io</title>
    <link>https://choieastsea.github.io/playgrounds/</link>
    <description>Recent content in Playgrounds on choieastsea.github.io</description>
    <generator>Hugo</generator>
    <language>ko-kr</language>
    <atom:link href="https://choieastsea.github.io/playgrounds/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Base64 Encoder / Decoder</title>
      <link>https://choieastsea.github.io/playgrounds/base64/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://choieastsea.github.io/playgrounds/base64/</guid>
      <description>&lt;style&gt;&#xA;.pg-tab-group {&#xA;  display: inline-flex;&#xA;  background: var(--code-background);&#xA;  border: 1px solid var(--code-border);&#xA;  border-radius: 8px;&#xA;  padding: 3px;&#xA;  margin-bottom: 1.5rem;&#xA;}&#xA;&#xA;.pg-tab-btn {&#xA;  padding: 0.4rem 1.1rem;&#xA;  border: none;&#xA;  border-radius: 6px;&#xA;  font-size: 0.875rem;&#xA;  font-weight: 500;&#xA;  cursor: pointer;&#xA;  transition: background 0.15s, color 0.15s;&#xA;  background: transparent;&#xA;  color: var(--content-secondary);&#xA;  font-family: var(--font-body);&#xA;}&#xA;&#xA;.pg-tab-btn.active {&#xA;  background: var(--content-primary);&#xA;  color: var(--background);&#xA;}&#xA;&#xA;.pg-section {&#xA;  margin-bottom: 1rem;&#xA;}&#xA;&#xA;.pg-label {&#xA;  font-size: 0.75rem;&#xA;  font-weight: 600;&#xA;  text-transform: uppercase;&#xA;  letter-spacing: 0.06em;&#xA;  color: var(--content-secondary);&#xA;  margin-bottom: 0.5rem;&#xA;}&#xA;&#xA;.pg-textarea {&#xA;  width: 100%;&#xA;  min-height: 140px;&#xA;  padding: 0.75rem 1rem;&#xA;  font-family: var(--font-mono);&#xA;  font-size: 0.875rem;&#xA;  line-height: 1.6;&#xA;  background: var(--code-background);&#xA;  color: var(--content-primary);&#xA;  border: 1px solid var(--code-border);&#xA;  border-radius: 8px;&#xA;  resize: vertical;&#xA;  outline: none;&#xA;  transition: border-color 0.15s;&#xA;  box-sizing: border-box;&#xA;}&#xA;&#xA;.pg-textarea:focus {&#xA;  border-color: var(--content-secondary);&#xA;}&#xA;&#xA;.pg-output-wrapper {&#xA;  position: relative;&#xA;}&#xA;&#xA;.pg-output-box {&#xA;  width: 100%;&#xA;  min-height: 140px;&#xA;  padding: 0.75rem 1rem;&#xA;  padding-right: 5.5rem;&#xA;  font-family: var(--font-mono);&#xA;  font-size: 0.875rem;&#xA;  line-height: 1.6;&#xA;  background: var(--code-background);&#xA;  color: var(--content-primary);&#xA;  border: 1px solid var(--code-border);&#xA;  border-radius: 8px;&#xA;  white-space: pre-wrap;&#xA;  word-break: break-all;&#xA;  box-sizing: border-box;&#xA;}&#xA;&#xA;.pg-placeholder {&#xA;  color: var(--content-secondary);&#xA;}&#xA;&#xA;.pg-copy-btn {&#xA;  position: absolute;&#xA;  top: 0.625rem;&#xA;  right: 0.625rem;&#xA;  padding: 0.3rem 0.75rem;&#xA;  font-size: 0.75rem;&#xA;  font-weight: 500;&#xA;  background: var(--background);&#xA;  color: var(--content-secondary);&#xA;  border: 1px solid var(--code-border);&#xA;  border-radius: 6px;&#xA;  cursor: pointer;&#xA;  transition: background 0.15s;&#xA;  font-family: var(--font-body);&#xA;}&#xA;&#xA;.pg-copy-btn:hover {&#xA;  background: var(--code-background);&#xA;}&#xA;&#xA;.pg-copy-btn.copied {&#xA;  color: #16a34a;&#xA;  border-color: #bbf7d0;&#xA;}&#xA;&#xA;.pg-error-box {&#xA;  margin-top: 0.5rem;&#xA;  padding: 0.75rem 1rem;&#xA;  border: 1px solid #fecaca;&#xA;  border-radius: 8px;&#xA;  color: #dc2626;&#xA;  font-size: 0.875rem;&#xA;}&#xA;&#xA;.dark .pg-error-box {&#xA;  border-color: #7f1d1d;&#xA;  color: #f87171;&#xA;}&#xA;&#xA;.pg-divider {&#xA;  display: flex;&#xA;  align-items: center;&#xA;  gap: 0.75rem;&#xA;  margin: 1rem 0;&#xA;  color: var(--content-secondary);&#xA;  font-size: 0.75rem;&#xA;}&#xA;&#xA;.pg-divider::before,&#xA;.pg-divider::after {&#xA;  content: &#39;&#39;;&#xA;  flex: 1;&#xA;  height: 1px;&#xA;  background: var(--code-border);&#xA;}&#xA;&lt;/style&gt;&#xA;&lt;div class=&#34;pg-tab-group&#34;&gt;&#xA;  &lt;button class=&#34;pg-tab-btn active&#34; id=&#34;btn-encode&#34; onclick=&#34;setMode(&#39;encode&#39;)&#34;&gt;Encode&lt;/button&gt;&#xA;  &lt;button class=&#34;pg-tab-btn&#34; id=&#34;btn-decode&#34; onclick=&#34;setMode(&#39;decode&#39;)&#34;&gt;Decode&lt;/button&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&#34;pg-section&#34;&gt;&#xA;  &lt;div class=&#34;pg-label&#34; id=&#34;input-label&#34;&gt;원본 텍스트&lt;/div&gt;&#xA;  &lt;textarea class=&#34;pg-textarea&#34; id=&#34;pg-input&#34; placeholder=&#34;인코딩할 텍스트를 입력하세요...&#34; spellcheck=&#34;false&#34; oninput=&#34;convert()&#34;&gt;&lt;/textarea&gt;&#xA;&lt;/div&gt;&#xA;&lt;div class=&#34;pg-divider&#34; id=&#34;pg-divider&#34;&gt;↓ 인코딩&lt;/div&gt;&#xA;&lt;div class=&#34;pg-section&#34;&gt;&#xA;  &lt;div class=&#34;pg-label&#34; id=&#34;output-label&#34;&gt;Base64&lt;/div&gt;&#xA;  &lt;div class=&#34;pg-output-wrapper&#34;&gt;&#xA;    &lt;div class=&#34;pg-output-box&#34; id=&#34;pg-output&#34;&gt;&lt;span class=&#34;pg-placeholder&#34;&gt;결과가 여기에 표시됩니다&lt;/span&gt;&lt;/div&gt;&#xA;    &lt;button class=&#34;pg-copy-btn&#34; id=&#34;pg-copy-btn&#34; style=&#34;display:none&#34; onclick=&#34;copyOutput()&#34;&gt;복사&lt;/button&gt;&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;pg-error-box&#34; id=&#34;pg-error&#34; style=&#34;display:none&#34;&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&lt;script&gt;&#xA;var mode = &#39;encode&#39;;&#xA;&#xA;function encodeBase64(text) {&#xA;  var bytes = new TextEncoder().encode(text);&#xA;  var binString = Array.from(bytes, function(b) { return String.fromCodePoint(b); }).join(&#39;&#39;);&#xA;  return btoa(binString);&#xA;}&#xA;&#xA;function decodeBase64(base64) {&#xA;  var cleaned = base64.replace(/\s/g, &#39;&#39;);&#xA;  var binString = atob(cleaned);&#xA;  var bytes = Uint8Array.from(binString, function(c) { return c.codePointAt(0); });&#xA;  return new TextDecoder().decode(bytes);&#xA;}&#xA;&#xA;function setMode(newMode) {&#xA;  mode = newMode;&#xA;  document.getElementById(&#39;pg-input&#39;).value = &#39;&#39;;&#xA;  document.getElementById(&#39;pg-output&#39;).innerHTML = &#39;&lt;span class=&#34;pg-placeholder&#34;&gt;결과가 여기에 표시됩니다&lt;/span&gt;&#39;;&#xA;  document.getElementById(&#39;pg-error&#39;).style.display = &#39;none&#39;;&#xA;  document.getElementById(&#39;pg-copy-btn&#39;).style.display = &#39;none&#39;;&#xA;&#xA;  var isEncode = mode === &#39;encode&#39;;&#xA;  document.getElementById(&#39;btn-encode&#39;).classList.toggle(&#39;active&#39;, isEncode);&#xA;  document.getElementById(&#39;btn-decode&#39;).classList.toggle(&#39;active&#39;, !isEncode);&#xA;  document.getElementById(&#39;input-label&#39;).textContent = isEncode ? &#39;원본 텍스트&#39; : &#39;Base64&#39;;&#xA;  document.getElementById(&#39;output-label&#39;).textContent = isEncode ? &#39;Base64&#39; : &#39;디코딩 결과&#39;;&#xA;  document.getElementById(&#39;pg-divider&#39;).textContent = isEncode ? &#39;↓ 인코딩&#39; : &#39;↓ 디코딩&#39;;&#xA;  document.getElementById(&#39;pg-input&#39;).placeholder = isEncode&#xA;    ? &#39;인코딩할 텍스트를 입력하세요...&#39;&#xA;    : &#39;디코딩할 Base64 문자열을 입력하세요...&#39;;&#xA;}&#xA;&#xA;function convert() {&#xA;  var input = document.getElementById(&#39;pg-input&#39;).value;&#xA;  var outputEl = document.getElementById(&#39;pg-output&#39;);&#xA;  var errorEl = document.getElementById(&#39;pg-error&#39;);&#xA;  var copyBtn = document.getElementById(&#39;pg-copy-btn&#39;);&#xA;&#xA;  if (!input.trim()) {&#xA;    outputEl.innerHTML = &#39;&lt;span class=&#34;pg-placeholder&#34;&gt;결과가 여기에 표시됩니다&lt;/span&gt;&#39;;&#xA;    errorEl.style.display = &#39;none&#39;;&#xA;    copyBtn.style.display = &#39;none&#39;;&#xA;    return;&#xA;  }&#xA;&#xA;  try {&#xA;    var result = mode === &#39;encode&#39; ? encodeBase64(input) : decodeBase64(input);&#xA;    outputEl.textContent = result;&#xA;    errorEl.style.display = &#39;none&#39;;&#xA;    copyBtn.style.display = &#39;block&#39;;&#xA;    copyBtn.textContent = &#39;복사&#39;;&#xA;    copyBtn.classList.remove(&#39;copied&#39;);&#xA;  } catch (e) {&#xA;    outputEl.innerHTML = &#39;&lt;span class=&#34;pg-placeholder&#34;&gt;결과가 여기에 표시됩니다&lt;/span&gt;&#39;;&#xA;    errorEl.textContent = &#39;유효하지 않은 Base64 문자열입니다. 입력값을 확인해주세요.&#39;;&#xA;    errorEl.style.display = &#39;block&#39;;&#xA;    copyBtn.style.display = &#39;none&#39;;&#xA;  }&#xA;}&#xA;&#xA;function copyOutput() {&#xA;  var text = document.getElementById(&#39;pg-output&#39;).textContent;&#xA;  var btn = document.getElementById(&#39;pg-copy-btn&#39;);&#xA;  navigator.clipboard.writeText(text).then(function() {&#xA;    btn.textContent = &#39;복사됨 ✓&#39;;&#xA;    btn.classList.add(&#39;copied&#39;);&#xA;    setTimeout(function() {&#xA;      btn.textContent = &#39;복사&#39;;&#xA;      btn.classList.remove(&#39;copied&#39;);&#xA;    }, 2000);&#xA;  });&#xA;}&#xA;&lt;/script&gt;</description>
    </item>
  </channel>
</rss>
