{"id":33617,"date":"2026-04-17T12:02:58","date_gmt":"2026-04-17T04:02:58","guid":{"rendered":"https:\/\/www.hkmu.edu.hk\/oetools\/?page_id=33617"},"modified":"2026-04-17T16:04:56","modified_gmt":"2026-04-17T08:04:56","slug":"openmaic","status":"publish","type":"page","link":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/","title":{"rendered":"OpenMAIC"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"33617\" class=\"elementor elementor-33617\" data-elementor-settings=\"[]\">\n\t\t\t\t\t\t\t<div class=\"elementor-section-wrap\">\n\t\t\t\t\t\t\t<section class=\"has_eae_slider wavo-column-gap-default elementor-section elementor-top-section elementor-element elementor-element-b375907 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"b375907\" data-element_type=\"section\" data-settings=\"{&quot;jet_parallax_layout_list&quot;:[],&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"has_eae_slider elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-af73566\" data-id=\"af73566\" data-element_type=\"column\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t\t<div class=\"elementor-element elementor-element-79649ea elementor-widget elementor-widget-html\" data-id=\"79649ea\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n    <title>109 OpenMAIC<\/title>\r\n    <link rel=\"stylesheet\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.css\">\r\n    <style>\r\n        :root {--primary-color:#0f2e63;--primary-light:#2a4a8a;--primary-dark:#1a202c;--primary-blue:#6495ED;--accent-color:#0096D6;--accent-green:#7AC143;--light-gray:#edf2f7;--medium-gray:#e0e0e0;--dark-gray:#707070;--success-color:#7AC143;--danger-color:#f44336;--warning-color:#ff9800;--info-color:#0096D6;--primary-red:#e53e3e;--accent-orange:#ed8936;--dark-text:#2d3748;--light-text:#718096;--card-bg:#ffffff;--bg-light:#f7fafc;--shadow:0 4px 12px rgba(0,0,0,0.15);--border-radius:12px;--small-radius:8px;--box-shadow:0 2px 8px rgba(0,0,0,0.1);--box-shadow-hover:0 8px 25px rgba(0,0,0,0.15);--transition:all 0.3s ease;--spacing-xs:8px;--spacing-sm:16px;--spacing-md:24px;--spacing-lg:32px;--spacing-xl:48px;--spacing-xxl:64px;--text-white:#ffffff;--font-serif:'Georgia','Times New Roman',serif;--font-sans:'Segoe UI',-apple-system,BlinkMacSystemFont,'Roboto',sans-serif;--card-light-bg:rgba(255,255,255,0.05);--logo-light-bg:rgba(255,255,255,0.1);}\r\n        * {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', sans-serif;}\r\n        body {background-color: var(--bg-light);color: var(--dark-text);font-size: 1rem;line-height: 1.6;scroll-behavior: smooth;}\r\n        #main-container {max-width: 100%;margin: 0 auto;background-color: #0F284A;min-height: 100vh;}\r\n        #content-wrapper {position: relative;}\r\n        main {width: 100%;max-width: 1400px;margin: 0 auto;padding: 0 var(--spacing-sm);}\r\n        .font-btn {background-color: var(--primary-color);color: white;border: none;border-radius: var(--small-radius);padding: 8px 15px;cursor: pointer;font-size: 1rem;transition: var(--transition);}\r\n        .font-btn:hover {background-color: var(--primary-light);transform: translateY(-2px);}\r\n        h1 {font-size: clamp(2rem, 5vw, 3.5rem);color: white;text-align: center;padding: var(--spacing-xl) var(--spacing-sm);margin-bottom: 0;font-weight: 700;text-shadow: 2px 2px 4px rgba(0,0,0,0.3);}\r\n        h2 {font-size: clamp(1.5rem, 4vw, 2.2rem);color: var(--primary-color);margin-bottom: var(--spacing-md);padding-bottom: var(--spacing-sm);border-bottom: 2px solid var(--medium-gray);display: flex;align-items: center;text-shadow: 1px 1px 2px rgba(148, 148, 148, 0.5);}\r\n        h3 {font-size: clamp(1.1rem, 3vw, 1.4rem);margin: var(--spacing-lg) 0 var(--spacing-sm) 0;color: var(--primary-color);}\r\n        p {margin-bottom: var(--spacing-sm);line-height: 1.7;}\r\n        a {text-decoration: none;color: var(--primary-color);transition: var(--transition);}\r\n        a:hover {color: var(--accent-color);}\r\n        section {background-color: white;padding: var(--spacing-xl) var(--spacing-lg);margin-bottom: var(--spacing-md);border-radius: var(--border-radius);box-shadow: var(--box-shadow);transition: var(--transition);position: relative;overflow: hidden;}\r\n        section:hover {box-shadow: var(--box-shadow-hover);transform: translateY(-2px);}\r\n        #educational-scenarios-section {background-color: #0F284A;color: white;}\r\n        #educational-scenarios-section h2,\r\n        #educational-scenarios-section h3,\r\n        #educational-scenarios-section h4,\r\n        #educational-scenarios-section p {color: white;}\r\n        #educational-scenarios-section .scenario {background-color: rgba(255, 255, 255, 0.1);color: white;}\r\n        #educational-scenarios-section .scenario h4 {color: var(--accent-green);}\r\n        #video-demo-section {background-color: #0F284A;color: white;}\r\n        #video-demo-section h2 {color: white;border-bottom-color: rgba(255,255,255,0.3);}\r\n        .faq-section {background-color: #0F284A !important;color: white;}\r\n        .faq-section h2 {color: white;border-bottom-color: rgba(255,255,255,0.3);}\r\n        #key-features-list {margin: var(--spacing-lg) 0;padding: 0;list-style: none;display: grid;gap: var(--spacing-sm);}\r\n        #key-features-list li {background-color: rgba(122, 193, 67, 0.1);padding: var(--spacing-sm);border-radius: var(--small-radius);border-left: 4px solid var(--accent-green);transition: var(--transition);}\r\n        #key-features-list li:hover {background-color: rgba(122, 193, 67, 0.2);transform: translateX(5px);}\r\n        #faq-grid {display: grid;grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));gap: var(--spacing-md);margin-top: var(--spacing-lg);perspective: 1000px;}\r\n        .flip-card {background-color: transparent;height: 140px;perspective: 1000px;}\r\n        .flip-card-inner {position: relative;width: 100%;height: 100%;text-align: center;transition: transform 0.6s;transform-style: preserve-3d;box-shadow: var(--box-shadow);border-radius: var(--border-radius);}\r\n        .flip-card:hover .flip-card-inner {transform: rotateY(180deg);}\r\n        .flip-card-front, .flip-card-back {position: absolute;width: 100%;height: 100%;-webkit-backface-visibility: hidden;backface-visibility: hidden;border-radius: var(--border-radius);display: flex;align-items: center;justify-content: center;padding: var(--spacing-sm);}\r\n        .flip-card:nth-child(odd) .flip-card-front {background: linear-gradient(135deg, #A9D486, #7AC143);color: white;}\r\n        .flip-card:nth-child(even) .flip-card-front {background: linear-gradient(135deg, #5CBABF, #0096D6);color: white;}\r\n        .flip-card:nth-child(odd) .flip-card-back {background: linear-gradient(135deg, #7AC143, #5a8f32);color: white;transform: rotateY(180deg);}\r\n        .flip-card:nth-child(even) .flip-card-back {background: linear-gradient(135deg, #0096D6, #0077B3);color: white;transform: rotateY(180deg);}\r\n        .faq-question, .faq-answer {font-weight: 600;font-size: 1rem;line-height: 1.4;text-align: center;}\r\n        #tool-logo {float: left;width: 100px;height: 100px;margin: 0 var(--spacing-lg) var(--spacing-md) 0;border-radius: var(--border-radius);overflow: hidden;box-shadow: var(--box-shadow);transition: var(--transition);display: flex;align-items: center;justify-content: center;background-color: white;opacity: 1;}\r\n        #tool-logo:hover {transform: scale(1.05);box-shadow: var(--box-shadow-hover);}\r\n        #tool-logo img {max-width: 100%;max-height: 100%;width: auto;height: auto;object-fit: contain;}\r\n        #specifications-list {display: grid;grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));gap: var(--spacing-md);margin-top: var(--spacing-lg);clear: both;}\r\n        .spec-item {background: linear-gradient(135deg, rgba(92, 186, 191, 0.1), rgba(122, 193, 67, 0.1));padding: var(--spacing-md);border-radius: var(--border-radius);border: 1px solid rgba(92, 186, 191, 0.2);transition: var(--transition);}\r\n        .spec-item:hover {background: linear-gradient(135deg, rgba(92, 186, 191, 0.2), rgba(122, 193, 67, 0.2));box-shadow: var(--box-shadow);transform: translateY(-3px);}\r\n        .spec-title {font-weight: 600;margin-bottom: var(--spacing-xs);font-size: 1.1rem;color: var(--primary-color);}\r\n        .spec-value {color: var(--dark-text);font-size: 0.95rem;line-height: 1.5;}\r\n        #video-container {position: relative;height: 350px;max-width: 100%;margin: 0 auto;border-radius: var(--border-radius);box-shadow: var(--box-shadow-hover);overflow: hidden;transition: var(--transition);}\r\n        #video-container:hover {transform: translateY(-5px);box-shadow: 0 12px 30px rgba(0,0,0,0.2);}\r\n        #video-container iframe {position: absolute;top: 0;left: 0;width: 100%;height: 100%;border: none;border-radius: var(--border-radius);}\r\n        #function-carousel {position: relative;width: 100%;display: flex;gap: 0;margin: var(--spacing-lg) 0;background: linear-gradient(135deg, #f9f9f9, #ffffff);border-radius: var(--border-radius);box-shadow: var(--box-shadow);transition: var(--transition);min-height: 300px;overflow: hidden;}\r\n        #carousel-navigation {width: 280px;padding: var(--spacing-md);background: linear-gradient(135deg, var(--light-gray), #e8f4f8);border-radius: var(--border-radius) 0 0 var(--border-radius);overflow-y: auto;}\r\n        .nav-item {padding: var(--spacing-sm) var(--spacing-md);margin-bottom: var(--spacing-sm);cursor: pointer;border-radius: var(--small-radius);transition: var(--transition);font-weight: 500;color: var(--primary-color);background: linear-gradient(135deg, #CAECA8, #b8e293);box-shadow: 0 2px 4px rgba(0,0,0,0.1);border: 1px solid rgba(122, 193, 67, 0.2);}\r\n        .nav-item:hover {background: linear-gradient(135deg, var(--accent-color), #0077B3);color: white;transform: translateX(5px);box-shadow: 0 4px 8px rgba(0,0,0,0.15);}\r\n        .nav-item.active {background: linear-gradient(135deg, var(--accent-color), #0077B3);color: white;font-weight: 600;}\r\n        #carousel-content {flex: 1;padding: var(--spacing-lg);display: flex;flex-direction: column;}\r\n        #carousel-image {width: 100%;height: 100%;border-radius: var(--small-radius);overflow: hidden;box-shadow: var(--box-shadow);background-color: #f5f5f5;display: flex;align-items: center;justify-content: center;position: relative;}\r\n        #carousel-image img {max-width: 100%;max-height: 100%;width: auto;height: auto;object-fit: contain;transition: opacity 0.3s ease;}\r\n        #toggle-container {display: flex;justify-content: center;margin-bottom: var(--spacing-xl);}\r\n        #perspective-toggle {display: flex;background: linear-gradient(135deg, #50A2AC, #0096D6);border-radius: 50px;padding: 6px;box-shadow: var(--box-shadow);position: relative;}\r\n        .toggle-option {padding: var(--spacing-sm) var(--spacing-lg);cursor: pointer;border-radius: 45px;transition: var(--transition);position: relative;z-index: 2;font-weight: 500;color: white;}\r\n        .toggle-option.active {background: linear-gradient(135deg, #8DB47B, #7AC143);color: white;font-weight: 600;box-shadow: 0 2px 8px rgba(0,0,0,0.2);}\r\n        #perspectives-wrapper {position: relative;min-height: 400px;}\r\n        #educators-scenarios, #learners-scenarios {position: absolute;width: 100%;top: 0;transition: transform 0.5s ease, opacity 0.5s ease;opacity: 0;transform: translateX(-20px);pointer-events: none;}\r\n        #educators-scenarios.active, #learners-scenarios.active {opacity: 1;transform: translateX(0);position: relative;pointer-events: auto;}\r\n        .scenario {background: linear-gradient(135deg, rgba(255,255,255,0.1), rgba(255,255,255,0.05));border-radius: var(--border-radius);padding: var(--spacing-lg);margin-bottom: var(--spacing-md);box-shadow: 0 4px 15px rgba(0,0,0,0.1);transition: var(--transition);border: 1px solid rgba(255,255,255,0.1);}\r\n        .scenario:hover {transform: translateY(-3px);box-shadow: 0 8px 25px rgba(0,0,0,0.15);background: linear-gradient(135deg, rgba(255,255,255,0.15), rgba(255,255,255,0.1));}\r\n        .scenario h4 {color: var(--accent-green);margin-bottom: var(--spacing-sm);font-size: 1.2rem;display: flex;align-items: center;}\r\n        .scenario h4:before {content: \"\";display: inline-block;width: 12px;height: 12px;background-color: var(--accent-green);border-radius: 50%;margin-right: var(--spacing-sm);box-shadow: 0 0 0 3px rgba(122, 193, 67, 0.3);}\r\n        @media (max-width: 1200px) {main {padding: 0 var(--spacing-md);}}\r\n        @media (max-width: 1024px) {section {padding: var(--spacing-lg) var(--spacing-md);}#function-carousel {flex-direction: column;    min-height: auto;}#carousel-navigation {width: 100%;    border-radius: var(--border-radius) var(--border-radius) 0 0;    display: flex;    overflow-x: auto;    padding: var(--spacing-md);    gap: var(--spacing-sm);}.nav-item {white-space: nowrap;    margin-bottom: 0;    flex-shrink: 0;}.nav-item:hover {transform: translateY(-3px);}#carousel-content {padding: var(--spacing-md);}#carousel-image {min-height: 300px;}}\r\n        @media (max-width: 768px) {:root {--spacing-xs: 6px;    --spacing-sm: 12px;    --spacing-md: 18px;    --spacing-lg: 24px;    --spacing-xl: 32px;    --spacing-xxl: 48px;}main {padding: 0 var(--spacing-sm);}section {padding: var(--spacing-md) var(--spacing-sm);    margin-bottom: var(--spacing-sm);}h1 {padding: var(--spacing-lg) var(--spacing-sm);}#faq-grid {grid-template-columns: 1fr;    gap: var(--spacing-sm);}.flip-card {height: 120px;}#tool-logo {float: none;    margin: 0 auto var(--spacing-md);    display: block;    width: 80px;    height: 80px;}#specifications-list {grid-template-columns: 1fr;    gap: var(--spacing-sm);    margin-top: var(--spacing-md);}#video-container {width: 100%;    max-width: 500px;    height: 281px;    margin: var(--spacing-md) auto;}#carousel-image {min-height: 200px;}.toggle-option {padding: var(--spacing-sm) var(--spacing-md);    font-size: 0.9rem;}.scenario {padding: var(--spacing-md);}}\r\n        @media (max-width: 480px) {section {padding: var(--spacing-sm);}h1 {font-size: 1.8rem;    padding: var(--spacing-md) var(--spacing-sm);}h2 {font-size: 1.3rem;    margin-bottom: var(--spacing-sm);}#specifications-list {grid-template-columns: 1fr;}#video-container {width: 100%;    height: 225px;}#carousel-image {min-height: 150px;}.flip-card {height: 100px;}.faq-question, .faq-answer {font-size: 0.9rem;}.toggle-option {padding: var(--spacing-xs) var(--spacing-sm);    font-size: 0.8rem;}#carousel-navigation {padding: var(--spacing-sm);}.nav-item {padding: var(--spacing-xs) var(--spacing-sm);    font-size: 0.9rem;}}\r\n        @keyframes fadeInUp {from {opacity: 0;    transform: translateY(30px);}to {opacity: 1;    transform: translateY(0);}}\r\n        @keyframes spin {0% { transform: rotate(0deg);}100% { transform: rotate(360deg);}}\r\n        section {animation: fadeInUp 0.6s ease-out;}\r\n        section:nth-child(1) { animation-delay: 0.1s;}\r\n        section:nth-child(2) { animation-delay: 0.2s;}\r\n        section:nth-child(3) { animation-delay: 0.3s;}\r\n        section:nth-child(4) { animation-delay: 0.4s;}\r\n        section:nth-child(5) { animation-delay: 0.5s;}\r\n        section:nth-child(6) { animation-delay: 0.6s;}\r\n        @media (prefers-reduced-motion: no-preference) {html {scroll-behavior: smooth;}}\r\n        *:focus {outline: 2px solid var(--accent-color);outline-offset: 2px;}\r\n        .tab-container {display: flex;padding: 20px;gap: 20px;}\r\n        .tab-options {width: 30%;background-color: #f5f5f5;border-radius: var(--border-radius);padding: 15px;}\r\n        .tab-option {padding: 12px 15px;margin-bottom: 10px;color: var(--primary-color);background-color: white;border-left: 3px solid var(--accent-color);cursor: pointer;transition: var(--transition);border-radius: 4px;}\r\n        .tab-option:hover {background-color: rgba(0, 150, 214, 0.1);transform: translateX(5px);}\r\n        .tab-option.active {background-color: var(--accent-color);color: white;font-weight: bold;}\r\n        .tab-content {width: 70%;background-color: white;color: var(--primary-color);border-radius: var(--border-radius);padding: 20px;box-shadow: var(--box-shadow);list-style-position: inside;}\r\n        .tab-panel {display: none;}\r\n        .tab-panel.active {display: block;animation: fadeIn 0.5s ease;}\r\n\t\t.tab-content img {max-width: 100%;height: auto;}\r\n        @media (max-width: 768px) {.tab-container {flex-direction: column;}.tab-options, .tab-content {width: 100%;}}\r\n        td {padding-left: 1px;vertical-align: top;min-width: 25px;}\r\n        @keyframes fadeIn {from { opacity: 0;}to { opacity: 1;}}\r\n        .related-tools-section {background-color: #0F284A;color: white;padding: var(--spacing-xl) var(--spacing-lg);margin-bottom: var(--spacing-md);border-radius: var(--border-radius);}\r\n        .related-tools-section h2 {color: white;border-bottom-color: rgba(255,255,255,0.3);margin-bottom: var(--spacing-lg);}\r\n        .related-tools-container {max-width: 100%;margin: 0 auto;position: relative;}\r\n        .related-tools-swiper {padding: 20px 50px;overflow: visible;}\r\n        .related-tool-card {border-radius: 8px;padding: 20px;text-align: center;transition: all 0.2s ease;backdrop-filter: blur(10px);border: 1px solid rgba(255, 255, 255, 0.12);position: relative;overflow: hidden;background: rgba(255, 255, 255, 0.05);height: auto;display: flex;flex-direction: column;}\r\n        .related-tool-card::before {content: '';position: absolute;top: 0;left: 0;right: 0;height: 3px;background: linear-gradient(90deg, var(--accent-green), var(--primary-blue));}\r\n        .related-tool-card:hover {transform: translateY(-4px);box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);border-color: rgba(255, 255, 255, 0.25);}\r\n        .related-tool-card:focus-within {outline: 2px solid var(--primary-blue);outline-offset: 2px;}\r\n        .related-tool-logo {width: 100px;height: 100px;margin: 0 auto 20px;border-radius: 20px;overflow: hidden;display: flex;align-items: center;justify-content: center;aspect-ratio: 1 \/ 1;background: rgba(255, 255, 255, 0.1);border: 1px solid rgba(0, 0, 0, 0.05);}\r\n        .related-tool-logo img {width: 85%;height: 85%;aspect-ratio: 1 \/ 1;object-fit: cover;}\r\n        .related-tool-name {font-family: var(--font-serif);font-size: 1.1rem;font-weight: 700;margin-bottom: 12px;color: var(--text-white);letter-spacing: 0.02em;}\r\n        .related-tool-description {font-family: var(--font-sans);font-size: 0.9rem;color: var(--text-white);text-align: center;line-height: 1.6;display: -webkit-box;-webkit-line-clamp: 3;line-clamp: 3;-webkit-box-orient: vertical;overflow: hidden;flex-grow: 1;}\r\n        .related-tool-link {text-decoration: none;color: inherit;display: block;height: 100%;}\r\n        .related-tools-swiper .swiper-button-prev,\r\n        .related-tools-swiper .swiper-button-next {color: white;background: rgba(255, 255, 255, 0.1);width: 40px;height: 40px;border-radius: 50%;backdrop-filter: blur(10px);border: 1px solid rgba(255, 255, 255, 0.2);}\r\n        .related-tools-swiper .swiper-button-prev:after,\r\n        .related-tools-swiper .swiper-button-next:after {font-size: 20px;font-weight: bold;}\r\n        .related-tools-swiper .swiper-button-prev:hover,\r\n        .related-tools-swiper .swiper-button-next:hover {background: rgba(255, 255, 255, 0.2);transform: scale(1.1);}\r\n        @media (max-width: 1024px) {.related-tools-swiper {padding: 20px 50px;}}\r\n        @media (max-width: 768px) {.related-tools-swiper {padding: 20px 40px;}.related-tool-card {padding: 15px;}}\r\n        @media (max-width: 480px) {.related-tools-swiper {padding: 20px 30px;}}\r\n    <\/style>\r\n<\/head>\r\n<body>\r\n    <script>\r\n        const GITHUB_ITEMS_URL = 'https:\/\/raw.githubusercontent.com\/oetools\/Free_AI_Tools_Hub_Home_Page\/refs\/heads\/main\/items.json';\r\n        let remoteItemsData = [];\r\nconst allItems = { \"Var_A\": \"OpenMAIC\", \"Var_B\": \"109\",  \"Var_C\": \"OpenMAIC (Open Multi-Agent Interactive Classroom) is an open-source AI platform that transforms any topic description or uploaded document into an immersive, interactive classroom experience. Developed by the THU-MAIC team at Tsinghua University, it was first introduced through academic research published in the Journal of Computer Science and Technology (JCST 2026), aiming to build a complete virtual classroom ecosystem. The platform moves beyond passive video lectures by leveraging large language model (LLM) orchestration and multi-agent collaboration to simulate an authentic classroom environment populated by AI teachers, teaching assistants, and classmates with distinct personas. Its primary audience includes university students, independent learners, K-12 students, enterprise trainees, and educators who seek active, personalized, and socially rich online learning experiences.\",  \"Var_D_A\": \"One-Click Lesson Generation: Generates complete interactive lessons from any topic description or uploaded document (e.g., PDF research papers). It uses a two-stage pipeline: a Plan agent creates a structured outline, followed by scene agents that generate rich multimedia scenes in parallel.\", \"Var_D_B\": \"Multi-Agent Classroom Dynamics: Orchestrates AI agents with distinct personas to enable classroom discussions, roundtable debates, and Q&A sessions, recreating the social dynamics of real learning environments. The AI teacher conducts voice lectures and operates the whiteboard, while AI classmates actively ask questions and discuss.\", \"Var_D_C\": \"Rich Scene Types: Produces intelligent slide lectures with voice narration and spotlight effects, interactive quizzes with AI grading, browser-based HTML simulations, and structured project-based learning (PBL) activities.\", \"Var_D_D\": \"Collaborative Whiteboard: AI agents draw on a shared whiteboard in real time to solve equations, sketch flowcharts, illustrate diagrams, or write formulas, making abstract concepts visually intuitive.\", \"Var_D_E\": \"Voice Interaction & TTS: Delivers natural text-to-speech narration with multiple voice providers, and supports automatic speech recognition for hands-free participation in discussions.\", \"Var_D_F\": \"Export & Integration: Exports lessons to editable PowerPoint (.pptx) or self-contained interactive HTML files. It integrates with messaging apps (Feishu, Slack, Telegram, Discord, WhatsApp, etc.) via OpenClaw, allowing users to call the AI assistant and generate courses directly without opening a webpage.\", \"Var_D_G\": \"\", \"Var_D_H\": \"\", \"Var_D_I\": \"\", \"Var_D_J\": \"\",\"Var_E\": \"OpenMAIC stands out by offering a complete, open-source AI classroom that simulates genuine pedagogical interactions through multi-agent orchestration. Unlike basic flashcard or video tools, it generates dynamic, scene-rich lessons with voice, whiteboard, and peer-like agents, all validated with over 700 students at Tsinghua University across two years. Its ability to handle diverse inputs (topic text or document uploads) and produce multiple output formats (slides, quizzes, simulations, PBL) makes it adaptable to nearly any subject. \", \"Var_F_A\": \"Yes\", \"Var_F_B\": \"No\", \"Var_F_C\": \"Yes\", \"Var_F_D\": \"\", \"Var_F_E\": \"NLP, Speech Recognition, TTS, Content Generation, Workflow Automation\",\r\n\r\n\t\t\t\/\/ Specifications\r\n\"Var_G_A\": \"https:\/\/openmaic.io\/ \",  \"Var_G_B\": \"China \",  \"Var_G_C\": \"THU-MAIC Team\",  \"Var_G_D\": \"Freemium \",  \"Var_G_E\": \"Web, Windows, macOS\",  \"Var_G_F\": \"Multilingual \",  \"Var_G_G\": \"Yes\",  \"Var_G_H\": \"No\",  \"Var_G_I\": \"No\",  \"Var_G_J\": \"Yes\",  \"Var_G_K\": \"https:\/\/www.hkmu.edu.hk\/oetools\/wp-content\/uploads\/sites\/86\/2026\/04\/109-OpenMAIC-Logo.png\",\r\n\/\/ Classifications\r\n\t\t\t\/\/ Video  URLs\r\n\"Var_I_A\": \"<iframe src='https:\/\/player.vimeo.com\/video\/1146473854?badge=0&autopause=0&player_id=0&app_id=58479&byline=0&portrait=0&title=0&texttrack=en' frameborder='0' allow='autoplay; fullscreen; encrypted-media; web-share' referrerpolicy='strict-origin-when-cross-origin' title='6 Brisk Teaching ' style='width: 100%; height: 100%;'><\/iframe>\",\"Var_J_Title_A\": \"\",\"Var_J_Title_B\": \"\", \"Var_J_Title_C\": \"\", \"Var_J_Title_D\": \"\", \"Var_J_Title_E\": \"\", \"Var_J_Title_F\": \"\", \"Var_J_A\": \"\",  \"Var_J_B\": \"\",  \"Var_J_C\": \"\",  \"Var_J_D\": \"\",  \"Var_J_E\": \"\",  \"Var_J_F\": \"\", \r\n\r\n\r\n\t\t\t\/\/ Educational Scenarios\r\n\"Var_K_A\": \"Flipped Classroom with AI-Generated Primers (Higher Education): A university professor teaching advanced machine learning uploads a new research paper to OpenMAIC and generates a 15-minute interactive lesson with slides, key concept quizzes, and a whiteboard explanation. Professors can easily create professional courseware for subjects like 'Introduction to Artificial Intelligence' or have the AI explain complex concepts like the Taylor series. Students review this AI-generated primer before class, ensuring they arrive with foundational knowledge and can spend lecture time on deeper discussion and problem-solving.\", \"Var_K_B\": \"Multi-Perspective Debate for Critical Thinking: In a philosophy course, the instructor uses the roundtable debate mode, configuring AI agents with different schools of thought (e.g., utilitarianism vs. deontology). Students observe the debate, then are called upon by the AI teacher to interject their own arguments, fostering critical analysis without requiring multiple human participants.\", \"Var_K_C\": \"Automated Project-Based Learning Scaffolding (Corporate Training & Enterprise): For a capstone engineering design course or corporate compliance training, the educator provides a project brief (e.g., 'design a solar-powered water pump'). OpenMAIC generates a structured PBL activity with role assignments (project manager, engineer, evaluator), milestone checklists, and simulated client feedback sessions, allowing students or new employees to practice collaboration in a low-stakes, simulated business environment.\", \"Var_L_A\": \"Self-Paced Programming Fundamentals (Lifelong Learning): A student new to computer science or a zero-foundation learner enters the topic 'Teach me Python loops and conditionals in 30 minutes'. OpenMAIC generates a complete lesson with narrated slides, code examples, an interactive coding simulation, and a short-answer quiz. The AI teaching assistant provides instant feedback on the student's quiz responses and suggests additional practice.\", \"Var_L_B\": \"Interactive Research Paper Analysis: A graduate student uploads a dense PDF of a computational biology paper or the latest DeepSeek research. OpenMAIC breaks the paper into digestible scenes: a slide overview of the problem, a whiteboard animation of the proposed algorithm, and a simulated data exploration tool. The student can ask the AI teacher clarifying questions in real time, with answers illustrated on the whiteboard.\", \"Var_L_C\": \"Language Immersion and K-12 Conceptual Learning: A younger student can join a math thinking camp to learn abstract concepts like general relativity or play interactive math games like the chicken-and-rabbit problem. Alternatively, a learner preparing for a study abroad program in Germany sets the topic 'Intermediate German: Discussing environmental policies'. OpenMAIC creates a roundtable debate among AI classmates with varying viewpoints (activist, industry representative, scientist), all speaking in German with TTS. The learner joins the debate via voice recognition, receiving contextual vocabulary hints from the AI teaching assistant.\",\r\n};\r\n\r\n        async function loadRemoteData() {\r\n            try {\r\n                console.log('Starting to load remote data...');\r\n                \r\n                const CACHE_KEY_ITEMS = 'faith_items_cache';\r\n                try {\r\n                    const cachedItems = localStorage.getItem(CACHE_KEY_ITEMS);\r\n                    if (cachedItems) {\r\n                        remoteItemsData = JSON.parse(cachedItems);\r\n                        console.log('Loaded items from cache:', remoteItemsData.length);\r\n                    }\r\n                } catch (cacheError) {\r\n                    console.warn('Error loading from cache:', cacheError);\r\n                }\r\n                \r\n                const itemsResponse = await fetch(GITHUB_ITEMS_URL);\r\n                if (itemsResponse.ok) {\r\n                    remoteItemsData = await itemsResponse.json();\r\n                    localStorage.setItem(CACHE_KEY_ITEMS, JSON.stringify(remoteItemsData));\r\n                    console.log('Items loaded from network:', remoteItemsData.length);\r\n                } else {\r\n                    console.error('Failed to load items:', itemsResponse.statusText);\r\n                }\r\n            } catch (error) {\r\n                console.error('Error loading remote data:', error);\r\n            }\r\n        }\r\n    <\/script>\r\n    \r\n    <div id=\"main-container\">\r\n        <header>\r\n            <h1 id=\"tool-name\"><\/h1>\r\n        <\/header>\r\n        \r\n        <div id=\"content-wrapper\">\r\n            <main>\r\n                <section id=\"introduction-section\">\r\n                    <div class=\"font-controls\" style=\"margin-top: 0px; text-align: right;\">\r\n                        <h4>Font Size:\r\n                            <button id=\"decrease-font\" class=\"font-btn\" style=\"margin-right: 5px;\" aria-label=\"Decrease font size\">-<\/button>\r\n                            <button id=\"reset-font\" class=\"font-btn\" style=\"margin-right: 5px;\" aria-label=\"Reset font size\">Aa<\/button>\r\n                            <button id=\"increase-font\" class=\"font-btn\" aria-label=\"Increase font size\">+<\/button>\r\n                        <\/h4>\r\n                    <\/div>\r\n                    <h2>Introduction<\/h2>\r\n                    <div id=\"intro-text\"><\/div>\r\n                    <h3>Key Features<\/h3>\r\n                    <ul id=\"key-features-list\"><\/ul>\r\n                    <h3>Uniqueness<\/h3>\r\n                    <div id=\"uniqueness-text\"><\/div>\r\n                <\/section>\r\n\r\n                <section id=\"faq-section\" class=\"faq-section\">\r\n                    <h2>Frequently Asked Questions<\/h2>\r\n                    <div id=\"faq-grid\">\r\n                        <div class=\"flip-card\">\r\n                            <div class=\"flip-card-inner\">\r\n                                <div class=\"flip-card-front\">\r\n                                    <div class=\"faq-question\">Open-Source?<\/div>\r\n                                <\/div>\r\n                                <div class=\"flip-card-back\">\r\n                                    <div class=\"faq-answer\" id=\"faq-answer-1\"><\/div>\r\n                                <\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n                        <div class=\"flip-card\">\r\n                            <div class=\"flip-card-inner\">\r\n                                <div class=\"flip-card-front\">\r\n                                    <div class=\"faq-question\">Registration Needed?<\/div>\r\n                                <\/div>\r\n                                <div class=\"flip-card-back\">\r\n                                    <div class=\"faq-answer\" id=\"faq-answer-2\"><\/div>\r\n                                <\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n                        <div class=\"flip-card\">\r\n                            <div class=\"flip-card-inner\">\r\n                                <div class=\"flip-card-front\">\r\n                                    <div class=\"faq-question\">Installation Required?<\/div>\r\n                                <\/div>\r\n                                <div class=\"flip-card-back\">\r\n                                    <div class=\"faq-answer\" id=\"faq-answer-3\"><\/div>\r\n                                <\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n                        <div class=\"flip-card\">\r\n                            <div class=\"flip-card-inner\">\r\n                                <div class=\"flip-card-front\">\r\n                                    <div class=\"faq-question\">AI-empowered?<\/div>\r\n                                <\/div>\r\n                                <div class=\"flip-card-back\">\r\n                                    <div class=\"faq-answer\" id=\"faq-answer-5\"><\/div>\r\n                                <\/div>\r\n                            <\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/section>\r\n                \r\n                <section id=\"specifications-section\">\r\n                    <h2>Specifications<\/h2>\r\n                    <div id=\"tool-logo\"><\/div>\r\n                    <div id=\"specifications-list\">\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">URL: <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-url\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Country or Region: <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-country\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Author(s): <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-authors\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Availability: <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-license\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Operating System(s): <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-os\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Language(s): <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-languages\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Registration Needed: <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-registration\"><\/div>\r\n                        <\/div>\r\n                        <div class=\"spec-item\">\r\n                            <div class=\"spec-title\">Installation Required: <\/div>\r\n                            <div class=\"spec-value\" id=\"spec-installation\"><\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/section>\r\n                <section id=\"video-demo-section\">\r\n                    <h2>Video Demonstration<\/h2>\r\n                    <div id=\"video-container\"><\/div>\r\n                <\/section>\r\n                \r\n                <section id=\"function-list-section\">\r\n                    \r\n    <h2>User Guide<\/h2>\r\n    <div class='tab-container'>\r\n        <div class='tab-options'>\r\n            <div class='tab-option active' data-tab='tab0'>OpenMAIC<\/div>\r\n            <div class='tab-option' data-tab='tab1'>1. Login to OpenMAIC<\/div>\r\n            <div class='tab-option' data-tab='tab2'>2. Generate Interactive Classroom<\/div>\r\n            <div class='tab-option' data-tab='tab3'>3. Study in Multi-Agent Classroom<\/div>\r\n            <div class='tab-option' data-tab='tab4'>4. Export and Share the Lesson<\/div>\r\n        <\/div>\r\n        <div class='tab-content'>\r\n            <div class='tab-panel active' id='tab0'>\r\n                <p><b>This guide introduces a selection of key features from OpenMAIC, including: Login to OpenMAIC, Generate Interactive Classroom, Study in Multi-Agent Classroom, and Export and Share the Lesson.<\/b><\/p>\r\n                <img src='https:\/\/www.hkmu.edu.hk\/oetools\/wp-content\/uploads\/sites\/86\/2026\/04\/100-Tools-screenshot-as-of-109-by-17Apr2026.png' width='831' height='454'>\r\n            <\/div>\r\n            <div class='tab-panel' id='tab1'>\r\n                <h3>1. Login to OpenMAIC<\/h3>\r\n                <table class='userguide'>\r\n                    <tr>\r\n                        <td>a.<\/td>\r\n                        <td>Navigate to the website: <b>https:\/\/open.maic.chat\/<\/b><i>(Note: This guide covers the hosted demo version which requires no local installation)<\/i>;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>b.<\/td>\r\n                        <td>Click the <b>Login<\/b> button located in the top-right corner of the page;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>c.<\/td>\r\n                        <td>Register or log in with an email or phone number <i>(Note: The discussion function requires a login to use)<\/i>.<\/td>\r\n                    <\/tr>\r\n                <\/table>\r\n            <\/div>\r\n            <div class='tab-panel' id='tab2'>\r\n                <h3>2. Generate Interactive Classroom<\/h3>\r\n                <table class='userguide'>\r\n                    <tr>\r\n                        <td>a.<\/td>\r\n                        <td>Navigate to the central chat input box on the homepage;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>b.<\/td>\r\n                        <td>Input a prompt describing the topic for study <i>(Note: Select the <b>attachment<\/b> icon to upload PDF files for the AI to analyse)<\/i>;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>c.<\/td>\r\n                        <td>Configure the <b>Classroom Role<\/b> by clicking the <b>Read to learn together<\/b> button to assign AI personas;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>d.<\/td>\r\n                        <td>Choose from the preset roles or select <b>Auto Generate<\/b> to allow the system to define participants;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>e.<\/td>\r\n                        <td>Select the <b>Enter Classroom<\/b> button to begin the course generation.<\/td>\r\n                    <\/tr>\r\n                <\/table>\r\n            <\/div>\r\n            <div class='tab-panel' id='tab3'>\r\n                <h3>3. Study in Multi-Agent Classroom<\/h3>\r\n                <table class='userguide'>\r\n                    <tr>\r\n                        <td>a.<\/td>\r\n                        <td>Select the newly generated lesson card to open the virtual classroom;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>b.<\/td>\r\n                        <td>Click the <b>Play<\/b> button to start the lesson;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>c.<\/td>\r\n                        <td>Click the <b>Talking bubble<\/b> icon in the bottom-right corner to view the Notes and Chat;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>d.<\/td>\r\n                        <td>Type a message to start <b>Q&A Mode<\/b>;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>e.<\/td>\r\n                        <td>Input messages into the chat panel on the right to converse with the AI teacher and classmates;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>f.<\/td>\r\n                        <td>Click the <b>pen icon<\/b> on the bottom menu to view the AI Whiteboard;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>g.<\/td>\r\n                        <td>Click the <b>Toggle sidebar<\/b> icon in the bottom-left corner, located above the AI teacher portrait icon;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>h.<\/td>\r\n                        <td>View the generated <b>courseware overview<\/b> in the left sidebar and select a different section to study.<\/td>\r\n                    <\/tr>\r\n                <\/table>\r\n            <\/div>\r\n            <div class='tab-panel' id='tab4'>\r\n                <h3>4. Export and Share the Lesson<\/h3>\r\n                <table class='userguide'>\r\n                    <tr>\r\n                        <td>a.<\/td>\r\n                        <td>Locate the <b>Export PPTX<\/b> button in the top-right corner of the page;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>b.<\/td>\r\n                        <td>Click the <b>Export PPTX<\/b> option to download the slides;<\/td>\r\n                    <\/tr>\r\n                    <tr>\r\n                        <td>c.<\/td>\r\n                        <td>Choose the <b>Export Resource Pack<\/b> function to export PPTX and interactive pages.<\/td>\r\n                    <\/tr>\r\n                <\/table>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n                \r\n                <\/section>\r\n \r\n                <section id=\"educational-scenarios-section\">\r\n                    <h2>Educational Scenarios<\/h2>\r\n                    <div id=\"toggle-container\">\r\n                        <div id=\"perspective-toggle\">\r\n                            <div class=\"toggle-option\" id=\"educators-toggle\">Educators' Perspectives<\/div>\r\n                            <div class=\"toggle-option\" id=\"learners-toggle\">Learners' Perspectives<\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                    \r\n                    <div id=\"perspectives-wrapper\">\r\n                        <div id=\"educators-scenarios\" class=\"active\">\r\n                        <\/div>\r\n                        \r\n                        <div id=\"learners-scenarios\">\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/section>\r\n                \r\n                <section id=\"related-tools-section\" class=\"related-tools-section\" style=\"display: none;\">\r\n                    <h2>Related Tools<\/h2>\r\n                    <div class=\"related-tools-container\">\r\n                        <div class=\"swiper related-tools-swiper\">\r\n                            <div class=\"swiper-wrapper\" id=\"relatedToolsWrapper\">\r\n                            <\/div>\r\n                            <div class=\"swiper-button-prev\"><\/div>\r\n                            <div class=\"swiper-button-next\"><\/div>\r\n                        <\/div>\r\n                    <\/div>\r\n                <\/section>\r\n            <\/main>\r\n        <\/div>\r\n    <\/div>\r\n    \r\n    <!-- Swiper JS -->\r\n    <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/swiper@11\/swiper-bundle.min.js\"><\/script>\r\n    \r\n    <script>\r\n        function renderItems() {\r\n            document.getElementById('tool-name').textContent = allItems.Var_A;\r\n            document.getElementById('intro-text').textContent = allItems.Var_C;\r\n            const keyFeaturesList = document.getElementById('key-features-list');\r\n            [\r\n                allItems.Var_D_A, allItems.Var_D_B, allItems.Var_D_C, allItems.Var_D_D,\r\n            ].filter(feature => feature !== \"\").forEach(feature => {\r\n                const li = document.createElement('li');\r\n                if (feature.includes(':')) {\r\n                    const parts = feature.split(':');\r\n                    li.innerHTML = `<strong>${parts[0]}:<\/strong>${parts.slice(1).join(':')}`;\r\n                } else {\r\n                    li.textContent = feature;\r\n                }\r\n                keyFeaturesList.appendChild(li);\r\n            });\r\n            document.getElementById('uniqueness-text').textContent = allItems.Var_E;\r\n            document.getElementById('faq-answer-1').textContent = allItems.Var_F_A;\r\n            document.getElementById('faq-answer-2').textContent = allItems.Var_F_B;\r\n            document.getElementById('faq-answer-3').textContent = allItems.Var_F_C;\r\n            document.getElementById('faq-answer-5').textContent = allItems.Var_F_E;\r\n            const toolLogo = document.getElementById('tool-logo');\r\n            const logoImg = document.createElement('img');\r\n            logoImg.src = allItems.Var_G_K;\r\n            logoImg.alt = `${allItems.Var_A} Logo`;\r\n            logoImg.onload = function() {\r\n                toolLogo.appendChild(logoImg);\r\n            };\r\n            \r\n            logoImg.onerror = function() {\r\n                console.error(\"Failed to load logo image\");\r\n                toolLogo.innerHTML = `<div style=\"color: var(--accent-color); font-size: 3rem; text-align: center;\">\r\n                    ${allItems.Var_A.charAt(0)}\r\n                <\/div>`;\r\n            };\r\n            document.getElementById('spec-url').innerHTML = `<a href=\"${allItems.Var_G_A}\" target=\"_blank\">${allItems.Var_G_A}<\/a>`;\r\n            document.getElementById('spec-country').textContent = allItems.Var_G_B;\r\n            document.getElementById('spec-authors').textContent = allItems.Var_G_C;\r\n            document.getElementById('spec-license').textContent = allItems.Var_G_D;\r\n            document.getElementById('spec-os').textContent = allItems.Var_G_E;\r\n            document.getElementById('spec-languages').textContent = allItems.Var_G_F;\r\n            document.getElementById('spec-registration').textContent = allItems.Var_G_H;\r\n            document.getElementById('spec-installation').textContent = allItems.Var_G_I;\r\n            const videoContainer = document.getElementById('video-container');\r\n            if (allItems.Var_I_A) {\r\n                videoContainer.innerHTML = allItems.Var_I_A;\r\n            }\r\n            const educatorsScenarios = document.getElementById('educators-scenarios');\r\n            [allItems.Var_K_A, allItems.Var_K_B, allItems.Var_K_C].forEach((scenario, index) => {\r\n                if (scenario) {\r\n                    const scenarioDiv = document.createElement('div');\r\n                    scenarioDiv.className = 'scenario';\r\n                    \r\n                    const scenarioTitle = document.createElement('h4');\r\n                    const colonIndex = scenario.indexOf(':');\r\n                    scenarioTitle.textContent = colonIndex !== -1 ? scenario.substring(0, colonIndex) : `Scenario ${index + 1}`;\r\n                    \r\n                    const scenarioContent = document.createElement('p');\r\n                    scenarioContent.textContent = colonIndex !== -1 ? scenario.substring(colonIndex + 1).trim() : scenario;\r\n                    \r\n                    scenarioDiv.appendChild(scenarioTitle);\r\n                    scenarioDiv.appendChild(scenarioContent);\r\n                    educatorsScenarios.appendChild(scenarioDiv);\r\n                }\r\n            });\r\n\r\n            const learnersScenarios = document.getElementById('learners-scenarios');\r\n            [allItems.Var_L_A, allItems.Var_L_B, allItems.Var_L_C].forEach((scenario, index) => {\r\n                if (scenario) {\r\n                    const scenarioDiv = document.createElement('div');\r\n                    scenarioDiv.className = 'scenario';\r\n                    const scenarioTitle = document.createElement('h4');\r\n                    const colonIndex = scenario.indexOf(':');\r\n                    scenarioTitle.textContent = colonIndex !== -1 ? scenario.substring(0, colonIndex) : `Scenario ${index + 1}`;\r\n                    const scenarioContent = document.createElement('p');\r\n                    scenarioContent.textContent = colonIndex !== -1 ? scenario.substring(colonIndex + 1).trim() : scenario;\r\n                    scenarioDiv.appendChild(scenarioTitle);\r\n                    scenarioDiv.appendChild(scenarioContent);\r\n                    learnersScenarios.appendChild(scenarioDiv);\r\n                }\r\n            });\r\n        }\r\n        function findRelatedTools() {\r\n            if (!remoteItemsData || remoteItemsData.length === 0) {\r\n                console.warn('Remote items data not loaded yet');\r\n                return [];\r\n            }\r\n\r\n            const currentToolName = allItems.Var_A;\r\n            const currentTool = remoteItemsData.find(item => item.name === currentToolName);\r\n            if (!currentTool) {\r\n                console.warn(`Current tool \"${currentToolName}\" not found in remote data`);\r\n                return [];\r\n            }\r\n\r\n            const currentCategories = currentTool.categories || [];\r\n            \r\n            if (currentCategories.length === 0) {\r\n                console.warn(`No categories found for current tool \"${currentToolName}\"`);\r\n                return [];\r\n            }\r\n\r\n            const relatedTools = remoteItemsData.filter(item => {\r\n                if (item.name === currentToolName) {\r\n                    return false;\r\n                }\r\n                \r\n                const itemCategories = item.categories || [];\r\n                return itemCategories.some(category => currentCategories.includes(category));\r\n            });\r\n\r\n            console.log(`Found ${relatedTools.length} related tools for \"${currentToolName}\"`);\r\n            return relatedTools;\r\n        }\r\n\r\n        let relatedToolsSwiper = null;\r\n        \r\n        function renderRelatedTools() {\r\n            const relatedTools = findRelatedTools();\r\n            const wrapper = document.getElementById('relatedToolsWrapper');\r\n            \r\n            if (!wrapper) {\r\n                console.error('Related tools wrapper not found');\r\n                return;\r\n            }\r\n\r\n            wrapper.innerHTML = '';\r\n\r\n            if (relatedTools.length === 0) {\r\n                const section = document.getElementById('related-tools-section');\r\n                if (section) {\r\n                    section.style.display = 'none';\r\n                }\r\n                return;\r\n            }\r\n\r\n            const section = document.getElementById('related-tools-section');\r\n            if (section) {\r\n                section.style.display = 'block';\r\n            }\r\n\r\n            relatedTools.forEach(tool => {\r\n                const slide = document.createElement('div');\r\n                slide.className = 'swiper-slide';\r\n\r\n                const card = document.createElement('div');\r\n                card.className = 'related-tool-card';\r\n                const link = document.createElement('a');\r\n                link.href = tool.url || '#';\r\n                link.className = 'related-tool-link';\r\n                link.target = '_blank';\r\n                link.rel = 'noopener noreferrer';\r\n                const logoDiv = document.createElement('div');\r\n                logoDiv.className = 'related-tool-logo';\r\n                logoDiv.innerHTML = tool.logo || '';\r\n                const nameDiv = document.createElement('div');\r\n                nameDiv.className = 'related-tool-name';\r\n                nameDiv.textContent = tool.name || '';\r\n                const descDiv = document.createElement('div');\r\n                descDiv.className = 'related-tool-description';\r\n                descDiv.textContent = tool.description || '';\r\n                link.appendChild(logoDiv);\r\n                link.appendChild(nameDiv);\r\n                link.appendChild(descDiv);\r\n                card.appendChild(link);\r\n                slide.appendChild(card);\r\n                wrapper.appendChild(slide);\r\n            });\r\n\r\n            if (relatedToolsSwiper) {\r\n                relatedToolsSwiper.destroy(true, true);\r\n            }\r\n\r\n            relatedToolsSwiper = new Swiper('.related-tools-swiper', {\r\n                slidesPerView: 4,\r\n                spaceBetween: 24,\r\n                navigation: {\r\n                    nextEl: '.swiper-button-next',\r\n                    prevEl: '.swiper-button-prev',\r\n                },\r\n                breakpoints: {\r\n                    320: {\r\n                        slidesPerView: 1,\r\n                        spaceBetween: 16\r\n                    },\r\n                    480: {\r\n                        slidesPerView: 2,\r\n                        spaceBetween: 16\r\n                    },\r\n                    768: {\r\n                        slidesPerView: 3,\r\n                        spaceBetween: 20\r\n                    },\r\n                    1024: {\r\n                        slidesPerView: 4,\r\n                        spaceBetween: 24\r\n                    }\r\n                }\r\n            });\r\n        }\r\n        \r\n        let tabsInitialized = false;\r\n        function initFunctionTabs() {\r\n            if (tabsInitialized) {\r\n                return;\r\n            }\r\n            const tabOptions = document.querySelectorAll('.tab-option');\r\n            const tabPanels = document.querySelectorAll('.tab-panel');\r\n            \r\n            if (tabOptions.length === 0 || tabPanels.length === 0) {\r\n                return;\r\n            }\r\n            tabOptions.forEach(option => {\r\n                option.addEventListener('click', () => {\r\n                    tabOptions.forEach(opt => opt.classList.remove('active'));\r\n                    tabPanels.forEach(panel => panel.classList.remove('active'));\r\n                    option.classList.add('active');\r\n                    const tabId = option.getAttribute('data-tab');\r\n                    const targetPanel = document.getElementById(tabId);\r\n                    if (targetPanel) {\r\n                        targetPanel.classList.add('active');\r\n                    }\r\n                });\r\n            });\r\n            \r\n            tabsInitialized = true;\r\n        }\r\n\r\n        document.addEventListener('DOMContentLoaded', function() {\r\n            initFunctionTabs();\r\n        });\r\n\r\n        function initializeCarousel() {\r\n            const carouselTitles = [\r\n                allItems.Var_J_Title_A, allItems.Var_J_Title_B, allItems.Var_J_Title_C, allItems.Var_J_Title_D, allItems.Var_J_Title_E, allItems.Var_J_Title_F,\r\n            ].filter(title => title !== \"\");\r\n            \r\n            const carouselImages = [\r\n                allItems.Var_J_A, allItems.Var_J_B, allItems.Var_J_C, allItems.Var_J_D, allItems.Var_J_E, allItems.Var_J_F,\r\n            ].filter(img => img !== \"\");\r\n            \r\n            if (carouselImages.length === 0) {\r\n                document.getElementById('function-list-section').style.display = 'none';\r\n                return;\r\n            }\r\n            let currentSlide = 0;\r\n            const totalSlides = carouselImages.length;\r\n            const navContainer = document.getElementById('carousel-navigation');\r\n            carouselTitles.forEach((title, index) => {\r\n                const navItem = document.createElement('div');\r\n                navItem.className = 'nav-item';\r\n                navItem.textContent = title;\r\n                navItem.addEventListener('click', () => {\r\n                    currentSlide = index;\r\n                    updateCarousel(currentSlide, carouselTitles, carouselImages);\r\n                });\r\n                navContainer.appendChild(navItem);\r\n            });\r\n            updateCarousel(currentSlide, carouselTitles, carouselImages);\r\n            document.addEventListener('keydown', function(e) {\r\n                const rect = document.getElementById('carousel-image').getBoundingClientRect();\r\n                const isInViewport = rect.top < window.innerHeight && rect.bottom >= 0;\r\n                \r\n                if (isInViewport) {\r\n                    if (e.key === 'ArrowUp') {\r\n                        currentSlide = (currentSlide - 1 + totalSlides) % totalSlides;\r\n                        updateCarousel(currentSlide, carouselTitles, carouselImages);\r\n                    } else if (e.key === 'ArrowDown') {\r\n                        currentSlide = (currentSlide + 1) % totalSlides;\r\n                        updateCarousel(currentSlide, carouselTitles, carouselImages);\r\n                    }\r\n                }\r\n            });\r\n        }\r\n\r\n        function updateCarousel(slideIndex, titles, images) {\r\n            const navItems = document.querySelectorAll('.nav-item');\r\n            navItems.forEach((item, index) => {\r\n                if (index === slideIndex) {\r\n                    item.classList.add('active');\r\n                } else {\r\n                    item.classList.remove('active');\r\n                }\r\n            });\r\n            const imageContainer = document.getElementById('carousel-image');\r\n            imageContainer.innerHTML = '<div style=\"width: 50px; height: 50px; border: 5px solid #f3f3f3; border-top: 5px solid var(--accent-color); border-radius: 50%; animation: spin 1s linear infinite;\"><\/div>';\r\n            \r\n            const newImg = new Image();\r\n            newImg.src = images[slideIndex];\r\n            newImg.alt = titles[slideIndex] || \"Function demonstration\";\r\n            newImg.style.opacity = '0';\r\n            newImg.style.transition = 'opacity 0.3s ease';\r\n            \r\n            newImg.onload = function() {\r\n                imageContainer.innerHTML = '';\r\n                imageContainer.appendChild(newImg);\r\n                void newImg.offsetWidth;\r\n                newImg.style.opacity = '1';\r\n            };\r\n            \r\n            newImg.onerror = function() {\r\n                imageContainer.innerHTML = '<div style=\"text-align: center; padding: 20px;\"><p>Image could not be loaded<\/p><\/div>';\r\n            };\r\n        }\r\n\r\n        function setupPerspectiveToggle() {\r\n            const educatorsToggle = document.getElementById('educators-toggle');\r\n            const learnersToggle = document.getElementById('learners-toggle');\r\n            const educatorsScenarios = document.getElementById('educators-scenarios');\r\n            const learnersScenarios = document.getElementById('learners-scenarios');\r\n            educatorsToggle.classList.add('active');\r\n            educatorsScenarios.classList.add('active');\r\n            educatorsToggle.addEventListener('click', function() {\r\n                if (!educatorsToggle.classList.contains('active')) {\r\n                    learnersToggle.classList.remove('active');\r\n                    educatorsToggle.classList.add('active');\r\n                    learnersScenarios.style.transform = 'translateX(20px)';\r\n                    learnersScenarios.style.opacity = '0';\r\n                    \r\n                    setTimeout(() => {\r\n                        learnersScenarios.classList.remove('active');\r\n                        educatorsScenarios.classList.add('active');\r\n\r\n                        setTimeout(() => {\r\n                            educatorsScenarios.style.transform = 'translateX(0)';\r\n                            educatorsScenarios.style.opacity = '1';\r\n                        }, 50);\r\n                    }, 300);\r\n                }\r\n            });\r\n            \r\n            learnersToggle.addEventListener('click', function() {\r\n                if (!learnersToggle.classList.contains('active')) {\r\n                    educatorsToggle.classList.remove('active');\r\n                    learnersToggle.classList.add('active');\r\n                    educatorsScenarios.style.transform = 'translateX(-20px)';\r\n                    educatorsScenarios.style.opacity = '0';\r\n                    setTimeout(() => {\r\n                        educatorsScenarios.classList.remove('active');\r\n                        learnersScenarios.classList.add('active');\r\n                        \r\n                        setTimeout(() => {\r\n                            learnersScenarios.style.transform = 'translateX(0)';\r\n                            learnersScenarios.style.opacity = '1';\r\n                        }, 50);\r\n                    }, 300);\r\n                }\r\n            });\r\n            \r\n            const perspectivesWrapper = document.getElementById('perspectives-wrapper');\r\n            let touchStartX = 0;\r\n            let touchEndX = 0;\r\n            \r\n            perspectivesWrapper.addEventListener('touchstart', function(e) {\r\n                touchStartX = e.changedTouches[0].screenX;\r\n            }, { passive: true });\r\n            \r\n            perspectivesWrapper.addEventListener('touchend', function(e) {\r\n                touchEndX = e.changedTouches[0].screenX;\r\n                handleSwipe();\r\n            }, { passive: true });\r\n            \r\n            document.addEventListener('keydown', function(e) {\r\n                const rect = document.getElementById('educational-scenarios-section').getBoundingClientRect();\r\n                const isInViewport = rect.top < window.innerHeight && rect.bottom >= 0;\r\n                \r\n                if (isInViewport) {\r\n                    if (e.key === 'Tab' && e.shiftKey) {\r\n                        e.preventDefault();\r\n                        \r\n                        if (educatorsToggle.classList.contains('active')) {\r\n                            learnersToggle.click();\r\n                        } else {\r\n                            educatorsToggle.click();\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n            \r\n            function handleSwipe() {\r\n                const swipeThreshold = 50;\r\n                \r\n                if (touchEndX < touchStartX - swipeThreshold) {\r\n                    if (educatorsToggle.classList.contains('active')) {\r\n                        learnersToggle.click();\r\n                    }\r\n                }\r\n                \r\n                if (touchEndX > touchStartX + swipeThreshold) {\r\n                    if (learnersToggle.classList.contains('active')) {\r\n                        educatorsToggle.click();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        \r\n        function initFontControls() {\r\n            const decreaseBtn = document.getElementById('decrease-font');\r\n            const resetBtn = document.getElementById('reset-font');\r\n            const increaseBtn = document.getElementById('increase-font');\r\n            let currentFontSize = 16;\r\n            function updateFontSizes() {\r\n                document.body.style.fontSize = `${currentFontSize}px`; \r\n                const elementsToSize = [\r\n                    'p', 'li', 'div', 'span', 'a', 'section', \r\n                    '.spec-value', '.faq-question', '.faq-answer',\r\n                    '.scenario p', '.toggle-option', '.nav-item'\r\n                ];\r\n                \r\n                elementsToSize.forEach(selector => {\r\n                    document.querySelectorAll(selector).forEach(el => {\r\n                        el.style.fontSize = `${currentFontSize}px`;\r\n                    });\r\n                });\r\n            }\r\n            \r\n            decreaseBtn.addEventListener('click', function() {\r\n                if (currentFontSize > 12) {\r\n                    currentFontSize -= 1;\r\n                    updateFontSizes();\r\n                }\r\n            });\r\n            \r\n            resetBtn.addEventListener('click', function() {\r\n                currentFontSize = 16;\r\n                updateFontSizes();\r\n            });\r\n            \r\n            increaseBtn.addEventListener('click', function() {\r\n                if (currentFontSize < 24) {\r\n                    currentFontSize += 1;\r\n                    updateFontSizes();\r\n                }\r\n            });\r\n        }\r\n        \r\n        window.addEventListener('DOMContentLoaded', async function() {\r\n            renderItems();\r\n            setupPerspectiveToggle();\r\n            initFunctionTabs();\r\n            initFontControls();\r\n            await loadRemoteData();\r\n            renderRelatedTools();\r\n            \r\n            document.querySelectorAll('a[href^=\"#\"]').forEach(anchor => {\r\n                anchor.addEventListener('click', function (e) {\r\n                    e.preventDefault();\r\n                    const targetId = this.getAttribute('href').substring(1);\r\n                    const targetElement = document.getElementById(targetId);\r\n                    \r\n                    if (targetElement) {\r\n                        targetElement.scrollIntoView({\r\n                            behavior: 'smooth'\r\n                        });\r\n                    }\r\n                });\r\n            });\r\n        });\r\n\r\n    <\/script>\r\n<\/body>\r\n<\/html>\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>&nbsp; &nbsp; &nbsp; Font Size: - Aa + Introduction Key Features Uniqueness Frequently Asked Questions Open-Source? Registration Needed? Installation Required? AI-empowered? Specifications URL: Country or Region: Author(s): Availability: Operating System(s): Language(s): Registration Needed: Installation Required: Video Demonstration User Guide OpenMAIC 1. Login to OpenMAIC 2. Generate Interactive Classroom 3. Study in Multi-Agent Classroom 4. Export...<\/p>\n","protected":false},"author":748,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"redux-templates_canvas","meta":{"_expiration-date-status":"","_expiration-date":0,"_expiration-date-type":"","_expiration-date-categories":[],"_expiration-date-options":[]},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v17.3 (Yoast SEO v21.2) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>OpenMAIC - Hong Kong Metropolitan University<\/title>\n<meta name=\"description\" content=\"OpenMAIC is an AI platform from Tsinghua University that turns any topic into an interactive virtual classroom. AI teachers, teaching assistants, and classmates with distinct personas collaborate to create active, personalized learning experiences.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"OpenMAIC\" \/>\n<meta property=\"og:description\" content=\"&nbsp; &nbsp; &nbsp; Font Size: - Aa + Introduction Key Features Uniqueness Frequently Asked Questions Open-Source? Registration Needed? Installation\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/\" \/>\n<meta property=\"og:site_name\" content=\"Hong Kong Metropolitan University\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-17T08:04:56+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.hkmu.edu.hk\/oetools\/wp-content\/uploads\/sites\/86\/2026\/04\/100-Tools-screenshot-as-of-109-by-17Apr2026.png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"2 minutes\" \/>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"OpenMAIC - Hong Kong Metropolitan University","description":"OpenMAIC is an AI platform from Tsinghua University that turns any topic into an interactive virtual classroom. AI teachers, teaching assistants, and classmates with distinct personas collaborate to create active, personalized learning experiences.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/","og_locale":"en_US","og_type":"article","og_title":"OpenMAIC","og_description":"&nbsp; &nbsp; &nbsp; Font Size: - Aa + Introduction Key Features Uniqueness Frequently Asked Questions Open-Source? Registration Needed? Installation","og_url":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/","og_site_name":"Hong Kong Metropolitan University","article_modified_time":"2026-04-17T08:04:56+00:00","og_image":[{"url":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-content\/uploads\/sites\/86\/2026\/04\/100-Tools-screenshot-as-of-109-by-17Apr2026.png"}],"twitter_card":"summary_large_image","twitter_misc":{"Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/","url":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/","name":"OpenMAIC - Hong Kong Metropolitan University","isPartOf":{"@id":"https:\/\/www.hkmu.edu.hk\/oetools\/#website"},"datePublished":"2026-04-17T04:02:58+00:00","dateModified":"2026-04-17T08:04:56+00:00","description":"OpenMAIC is an AI platform from Tsinghua University that turns any topic into an interactive virtual classroom. AI teachers, teaching assistants, and classmates with distinct personas collaborate to create active, personalized learning experiences.","breadcrumb":{"@id":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.hkmu.edu.hk\/oetools\/openmaic\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Open Educational Tools","item":"\/oetools\/"},{"@type":"ListItem","position":2,"name":"OpenMAIC"}]},{"@type":"WebSite","@id":"https:\/\/www.hkmu.edu.hk\/oetools\/#website","url":"https:\/\/www.hkmu.edu.hk\/oetools\/","name":"Hong Kong Metropolitan University","description":"Open Educational Tools - Hong Kong Metropolitan University","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.hkmu.edu.hk\/oetools\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"}]}},"_links":{"self":[{"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/pages\/33617"}],"collection":[{"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/users\/748"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/comments?post=33617"}],"version-history":[{"count":12,"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/pages\/33617\/revisions"}],"predecessor-version":[{"id":33667,"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/pages\/33617\/revisions\/33667"}],"wp:attachment":[{"href":"https:\/\/www.hkmu.edu.hk\/oetools\/wp-json\/wp\/v2\/media?parent=33617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}