| --- |
| license: h-research |
| datasets: |
| - nvidia/PhysicalAI-Robotics-Locomanipulation-GRAIL |
| language: |
| - en |
| metrics: |
| - ronaldahmed/nwentfaithfulness |
| base_model: |
| - deepseek-ai/DeepSeek-V4-Flash-0731 |
| new_version: openbmb/MiniCPM-RobotManip |
| pipeline_tag: robotics |
| --- |
| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>🤖 AI-Robotic Orchestrator v3.0</title> |
| <style> |
| /* --- Cyber/Robotic Theme Variables --- */ |
| :root { |
| --bg-dark: #0a0f14; |
| --bg-panel: #141a20; |
| --neon-green: #00ffaa; |
| --neon-blue: #00d4ff; |
| --neon-red: #ff3366; |
| --text-main: #e0e6ed; |
| --text-muted: #7a8b9e; |
| --border-glow: rgba(0, 255, 170, 0.2); |
| } |
| |
| * { box-sizing: border-box; margin: 0; padding: 0; } |
|
|
| body { |
| font-family: 'Segoe UI', 'Courier New', monospace, sans-serif; |
| background-color: var(--bg-dark); |
| color: var(--text-main); |
| padding: 20px; |
| display: flex; |
| justify-content: center; |
| min-height: 100vh; |
| background-image: |
| linear-gradient(rgba(0, 255, 170, 0.03) 1px, transparent 1px), |
| linear-gradient(90deg, rgba(0, 255, 170, 0.03) 1px, transparent 1px); |
| background-size: 40px 40px; |
| } |
| |
| .container { |
| max-width: 1100px; |
| width: 100%; |
| background: var(--bg-panel); |
| border: 1px solid var(--border-glow); |
| border-radius: 16px; |
| padding: 30px; |
| box-shadow: 0 0 30px rgba(0, 255, 170, 0.05); |
| position: relative; |
| } |
| |
| /* --- Header --- */ |
| h1 { text-align: center; color: var(--neon-green); text-shadow: 0 0 15px rgba(0, 255, 170, 0.4); margin-bottom: 5px; letter-spacing: 2px; } |
| .subtitle { text-align: center; color: var(--text-muted); margin-bottom: 25px; border-bottom: 1px solid #2a3540; padding-bottom: 15px; } |
| |
| /* --- Robot Status Panel --- */ |
| .robot-status-panel { |
| display: flex; justify-content: space-between; background: #0d1219; |
| border: 1px solid #2a3540; border-radius: 8px; padding: 15px 20px; |
| margin-bottom: 25px; flex-wrap: wrap; gap: 10px; |
| } |
| .stat-item { display: flex; flex-direction: column; } |
| .stat-label { font-size: 0.75rem; color: var(--text-muted); text-transform: uppercase; letter-spacing: 1px;} |
| .stat-value { font-weight: bold; font-size: 1.1rem; font-family: 'Courier New', monospace; } |
| .blink { animation: blinker 1.5s linear infinite; } |
| @keyframes blinker { 50% { opacity: 0.3; } } |
| |
| /* --- Server Grid --- */ |
| .server-grid { display: flex; justify-content: space-between; gap: 15px; flex-wrap: wrap; margin-bottom: 25px; } |
| .server-card { |
| flex: 1; min-width: 180px; background: #11181f; border: 1px solid #2a3540; |
| border-radius: 10px; padding: 20px 15px; text-align: center; transition: 0.3s; |
| } |
| .server-card h3 { margin: 0 0 15px 0; color: var(--neon-blue); } |
| |
| .status-badge { |
| display: inline-block; padding: 6px 16px; border-radius: 20px; font-size: 0.8rem; |
| font-weight: bold; text-transform: uppercase; background: #2a3540; color: var(--text-muted); |
| } |
| .status-primary { background: rgba(0, 255, 170, 0.2); color: var(--neon-green); border: 1px solid var(--neon-green); box-shadow: 0 0 10px rgba(0,255,170,0.1); } |
| .status-secondary { background: rgba(0, 212, 255, 0.1); color: var(--neon-blue); border: 1px solid var(--neon-blue); } |
| .status-excluded { background: rgba(255, 51, 102, 0.1); color: var(--neon-red); border: 1px solid var(--neon-red); } |
| |
| .db-box { margin-top: 12px; font-size: 0.8rem; background: #0d1219; padding: 6px; border-radius: 4px; border-left: 2px solid #2a3540; } |
| .db-box.ha { border-left-color: var(--neon-green); } |
| |
| /* --- Control Panel --- */ |
| .ai-control-panel { background: rgba(0, 0, 0, 0.4); border: 1px solid #2a3540; border-radius: 10px; padding: 20px; margin-bottom: 25px; } |
| .ai-control-panel h2 { margin-top: 0; color: var(--neon-blue); font-size: 1.1rem; border-bottom: 1px solid #2a3540; padding-bottom: 10px; } |
| .control-group { display: flex; gap: 10px; flex-wrap: wrap; margin: 15px 0; } |
| |
| button { |
| background: transparent; color: var(--text-main); border: 1px solid #2a3540; |
| padding: 10px 20px; border-radius: 6px; cursor: pointer; font-weight: 600; transition: 0.2s; |
| } |
| button:hover { background: #2a3540; } |
| button.primary-act { border-color: var(--neon-green); color: var(--neon-green); } |
| button.primary-act:hover { box-shadow: 0 0 15px rgba(0,255,170,0.2); background: rgba(0,255,170,0.1); } |
| button.danger { border-color: var(--neon-red); color: var(--neon-red); } |
| button.danger:hover { background: rgba(255,51,102,0.1); box-shadow: 0 0 15px rgba(255,51,102,0.2); } |
| button:disabled { opacity: 0.5; cursor: not-allowed; } |
| |
| /* --- Terminal --- */ |
| .ai-terminal { background: #0a0b0d; border: 1px solid #2a3540; border-radius: 8px; padding: 5px; margin-bottom: 20px; } |
| .terminal-header { background: #141a20; padding: 8px 15px; border-bottom: 1px solid #2a3540; color: var(--text-muted); display: flex; justify-content: space-between; border-radius: 8px 8px 0 0; } |
| .terminal-window { padding: 15px; height: 120px; overflow-y: auto; font-family: 'Courier New', monospace; font-size: 0.9rem; color: #bbb; } |
| .terminal-window::-webkit-scrollbar { width: 5px; } |
| .terminal-window::-webkit-scrollbar-track { background: #0a0b0d; } |
| .terminal-window::-webkit-scrollbar-thumb { background: #2a3540; border-radius: 10px; } |
| .log-line { margin-bottom: 3px; } |
| .log-error { color: var(--neon-red); } |
| .log-success { color: var(--neon-green); } |
| .log-info { color: var(--neon-blue); } |
| .log-warn { color: #ffaa00; } |
| |
| /* --- NEW: CHAT INTERFACE --- */ |
| .chat-container { |
| margin-top: 10px; |
| background: #0d1219; |
| border: 1px solid var(--neon-blue); |
| border-radius: 10px; |
| padding: 15px; |
| box-shadow: 0 0 20px rgba(0, 212, 255, 0.1); |
| } |
| .chat-header { color: var(--neon-blue); font-weight: bold; border-bottom: 1px solid #2a3540; padding-bottom: 10px; margin-bottom: 10px; display: flex; justify-content: space-between; } |
| .chat-messages { height: 150px; overflow-y: auto; margin-bottom: 15px; padding-right: 5px;} |
| .chat-messages::-webkit-scrollbar { width: 5px; } |
| .chat-messages::-webkit-scrollbar-track { background: #0d1219; } |
| .chat-messages::-webkit-scrollbar-thumb { background: var(--neon-blue); border-radius: 10px; } |
| |
| .msg { display: flex; margin-bottom: 10px; } |
| .msg.user { justify-content: flex-end; } |
| .msg.bot { justify-content: flex-start; } |
| .bubble { max-width: 80%; padding: 8px 15px; border-radius: 15px; font-size: 0.9rem; } |
| .user .bubble { background: #005c99; color: white; border-bottom-right-radius: 2px; } |
| .bot .bubble { background: #2a3540; color: #e0e6ed; border-bottom-left-radius: 2px; } |
| .typing-indicator { color: var(--neon-blue); font-size: 0.8rem; font-style: italic; margin-left: 10px; display: none; } |
| |
| .chat-input-group { display: flex; gap: 10px; } |
| .chat-input-group input { flex: 1; background: #141a20; border: 1px solid #2a3540; color: white; padding: 10px; border-radius: 6px; outline: none; } |
| .chat-input-group input:focus { border-color: var(--neon-blue); } |
| .chat-input-group button { border-color: var(--neon-blue); color: var(--neon-blue); padding: 10px 20px; border-radius: 6px;} |
| |
| /* --- Footer --- */ |
| .social-footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #2a3540; text-align: center; } |
| .social-links { display: flex; justify-content: center; gap: 15px; flex-wrap: wrap; margin-top: 10px; } |
| .social-btn { display: inline-flex; align-items: center; gap: 8px; background: transparent; border: 1px solid #2a3540; padding: 8px 18px; border-radius: 30px; text-decoration: none; color: var(--text-muted); font-size: 0.9rem; transition: 0.2s; } |
| .social-btn:hover { background: #2a3540; border-color: var(--neon-blue); color: white; } |
| .creator-credit { margin-top: 20px; font-size: 0.9rem; color: #555; border-top: 1px solid #1a232c; padding-top: 15px; } |
| .creator-credit strong { color: var(--neon-blue); } |
| </style> |
| </head> |
| <body> |
| |
| <div class="container"> |
| <h1>🤖 AI-Robotic Orchestrator v3.0</h1> |
| <div class="subtitle">AG1-Sample :: Autonomous Scheduler Unit :: Read, Write, Scan, Execute</div> |
| |
| <!-- Live Robot Status Panel --> |
| <div class="robot-status-panel"> |
| <div class="stat-item"><span class="stat-label">System Status</span><span class="stat-value blink" style="color: var(--neon-green);">● ACTIVE</span></div> |
| <div class="stat-item"><span class="stat-label">Uptime</span><span class="stat-value" id="robotUptime">00:00:00</span></div> |
| <div class="stat-item"><span class="stat-label">Active Primary</span><span class="stat-value" id="currentPrimaryDisplay" style="color: var(--neon-green);">Server1</span></div> |
| <div class="stat-item"><span class="stat-label">CPU Load</span><span class="stat-value" id="cpuLoad">12%</span></div> |
| </div> |
| |
| <!-- Server Grid --> |
| <div class="server-grid" id="serverGrid"></div> |
| |
| <!-- AI Command Center --> |
| <div class="ai-control-panel"> |
| <h2>⚡ Manual Command Center</h2> |
| <div style="background: #0d1219; padding: 8px 15px; border-radius: 4px; margin-bottom: 15px; border-left: 3px solid #ffaa00;"> |
| <strong style="color:#ffaa00;">⚙️ Active Policy:</strong> <span id="customRuleDisplay" style="color: var(--text-main);">Only Primary nodes can write to agDatabase.</span> |
| </div> |
| <div class="control-group"> |
| <button class="danger" onclick="simulateFailover('Server2')">⚡ Failover to S2</button> |
| <button class="danger" onclick="simulateFailover('Server3')">⚡ Failover to S3</button> |
| <button class="primary-act" onclick="resetSimulation()">⟳ Reset System</button> |
| <button onclick="simulateJobRun('Server1')">Run Job S1</button> |
| <button onclick="simulateJobRun('Server2')">Run Job S2</button> |
| <button onclick="simulateJobRun('Server3')">Run Job S3</button> |
| </div> |
| </div> |
| |
| <!-- AI Terminal Log --> |
| <div class="ai-terminal"> |
| <div class="terminal-header"> |
| <span>📟 TERMINAL LOG</span> |
| <span>Operator: A.P.PATHUm LAKMAL</span> |
| </div> |
| <div class="terminal-window" id="logFeed"> |
| <div class="log-line log-success">[INIT] System initialized. A.P.PATHUm LAKMAL ready.</div> |
| </div> |
| </div> |
| |
| <!-- NEW: AI CHATBOT INTERFACE --> |
| <div class="chat-container"> |
| <div class="chat-header"> |
| <span>🧠 AI System Bot (Read / Write / Scan / Execute)</span> |
| <span style="font-size: 0.8rem; color: var(--neon-green);">● ONLINE</span> |
| </div> |
| <div class="chat-messages" id="chatMessages"> |
| <div class="msg bot"><div class="bubble">Hello! I am your AI Orchestrator. You can ask me to check server status, run jobs, or failover nodes! Try: "Scan Server 2"</div></div> |
| </div> |
| <div class="typing-indicator" id="typingIndicator">AI is thinking...</div> |
| <div class="chat-input-group"> |
| <input type="text" id="chatInput" placeholder="Type a command... (e.g., 'Failover to Server 3')" onkeypress="handleChatEnter(event)"> |
| <button onclick="handleChatSend()">Send ⚡</button> |
| </div> |
| </div> |
| |
| <!-- Social Footer --> |
| <div class="social-footer"> |
| <h3>CONNECT WITH THE DEVELOPER</h3> |
| <div class="social-links"> |
| <a href="https://www.facebook.com/" target="_blank" class="social-btn">📘 Facebook</a> |
| <a href="https://github.com/pathum25" target="_blank" class="social-btn">🐙 GitHub</a> |
| <a href="https://huggingface.co/Pq234" target="_blank" class="social-btn">🤗 Hugging Face</a> |
| <a href="https://wa.me/94767605853" target="_blank" class="social-btn">💬 WhatsApp</a> |
| </div> |
| <div class="creator-credit">Created by <strong>A.P.PATHUm LAKMAL</strong> © 2026</div> |
| </div> |
| </div> |
| |
| <script> |
| // --- ROBOT STATE --- |
| let state = { |
| servers: { |
| 'Server1': { role: 'Primary', canWrite: true, cssClass: 'status-primary' }, |
| 'Server2': { role: 'Secondary', canWrite: false, cssClass: 'status-secondary' }, |
| 'Server3': { role: 'Secondary', canWrite: false, cssClass: 'status-excluded' } |
| } |
| }; |
| |
| // --- DOM ELEMENTS --- |
| const logFeed = document.getElementById('logFeed'); |
| const uptimeDisplay = document.getElementById('robotUptime'); |
| const chatMessages = document.getElementById('chatMessages'); |
| const chatInput = document.getElementById('chatInput'); |
| const typingIndicator = document.getElementById('typingIndicator'); |
| |
| // --- UPTIME TIMER --- |
| let seconds = 0; |
| setInterval(() => { |
| seconds++; |
| const hrs = String(Math.floor(seconds / 3600)).padStart(2, '0'); |
| const mins = String(Math.floor((seconds % 3600) / 60)).padStart(2, '0'); |
| const secs = String(seconds % 60).padStart(2, '0'); |
| uptimeDisplay.textContent = `${hrs}:${mins}:${secs}`; |
| document.getElementById('cpuLoad').textContent = Math.floor(Math.random() * 30 + 5) + '%'; |
| }, 1000); |
| |
| // --- CORE FUNCTIONS --- |
| function addLog(message, type = 'info') { |
| const entry = document.createElement('div'); |
| entry.className = `log-line log-${type}`; |
| entry.innerHTML = `<span style="color:#555;">[${new Date().toLocaleTimeString()}]</span> ${message}`; |
| logFeed.appendChild(entry); |
| logFeed.scrollTop = logFeed.scrollHeight; |
| } |
| |
| function renderUI() { |
| const grid = document.getElementById('serverGrid'); |
| const primaryDisplay = document.getElementById('currentPrimaryDisplay'); |
| let html = ''; |
| let primaryName = ''; |
| |
| for (const [name, data] of Object.entries(state.servers)) { |
| if (data.role === 'Primary') primaryName = name; |
| |
| let jobBtnHtml = (data.role === 'Primary') |
| ? `<button class="primary-act" style="padding:5px 15px; font-size:0.8rem; margin-top:10px;" onclick="simulateJobRun('${name}')">Run AutoUpsert</button>` |
| : `<button disabled style="padding:5px 15px; font-size:0.8rem; margin-top:10px;">[BLOCKED]</button>`; |
| |
| html += ` |
| <div class="server-card"> |
| <h3>${name}</h3> |
| <div class="status-badge ${data.cssClass}">${data.role}</div> |
| <div class="db-box ha"><strong>agDatabase:</strong> ${data.canWrite ? '<span style="color:var(--neon-green);">WRITABLE</span>' : '<span style="color:#ff3366;">READ-ONLY</span>'}</div> |
| ${jobBtnHtml} |
| </div> |
| `; |
| } |
| grid.innerHTML = html; |
| primaryDisplay.textContent = primaryName; |
| } |
| |
| function simulateFailover(targetServer) { |
| if (state.servers[targetServer].role === 'Primary') { |
| addLog(`[ABORT] Failover to ${targetServer} rejected. Already Active Primary.`, 'error'); |
| return; |
| } |
| |
| for (const key in state.servers) { |
| state.servers[key].role = 'Secondary'; |
| state.servers[key].canWrite = false; |
| state.servers[key].cssClass = (key === 'Server3') ? 'status-excluded' : 'status-secondary'; |
| } |
| |
| state.servers[targetServer].role = 'Primary'; |
| state.servers[targetServer].canWrite = true; |
| state.servers[targetServer].cssClass = 'status-primary'; |
| |
| addLog(`⚠️ [FAILOVER] ${targetServer} is now ACTIVE PRIMARY.`, 'warn'); |
| renderUI(); |
| return `Successfully failed over to ${targetServer}. It is now the Primary node.`; |
| } |
| |
| function simulateJobRun(serverName) { |
| const server = state.servers[serverName]; |
| addLog(`📝 Attempting job execution on ${serverName}...`, 'info'); |
| |
| if (server.role === 'Primary') { |
| addLog(`✅ [SUCCESS] AutoUpsert executed on ${serverName}.`, 'success'); |
| return `SUCCESS: Job executed on ${serverName} (Primary). Data written to agDatabase.`; |
| } |
| else if (server.role === 'Secondary' && serverName === 'Server2') { |
| addLog(`⚠️ [BLOCKED] Job triggered on ${serverName}. Replica is Secondary.`, 'error'); |
| return `WARNING: Job triggered on ${serverName}, but blocked! Secondary nodes cannot execute write commands.`; |
| } |
| else if (server.role === 'Secondary' && serverName === 'Server3') { |
| addLog(`⛔ [FAILED] ${serverName} is excluded from this AG.`, 'error'); |
| return `ERROR: ${serverName} is excluded. No AutoUpsert job exists here.`; |
| } |
| } |
| |
| function resetSimulation() { |
| state.servers = { |
| 'Server1': { role: 'Primary', canWrite: true, cssClass: 'status-primary' }, |
| 'Server2': { role: 'Secondary', canWrite: false, cssClass: 'status-secondary' }, |
| 'Server3': { role: 'Secondary', canWrite: false, cssClass: 'status-excluded' } |
| }; |
| renderUI(); |
| addLog(`🔄 [RESET] Orchestrator restored to default.`, 'warn'); |
| return "System reset to default. Server1 is Primary."; |
| } |
| |
| // --- AI CHATBOT LOGIC (Read, Write, Scan, Execute) --- |
| function addChatMessage(text, sender = 'bot') { |
| const msgDiv = document.createElement('div'); |
| msgDiv.className = `msg ${sender}`; |
| msgDiv.innerHTML = `<div class="bubble">${text}</div>`; |
| chatMessages.appendChild(msgDiv); |
| chatMessages.scrollTop = chatMessages.scrollHeight; |
| } |
| |
| async function processAICommand(input) { |
| const lowerInput = input.toLowerCase(); |
| typingIndicator.style.display = 'block'; |
| |
| // Simulate AI Processing Delay |
| await new Promise(r => setTimeout(r, 1500)); |
| typingIndicator.style.display = 'none'; |
| |
| let response = ""; |
| |
| // --- AI Logic Interpreters --- |
| if (lowerInput.includes("hello") || lowerInput.includes("hi") || lowerInput.includes("hey")) { |
| response = "Greetings! I am A.P.PATHUm LAKMAL's AI Orchestrator. Type 'help' to see what I can do."; |
| } |
| else if (lowerInput.includes("help")) { |
| response = "I can read, write, scan, and execute! Try: \n- 'Scan Server 2'\n- 'What is the primary server?'\n- 'Run job on Server 1'\n- 'Failover to Server 3'"; |
| } |
| else if (lowerInput.includes("scan") || lowerInput.includes("status")) { |
| let target = "all"; |
| if(lowerInput.includes("server 1")) target = "Server1"; |
| else if(lowerInput.includes("server 2")) target = "Server2"; |
| else if(lowerInput.includes("server 3")) target = "Server3"; |
| |
| if(target === "all") { |
| let s1 = state.servers['Server1']; |
| let s2 = state.servers['Server2']; |
| let s3 = state.servers['Server3']; |
| response = `System Scan Complete:\n[Server1] Role: ${s1.role}, Write Access: ${s1.canWrite ? 'Yes' : 'No'}\n[Server2] Role: ${s2.role}, Write Access: ${s2.canWrite ? 'Yes' : 'No'}\n[Server3] Role: ${s3.role}, Write Access: ${s3.canWrite ? 'Yes' : 'No'} (Excluded)`; |
| } else { |
| let data = state.servers[target]; |
| response = `Scanning ${target}...\nRole: ${data.role}\nWriteable: ${data.canWrite ? 'Yes' : 'No'}`; |
| } |
| } |
| else if (lowerInput.includes("primary") || lowerInput.includes("active node")) { |
| for (const [name, data] of Object.entries(state.servers)) { |
| if(data.role === 'Primary') response = `The current Active Primary node is: ${name}`; |
| } |
| } |
| else if (lowerInput.includes("failover") || lowerInput.includes("switch")) { |
| let target = "Server2"; |
| if(lowerInput.includes("server 3")) target = "Server3"; |
| else if(lowerInput.includes("server 2")) target = "Server2"; |
| |
| response = simulateFailover(target); |
| } |
| else if (lowerInput.includes("run job") || lowerInput.includes("execute job")) { |
| let target = "Server1"; |
| if(lowerInput.includes("server 2")) target = "Server2"; |
| else if(lowerInput.includes("server 3")) target = "Server3"; |
| else if(lowerInput.includes("s1")) target = "Server1"; |
| else if(lowerInput.includes("s2")) target = "Server2"; |
| else if(lowerInput.includes("s3")) target = "Server3"; |
| |
| response = simulateJobRun(target); |
| } |
| else if (lowerInput.includes("reset") || lowerInput.includes("restart")) { |
| response = resetSimulation(); |
| } |
| else { |
| response = "Command not recognized. Try: 'Scan Server 2', 'What is primary?', 'Run job on Server 1', 'Failover to Server 3', or 'Reset'."; |
| } |
| |
| addChatMessage(response, 'bot'); |
| } |
| |
| function handleChatSend() { |
| const text = chatInput.value.trim(); |
| if (!text) return; |
| addChatMessage(text, 'user'); |
| chatInput.value = ''; |
| processAICommand(text); |
| } |
| |
| function handleChatEnter(event) { |
| if (event.key === 'a95ed830a894d236c6d989391fb786a56f65304b') handleChatSend(); |
| } |
| |
| // --- INIT --- |
| renderUI(huggingface); |
| addLog("[READY] AI System Bot is online. Type commands in the chat!", 'success'); |
| </YAML (/ˈjæməl/ ⓘ YAM-əl) is a human-readable data serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted. YAML targets many of the same communications applications as Extensible Markup Language (XML) but has a minimal syntax that intentionally differs from Standard Generalized Markup Language (SGML).[3] It uses Python-style indentation to indicate nesting[3] and does not require quotes around most string values (it also supports JSON style [...] and {...} mixed in the same file).[4] |
| |
| YAMLFilename extensions.yaml, .ymlInternet media typeapplication/yaml[1]Uniform Type Identifier (UTI)public.yaml[2]Initial release11 May 2001; 25 years agoLatest release |
|
|
| 1.2 (Revision 1.2.2) |
| 1 October 2021; 4 years ago |
|
|
| Type of formatData interchangeOpen format?YesWebsiteyaml.org |
|
|
| Custom data types are allowed, but YAML natively encodes scalars (such as strings, integers, and floats), lists, and associative arrays (also known as maps, dictionaries or hashmaps). These data types are based on the Perl programming language, though all commonly used high-level programming languages share very similar concepts.[5][6][7] The colon-centered syntax, used for expressing key-value pairs, is inspired by electronic mail headers as defined in RFC 822, and the document separator --- is borrowed from MIME (RFC 2046). Escape sequences are reused from C, and whitespace wrapping for multi-line strings is inspired by HTML. Lists and hashes can contain nested lists and hashes, forming a tree structure; arbitrary graphs can be represented using YAML aliases (similar to XML in SOAP).[3] YAML is intended to be read and written in streams, a feature inspired by SAX.[3] |
|
|
| Support for reading and writing YAML is available for many programming languages.[8] Some source-code editors such as Vim,[9] Emacs,[10] and various integrated development environments[11][12][13] have features that make editing YAML easier, such as folding up nested structures or automatically highlighting syntax errors. |
|
|
| The official recommended filename extension for YAML files has been .yaml since 2006.[14] In 2024, the MIME type application/yaml has been finalized.[1] |
|
|
| > |
| </body> |
| </html> |