GNU/_PAGE/library/manual_ai/directory_structure.php
<?php
/**
 * Directory Tree Viewer - AI Structure Copy Edition
 * 기능: 폴더 옆 '복사' 클릭 시 해당 폴더 포함 하위 트리 전체 텍스트 복사
 */

$root_path = '/home/www'; 

// 트리 생성 함수 (출력용) - 구조 보존
if (!function_exists('get_directory_tree')) {
    function get_directory_tree($path, $level = 0) {
        if (!is_dir($path)) return;

        $items = scandir($path);
        $items = array_diff($items, array('.', '..'));
        $count = count($items);
        $i = 0;

        foreach ($items as $item) {
            $full_path = $path . DIRECTORY_SEPARATOR . $item;
            $is_dir = is_dir($full_path);
            $is_last = (++$i === $count);

            $prefix = ($level > 0) ? str_repeat("│  ", $level - 1) . ($is_last ? "└─ " : "├─ ") : "";
            $class = $is_dir ? "folder" : "file";
            
            echo "<li class='tree-node'>";
            echo "  <div class='tree-line'>";
            echo "    <div class='tree-text'><span>{$prefix}</span><span class='{$class}'>{$item}</span></div>";
            echo "    <div class='copy-zone'><button class='copy-btn' onclick=\"copySubTree(this)\">복사</button></div>";
            echo "  </div>";

            if ($is_dir) {
                echo "<ul>";
                get_directory_tree($full_path, $level + 1);
                echo "</ul>";
            }
            echo "</li>";
        }
    }
}
?>

<?php require_once '/home/www/GNU/_PAGE/head.php'; ?>

<!-- 웹 폰트 및 아이콘 로드 -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Inter:wght@400;700&display=swap" rel="stylesheet">

<style>
    /* [레이아웃 수정] body 대신 전용 래퍼 사용으로 상단 메뉴 밀림 방지 */
    #TERMINAL_WRAP {
        background-color: #050505; 
        background-image: radial-gradient(circle at 50% 50%, #1a1f35 0%, #050505 100%);
        color: #e0e0e0; 
        font-family: 'Inter', -apple-system, sans-serif; 
        margin: 0; 
        padding: 40px 0;
        display: flex;
        justify-content: center;
        min-height: 800px;
    }

    .dt-container { 
        width: calc(100% - 40px); 
        max-width: 1200px; 
        border: 1px solid #222; 
        padding: 30px; 
        background-color: rgba(15, 15, 20, 0.95); 
        border-radius: 12px;
        box-shadow: 0 20px 50px rgba(0,0,0,0.5);
        backdrop-filter: blur(10px);
        position: relative;
        overflow: hidden;
    }

    /* 터미널 상단 헤더 */
    .dt-header { 
        color: #00ff88; 
        font-family: 'JetBrains Mono', monospace;
        font-size: 1.2rem; 
        font-weight: bold; 
        border-bottom: 1px solid #222; 
        padding-bottom: 20px; 
        margin-bottom: 25px; 
        display: flex;
        align-items: center;
        gap: 12px;
        text-transform: uppercase;
        letter-spacing: 1px;
    }

    .dt-header::before {
        content: "";
        width: 12px;
        height: 12px;
        background-color: #ff5f56;
        border-radius: 50%;
        box-shadow: 20px 0 0 #ffbd2e, 40px 0 0 #27c93f;
        margin-right: 50px;
    }
    
    .dt-container ul { list-style: none; padding: 0; margin: 0; }
    
    .tree-line { 
        display: flex; 
        justify-content: space-between; 
        align-items: center; 
        border-bottom: 1px solid rgba(255,255,255,0.02); 
        padding: 6px 12px; 
        transition: 0.2s;
        border-radius: 4px;
    }
    
    .tree-line:hover { 
        background-color: rgba(255, 255, 255, 0.05); 
        box-shadow: inset 0 0 10px rgba(0, 210, 255, 0.05);
    }
    
    .tree-text { 
        font-family: 'JetBrains Mono', monospace;
        font-size: 13px;
        white-space: pre; 
        flex-grow: 1; 
        color: #e0e0e0;
    }
    
    .folder { color: #f1c40f; font-weight: bold; }
    .file { color: #00d2ff; }

    .folder::before {
        content: "\f07b";
        font-family: "Font Awesome 6 Free";
        font-weight: 900;
        margin-right: 8px;
        font-size: 12px;
    }
    .file::before {
        content: "\f15b";
        font-family: "Font Awesome 6 Free";
        font-weight: 400;
        margin-right: 8px;
        font-size: 12px;
        opacity: 0.7;
    }

    .copy-btn { 
        background-color: transparent; 
        color: #666; 
        border: 1px solid #333; 
        padding: 4px 14px; 
        font-size: 10px; 
        cursor: pointer; 
        border-radius: 4px; 
        font-weight: bold;
        font-family: 'JetBrains Mono', monospace;
        transition: all 0.3s;
        text-transform: uppercase;
    }

    .copy-btn:hover { 
        background-color: #00ff88; 
        color: #000; 
        border-color: #00ff88; 
        box-shadow: 0 0 15px rgba(0, 255, 136, 0.4);
    }

    /* 스크롤바 커스텀 */
    #TERMINAL_WRAP ::-webkit-scrollbar { width: 8px; }
    #TERMINAL_WRAP ::-webkit-scrollbar-track { background: #0a0a0a; }
    #TERMINAL_WRAP ::-webkit-scrollbar-thumb { background: #222; border-radius: 4px; }
</style>

<div id="TERMINAL_WRAP">
    <div class="dt-container">
        <div class="dt-header">
            <i class="fa-solid fa-terminal"></i> DIRECTORY STRUCTURE COMMANDER
        </div>
        
        <ul>
            <li class="tree-node">
                <div class="tree-line">
                    <div class="tree-text"><span class="folder">www</span></div>
                    <div class="copy-zone"><button class="copy-btn" onclick="copySubTree(this)">복사</button></div>
                </div>
                <ul>
                    <?php
                    if (file_exists($root_path)) {
                        get_directory_tree($root_path, 1);
                    }
                    ?>
                </ul>
            </li>
        </ul>
    </div>
</div>

<script>
    function copySubTree(btn) {
        const node = btn.closest('.tree-node');
        const textElements = node.querySelectorAll('.tree-text');
        let structureText = "";
        
        textElements.forEach((el, index) => {
            structureText += el.innerText + (index < textElements.length - 1 ? "\n" : "");
        });

        const textarea = document.createElement("textarea");
        textarea.value = structureText;
        document.body.appendChild(textarea);
        textarea.select();
        document.execCommand("copy");
        document.body.removeChild(textarea);

        const originalText = btn.innerText;
        btn.innerText = "SUCCESS";
        btn.style.color = "#000";
        btn.style.backgroundColor = "#00ff88";
        btn.style.borderColor = "#00ff88";
        
        setTimeout(() => {
            btn.innerText = originalText;
            btn.style.color = "";
            btn.style.backgroundColor = "";
            btn.style.borderColor = "";
        }, 1000);
    }
</script>

<?php require_once '/home/www/GNU/_PAGE/tail.php'; ?>