Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.


HTML
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dicionário de Dados - TOTVS</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Roboto', Tahoma'Oxygen', Geneva'Ubuntu', Verdana'Cantarell', sans-serif;
            background: linear-gradient(135deg, #f5f7fa#667eea 0%, #c3cfe2#764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .release-notes-container {
            max-width: 1400px1600px;
            margin: 0 auto;
            background: white;
            border-radius: 12px16px;
            box-shadow: 0 10px20px 40px60px rgba(0, 0, 0, 0.13);
            overflow: hidden;
        }
        
        .header {
            background: linear-gradient(135deg, #0A2333 0%, #004D80 50%, #007BFF 100%);
            color: white;
            padding: 30px40px 40px50px;
            position: relative;
            overflow: hidden;
        }
        
        .header::before {
            content: '';
            position: absolute;
            top: 0-50%;
            right: 0-10%;
            width: 60%800px;
            height: 100%800px;
            background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200"><path d="M0,0 L200,0 L200,200 L0,200 Z" fill="none"/><path d="M0,100 Q50,50 100,100 T200,100" stroke="rgba(255,255,255,0.1)" stroke-width="2" fill="none"/><path d="M0,120 Q50,70 100,120 T200,120" stroke="rgba(255,255,255,0.1)" stroke-width="2" fill="none"/><path d="M0,80 Q50,30 100,80 T200,80" stroke="rgba(255,255,255,0.1)" stroke-width="2" fill="none"/></svg>') no-repeat;radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
            border-radius: 50%;
        }
        
            background-size: cover;.header::after {
            opacitycontent: 0.3'';
        }
    position: absolute;
    
        bottom: .header-content {-30%;
            positionleft: relative-5%;
            z-indexwidth: 1600px;
            displayheight: flex600px;
            align-items: centerbackground: radial-gradient(circle, rgba(255,255,255,0.08) 0%, transparent 70%);
            gapborder-radius: 20px50%;
        }
        
        .totvsheader-logocontent {
            displayposition: flexrelative;
            alignz-itemsindex: center1;
            gapdisplay: 12pxflex;
        }
    align-items: center;
   
         .totvs-icon {gap: 30px;
        }
    width: 50px;
   
         height: 50px;.totvs-logo {
            backgrounddisplay: whiteflex;
            borderalign-radiusitems: 8pxcenter;
            displaygap: flex15px;
            alignflex-itemsshrink: center0;
        }
       justify-content: center;
        .totvs-icon {
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2)width: 60px;
            positionheight: relative60px;
        }
    background: white;
    
        .totvsborder-icon svg {radius: 12px;
            widthdisplay: 32pxflex;
            heightalign-items: 32pxcenter;
        }
    justify-content: center;
   
         .totvs-text {box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
            font-size: 28pxtransition: transform 0.3s ease;
        }
    font-weight: 700;
    
        letter.totvs-spacingicon:hover 2px;{
            text-shadowtransform: 0 2px 4px rgba(0, 0, 0, 0.2scale(1.05) rotate(5deg);
        }
        
        .headertotvs-titleicon svg {
            flexwidth: 138px;
            margin-leftheight: 20px38px;
        }
    padding-left: 20px;
   
         border-left: 2px solid rgba(255, 255, 255, 0.3);
        }
        
        .header h1 .totvs-text {
            marginfont-size: 032px;
            font-sizeweight: 32px700;
            fontletter-weightspacing: 6003px;
            text-shadow: 0 2px4px 4px8px rgba(0, 0, 0, 0.23);
        }
        
        .metadataheader-title {
            backgroundflex: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%)1;
            paddingmargin-left: 20px 40px30px;
            displaypadding-left: flex30px;
            justifyborder-content: space-betweenleft: 3px solid rgba(255, 255, 255, 0.4);
        }
    align-items: center;
   
         flex-wrap: wrap;.header h1 {
            gapmargin: 20px0;
            borderfont-bottomsize: 1px solid #dee2e636px;
        }
        font-weight: 600;
        .metadata-item {
   text-shadow: 0 2px 4px rgba(0, 0,    display: flex0, 0.2);
            alignline-itemsheight: center1.2;
        }
    gap: 10px;
   
         font-size: 14px;
.header-subtitle {
         }
   margin-top: 8px;
    
        .metadatafont-item strong {size: 16px;
            coloropacity: #0A23330.9;
            font-weight: 600300;
        }
        
        .metadatainfo-item spanbar {
            color: #495057background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
            backgroundpadding: 25px white50px;
            paddingdisplay: 6px 12pxgrid;
            bordergrid-template-radius: 6pxcolumns: repeat(auto-fit, minmax(200px, 1fr));
            font-weightgap: 50025px;
            boxborder-shadowbottom: 0 2px 4px rgba(0, 0, 0, 0.05);
 solid #dee2e6;
          }
        
        .linksinfo-card {
            paddingdisplay: 20px 40pxflex;
            backgroundalign-items: #f8f9facenter;
            border-bottomgap: 1px solid #dee2e612px;
        }
    background: white;
   
         .linkspadding: a15px {20px;
            displayborder-radius: inline-flex10px;
            alignbox-items: centershadow: 0 2px 8px rgba(0, 0, 0, 0.08);
            gap: 8pxtransition: all 0.3s ease;
        }
      padding: 12px 24px;
        .info-card:hover {
     background: linear-gradient(135deg, #007BFF 0%, #0052CC 100%       transform: translateY(-2px);
            color: whitebox-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
        }
    text-decoration: none;
   
         border-radius: 8px;.info-icon {
            font-weightsize: 60024px;
            font-sizewidth: 14px40px;
            transitionheight: all 0.3s ease40px;
            box-shadowdisplay: 0flex;
 4px 12px rgba(0, 123, 255, 0.3);
        }align-items: center;
        
        .links a:hover {justify-content: center;
            transformbackground: translateY(-2pxlinear-gradient(135deg, #007BFF 0%, #0052CC 100%);
            box-shadowcolor: 0 6px 20px rgba(0, 123, 255, 0.4);
    white;
            border-radius: 8px;
        background: linear-gradient(135deg, #0052CC 0%, #003d99 100%) flex-shrink: 0;
        }
        
        .widgetinfo-containercontent {
            marginflex: 01;
        }
    border: none;
   
         border-radius: 0;.info-label {
            overflowfont-size: hidden12px;
            min-heightcolor: 700px#6c757d;
            backgroundtext-transform: #ffffffuppercase;
        }
    letter-spacing: 0.5px;
    
        .loading {font-weight: 600;
            textmargin-alignbottom: center4px;
        }
    padding: 60px 20px;
  
          color: #6c757d;.info-value {
            font-size: 16px;
        }
    color: #0A2333;
    
        .loading::before {font-weight: 600;
        }
    content: '';
   
         display: block;.action-bar {
            widthpadding: 25px 50px;
            heightbackground: 50px#ffffff;
            marginborder-bottom: 01px autosolid 20px#e9ecef;
            borderdisplay: 4px solid #e9ecefflex;
            borderalign-top-coloritems: #007BFFcenter;
            border-radius: 50%;
            animation: spin 1s linear infinitegap: 15px;
        }
        
        @keyframes spin.btn-primary {
            from { transformdisplay: rotate(0deg); }inline-flex;
            to { transformalign-items: rotate(360deg); }
center;
          }
  gap: 10px;
     
       padding: .error14px {28px;
            background: linear-gradient(135deg, #fee#007BFF 0%, #fcc#0052CC 100%);
            color: #c33white;
            paddingtext-decoration: 20px 40pxnone;
            border-leftradius: 4px solid #dc354510px;
            margin: 20px 40px;
            border-radius: 8px;font-weight: 600;
            font-size: 15px;
            transition: all 0.3s ease;
            box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3);
            border: none;
            cursor: pointer;
        }
        
        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 25px rgba(0, 123, 255, 0.4);
            background: linear-gradient(135deg, #0052CC 0%, #003d99 100%);
        }
        
        .btn-primary:active {
            transform: translateY(0);
        }
        
        .btn-icon {
            font-size: 18px;
        }
        
        .widget-container {
            margin: 0;
            border: none;
            border-radius: 0;
            overflow: hidden;
            min-height: 800px;
            background: #ffffff;
            position: relative;
        }
        
        .loading {
            text-align: center;
            padding: 80px 20px;
            color: #6c757d;
            font-size: 18px;
        }
        
        .loading::before {
            content: '';
            display: block;
            width: 60px;
            height: 60px;
            margin: 0 auto 30px;
            border: 5px solid #e9ecef;
            border-top-color: #007BFF;
            border-right-color: #007BFF;
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        
        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }
        
        .alert {
            margin: 30px 50px;
            padding: 25px 30px;
            border-radius: 12px;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
            line-height: 1.6;
        }
        
        .alert-error {
            background: linear-gradient(135deg, #fee 0%, #fcc 100%);
            color: #721c24;
            border-left: 5px solid #dc3545;
        }
        
        .alert-warning {
            background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%);
            color: #856404;
            border-left: 5px solid #ffc107;
        }
        
        .alert-icon {
            font-size: 24px;
            margin-right: 12px;
            vertical-align: middle;
        }
        
        #widget-placeholder {
            padding: 0;
        }
        
        #widget-placeholder iframe {
            border-radius: 0;
            box-shadow: none;
            display: block;
        }
        
        /* Instruções para símbolos - comentário no HTML */
        .symbol-help {
            display: none; /* Oculto por padrão, pode ser ativado para debug */
        }
        
        @media (max-width: 768px) {
            body {
                padding: 10px;
            }
            
            .header {
                padding: 25px 20px;
            }
            
            .header-content {
                flex-direction: column;
                align-items: flex-start;
                gap: 20px;
            }
            
            .header-title {
                margin-left: 0;
                padding-left: 0;
                border-left: none;
                border-top: 3px solid rgba(255, 255, 255, 0.4);
                padding-top: 20px;
                margin-top: 20px;
            }
            
            .header h1 {
                font-size: 28px;
            }
            
            .totvs-text {
                font-size: 24px;
            }
            
            .info-bar {
                padding: 20px;
                grid-template-columns: 1fr;
            }
            
            .action-bar {
                padding: 20px;
                flex-direction: column;
                align-items: stretch;
            }
            
            .btn-primary {
                width: 100%;
                justify-content: center;
            }
            
            .alert {
                margin: 20px;
                padding: 20px;
            }
        }
    </style>
    
    <!-- 
    ===================================================================
    COMO INSERIR SÍMBOLOS MANUALMENTE NO HTML
    ===================================================================
    
    1. EMOJIS UNICODE (Mais fácil):
       - Copie e cole  box-shadow: 0 4px 12px rgba(220, 53, 69, 0.1);diretamente: 📄 📁 📚 ✅ ❌ ⚠️ 🔄 💡
       - }
Ou use códigos HTML: 📄 📁 📚  
   💡
     .warning {
    2.        background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%);ENTIDADES HTML:
       - ©    color: #856404;
    = ©
       - padding:® 20px= 40px;®
       -  =   border-left: 4px solid #ffc107;
  -   = espaço não quebrável
     margin: 20px 40px;
- & = &
       - < border-radius: 8px;= <
       - > = >
   box-shadow: 0 4px 12px rgba(255, 193, 7, 0.1);
 
    3. CÓDIGOS UNICODE (hexadecimal):
       - 📄 = }📄
       - 📁 = 📁
        #widget-placeholder {
- 📚 = 📚
       -  =    padding: 0;
   -  =   }
     -  = ⚠️
       - #widget-placeholder🔄 iframe= {🔄
       - 💡    border-radius: 0;= 💡
    
    4. FONT AWESOME  box-shadow: none;(se disponível):
       - }
        
<i class="fa fa-file"></i> = ícone de arquivo
       - <i  @media (max-width: 768px) {
  class="fa fa-folder"></i> = ícone de pasta
       - <i  .header {
   class="fa fa-book"></i> = ícone de livro
    
     5. SVG CUSTOMIZADO (mais paddingcontrole): 20px;
       - Veja exemplo do logo }
TOTVS no código
    
    EXEMPLOS DE USO:
    - Em texto: <span>📄 Documento</span>
    .header-content {
    Em botões: <a href="#">📄 Abrir</a>
    - Em JavaScript: document.innerHTML = '📄 Carregando...';
   flex-direction: column;
    FERRAMENTAS ÚTEIS:
    - https://emojipedia.org/ (buscar emojis)
    align-items: flex-start; https://unicode-table.com/ (tabela Unicode completa)
    - Windows: Win + . (abre seletor de }emojis)
    - Mac: Cmd + Ctrl + Espaço (abre 
seletor de emojis)
    ===================================================================
      .header-title {-->
</head>
<body>
    <div class="release-notes-container">
           margin-left: 0;<div class="header">
                padding-left: 0;
<div class="header-content">
                <div border-left: none;class="totvs-logo">
                border-top: 2px solid rgba(255, 255, 255, 0.3);<div class="totvs-icon">
                padding-top: 15px;
       <svg viewBox="0 0 100      margin-top: 15px;100" xmlns="http://www.w3.org/2000/svg">
            }
            
    <polygon points="50,10 90,30 90,70 50,90    .header h1 {
 10,70 10,30" 
               font-size: 24px;
            }
           fill="#007BFF" 
            .metadata {
                padding: 15px 20px;
                flex-direction: column;
  stroke="#0052CC" 
              align-items: flex-start;
            }
            
 stroke-width="2"/>
           .links {
                padding: 15px 20px;
   <path d="M 30 50 L 50 30 L 70 }
50 L 50 70 Z" 
   }
    </style>
</head>
<body>
    <div class="release-notes-container">
        <div class="header">
            <div classfill="header-contentwhite"> 
                <div class="totvs-logo">
                    <div classopacity="totvs-icon"0.9"/>
                        <svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
</svg>
                    </div>
         <polygon points="50,10 90,30 90,70 50,90 10,70 10,30" 
           <div class="totvs-text">TOTVS</div>
                </div>
                <div fillclass="#007BFFheader-title">
 
                   <h1 id="page-title">Dicionário de Dados</h1>
                stroke="#0052CC" 
   <div class="header-subtitle">Documentação técnica e referência de versões</div>
                </div>
            stroke-width="2"/></div>
        </div>
            
        <path<div dclass="M 30 50 L 50 30 L 70 50 L 50 70 Z" "info-bar">
            <div class="info-card">
                <div class="info-icon">📋</div>
                <div fillclass="whiteinfo-content">
 
                   <div class="info-label">Versão</div>
              opacity="0.9"/>
      <div class="info-value" id="version">Carregando...</div>
                </svg>div>
            </div>
          </div>
    <div class="info-card">
                <div class="totvsinfo-texticon">TOTVS<>🕒</div>
                </div>
<div class="info-content">
                    <div class="headerinfo-title">
label">Última Atualização</div>
                     <h1<div class="info-value" id="pagelast-title">Dicionário de Dados</h1>update">-</div>
                </div>
            </div>
             </div><div class="info-card">
        
        <div class="metadata">
info-icon">📊</div>
                <div class="metadatainfo-itemcontent">
                   <strong>Versão:</strong> <span<div idclass="version">Carregando...</span>
    info-label">Status</div>
        </div>
            <div class="metadata-item">
 info-value" id="status">Ativo</div>
               <strong>Última atualização:</strong> <span id="last-update">-</span>div>
            </div>
        </div>
        
        <div class="linksaction-bar" id="links-container">
            <!-- Links serão inseridos aqui -->
        </div>
        
        <div class="widget-container">
            <div id="loading" class="loading">
                Carregando documento...
            </div>
            <div id="error" class="alert alert-error" style="display: none;"></div>
            <div id="warning" class="alert alert-warning" style="display: none;"></div>
            <div id="widget-placeholder"></div>
        </div>
    </div>

    <script>
        (function() {
            // Mapeamento de versões para Document IDs do Google Docs e arquivos .txt
            // Gerado automaticamente a partir da pasta: 141aJRhZeYZca4QCBnou6-00WzRLkBYbs
            // Data: 2025-12-16
            // Total: 62 versões (2 Google Docs + 60 arquivos .txt - todos funcionando!)
            const versionToDocId = {
                // Google Docs (2)
                '12.1.2503.14': '13QaSU_lP1_haWnOYl7UjPvsKfi3AaPdKwciYHrceEt4',
                '12.1.2511.2': '1gLo16QDT99iGdaoKyFHBW1n5jF-gt-awBjnSQrBZa3c',
                
                // Arquivos .txt (60) - funcionando diretamente no Widget Connector
                '12.1.2503': '1BRsJyHOHQNOEpAfIm5ndOn6z_0gffbaF',
                '12.1.2503.15': '12ejZuDikegyaH2n16n2Hpas1Z3VEjc5e',
                '12.1.2503.16': '15BkT50wXw7kJccfw4iRB-LVGQyTzQVf1',
                '12.1.2503.17': '1L4FUKbDjnAs29rK0ymfMgRVJPPVtzYdW',
                '12.1.2503.18': '1LNSFua5jsEw9m2D4X7lBVsbk6qXsG3cm',
                '12.1.2507': '1pT42y90cnf2UY2gK5k035jEFVkIs7s-n',
                '12.1.2507.1': '1lo7KiRJGWYJFfH-Xqv-dvNcRoIy6ecj3',
                '12.1.2507.2': '1xe9L8cCurcXIw5tzxe4H9KNzFgpIObA1',
                '12.1.2507.3': '1P9jEM2cgtUkyfdK5bsKlSvFCk_SqpMqU',
                '12.1.2507.4': '12Qk7mEnEe2iIsE-nFUUGOmbt_t8rwjn-',
                '12.1.2507.5': '1ljgI7Re2mT3yv7TgnZLOZv_n0vzzJTxF',
                '12.1.2507.6': '1lwblHVXZUKF8qgdajVB2Va41fxpJkZ9X',
                '12.1.2507.7': '1LWO9GFD8iO6HQEJn_wBybP1EdZ2AZSsD',
                '12.1.2507.8': '1bhB3Pig68EAvmXGoUptLYnJPEnGW4fVr',
                '12.1.2507.9': '1shjpLbeGfQmrV6DMtm4EuIvqdhHTuEIy',
                '12.1.2507.10': '1wU40XkkEMRqw4Ieanf5QrkBz8SwqISzj',
                '12.1.2507.11': '1goM3M1WCXvtdx46fY7ZmeeDtwpnvbld5',
                '12.1.2507.12': '15r-G5LdQpPn9gcktkpYVPQS1exs6Io8t',
                '12.1.2507.13': '1xVHx0mjDewGUVwIGR8GWqTMqX1R_Cj21',
                '12.1.2507.14': '1uFblMZhJaYPFrGKtFCC9bAa-2xxtXmi_',
                '12.1.2507.15': '1vNN6ONnbq1ApNJy6uzGW_hZ27HvhW7Dd',
                '12.1.2507.16': '1g27jhn6ZEliSZhAJ7Co9FUFLtNBfqVHH',
                '12.1.2507.17': '1LkwBvxVy_oykf3gEAwlf2eRn0NMiMnL1',
                '12.1.2507.18': '1he66XmpG6YhgKlxtMv3xik6KccuMKLeS',
                '12.1.2511': '1gPiO2P_mF0wpLX-2g5oFBqi4QS630wKM',
                '12.1.2511.1': '1yv4EZZKrfPgI-RWggMfBANtx6dL8owhA',
                '12.1.2511.3': '14Zd-Npn6VGioc1wsokDL4vfPRVzhb-AY',
                '12.1.2511.4': '1VjoqjmjqCokx4Kv5QDTDa9wZsF1QwICY',
                '12.1.2511.5': '1evpMFJmgDUFX__dC6W83LZqKQXjmy88s',
                '12.1.2511.6': '1_e3AgOsc9Oqy-JoZhus-zyU-961karvw',
                '12.1.2511.7': '19TKZ4fYof03H0pdzldQnV7_ZYjxowkNr',
                '12.1.2511.8': '12ivR5sJUwVwcRJr0Q_aHBT_y4JwlnTd4',
                '12.1.2511.9': '1Exio4F5z2lo6HnEnLpkDquuu8HUiD3C-',
                '12.1.2511.10': '1NRs4aZct5OVmSiXDPgMmUw9iFURlC6Od',
                '12.1.2511.11': '1AAOtpmIahaHaYYUtUFL3OJGJ07dTKLU_',
                '12.1.2511.12': '1c19qwsUQdWb_H58qcamAQ6Fz9Bwg78Bs',
                '12.1.2511.13': '1CS-VXZJLzPSBjov0r4JVAcTPE5daaE4M',
                '12.1.2511.14': '1dei-4_gijuPsGzSQKZpIh9DMCYJ2pw8j',
                '12.1.2511.15': '1qDv9Zm_0CJiKl6iJBzxVxwFCoHNZBky4',
                '12.1.2511.16': '1H51vcp3ierWZE0XB1QEtzUnm0J-0uEVp',
                '12.1.2511.17': '1OwFzjD6j4_OlDi9x7f5xqqoBo_eKY1rd',
                '12.1.2511.18': '1iaMmEP6yDzHR4oTM_SjM2obkaUz1zrBA',
                '12.1.2603.1': '19iieXcJNDoIM8lp09Zd-faD22AWepfTC',
                '12.1.2603.2': '1DFR1cWRUVm3PsPQsVbuJySIjxMIy085L',
                '12.1.2603.3': '1PLCl8hhtuvnW8Q9WDug9NH9F_qO-CUoq',
                '12.1.2603.4': '1qFmELYGulpQizNrXFBCpHdcLOSC5LrsZ',
                '12.1.2603.5': '1Q8ZSMOooNeSgmfdEucEsRO6P8z370enZ',
                '12.1.2603.6': '1P5-nq151raX-NhYufnTRrZMZyeAKsSp2',
                '12.1.2603.7': '1VfNdP7lRvi37ZKSOzX1KyEp6dK_t0I-N',
                '12.1.2603.8': '1pxJPuMKfOWXrkwS7zzmm_3i_GerA44Zi',
                '12.1.2603.9': '1evoXM_3WvL4SGVkwB8EYgwXuD6E4Asmw',
                '12.1.2603.10': '18tytubaH1oywQoWyAycMM-qMq_347CHb',
                '12.1.2603.11': '1ORyeFI8qYQynt20Ud66XLKewYQoVdLA6',
                '12.1.2603.12': '1gDfH7fyZSUGl90ikqO3yXsZGm_EXC4PW',
                '12.1.2607.1': '1ruRPs4fBJrKpLoECMGh0X5Ca4Bc_hfPb',
                '12.1.2607.2': '1njYTB38Ts6_dAZKvkqdvdQcPx99HTRml',
                '12.1.2607.3': '1uQR-2_JLet0Cyo7K6XaClDaXqxBu7udV',
                '12.1.2607.4': '1G41yiKUzoWgIrbQATlhYntb73FSH9U76',
                '12.1.2607.5': '1_BfY0poM0AeAFy39vK-XZmBhEafIzzBf',
                '12.1.2607.6': '1cm7WuMWrQYjGDdeMdmdAqIFX5ugROaHY',
            };
            
            // Função para extrair versão do título "Dicionário de Dados 12.1.2503.14"
            function extractVersionFromTitle() {
                let version = null;
                const versionPattern = /(\d+\.\d+\.\d+(?:\.\d+)?)/;
                
                // Método 1: Título da página (Confluence)
                const pageTitle = document.querySelector('h1#title-text, .page-title, h1, [data-page-title]');
                if (pageTitle) {
                    const titleText = pageTitle.textContent.trim();
                    const match = titleText.match(versionPattern);
                    if (match) {
                        version = match[1];
                    }
                }
                
                // Método 2: Meta tags
                if (!version) {
                    const metaTitle = document.querySelector('meta[property="og:title"], meta[name="title"]');
                    if (metaTitle) {
                        const titleText = metaTitle.getAttribute('content') || '';
                        const match = titleText.match(versionPattern);
                        if (match) {
                            version = match[1];
                        }
                    }
                }
                
                // Método 3: document.title
                if (!version) {
                    const match = document.title.match(versionPattern);
                    if (match) {
                        version = match[1];
                    }
                }
                
                // Método 4: URL (fallback)
                if (!version) {
                    const urlParams = new URLSearchParams(window.location.search);
                    const titleParam = urlParams.get('title');
                    if (titleParam) {
                        const match = decodeURIComponent(titleParam).match(versionPattern);
                        if (match) {
                            version = match[1];
                        }
                    }
                }
                
                return version;
            }
            
            // Função principal
            function init() {
                const version = extractVersionFromTitle();
                
                if (!version) {
                    document.getElementById('error').style.display = 'block';
                    document.getElementById('error').innerHTML = 
                        '❌ <strong>Versão<span class="alert-icon">❌</span><strong>Versão não identificada</strong><br>' +
                        'Certifique-se de que o título da página contém a versão no formato: "Dicionário de Dados 12.1.2503.14"';
                    document.getElementById('loading').style.display = 'none';
                    return;
                }
                
                // Atualizar interface
                document.getElementById('version').textContent = version;
                document.getElementById('page-title').textContent = `Dicionário de Dados ${version}`;
                document.getElementById('last-update').textContent = new Date().toLocaleString('pt-BR');
                
                // Obter Document ID
                const docId = versionToDocId[version];
                
                if (!docId) {
                    showWarning(version);
                    return;
                }
                
                loadDocument(docId, version);
            }
            
            function showWarning(version) {
                document.getElementById('warning').style.display = 'block';
                document.getElementById('warning').innerHTML = 
                    `⚠️ <strong>Documento`<span class="alert-icon">⚠️</span><strong>Documento não encontrado para versão ${version}</strong><br>` +
                    `O documento pode ainda não ter sido criado no Google Drive ou o mapeamento precisa ser atualizado.<br><br>` +
                    `Para adicionar este documento ao mapeamento:<br>` +
                    `1. Certifique-se de que existe um Google Doc ou arquivo .txt com o nome "${version}" ou "${version}.txt" na pasta<br>` +
                    `2. Execute o script: <code>python generate_complete_mapping_with_txt.py</code><br>` +
                    `3. Atualize o objeto <code>versionToDocId</code> neste HTML com o novo Document ID`;
                document.getElementById('loading').style.display = 'none';
            }
            
            function loadDocument(docId, version) {
                // Construir URLs (funciona para Google Docs e arquivos .txt)
                // Para arquivos .txt, o Google DriveDocs permitee visualizaçãoarquivos direta.txt)
                const googleDocUrl = `https://docs.google.com/document/d/${docId}/edit?usp=sharing`;
                const previewUrl = `https://docs.google.com/document/d/${docId}/preview`;
                
                // Criar botão linksde ação
                const linksContainer = document.getElementById('links-container');
                linksContainer.innerHTML = `
                    <a href="${googleDocUrl}" target="_blank">📄 Abrir no Google Docs<{googleDocUrl}" target="_blank" class="btn-primary">
                        <span class="btn-icon">📄</span>
                        <span>Abrir no Google Docs</span>
                    </a>
                `;
                
                // Criar Widget Connector ou iframe
                const placeholder = document.getElementById('widget-placeholder');
                
                // Verificar se está em modo de edição do Confluence
                const isEditMode = window.location.href.includes('editpage.action') || 
                                  window.location.href.includes('edit');
                
                if (isEditMode) {
                    // Modo de edição: mostrar código do macro Widget Connector
                    const widgetCode = `<ac:structured-macro ac:name="widget" ac:schema-version="1">
  <ac:parameter ac:name="url">${googleDocUrl}</ac:parameter>
  <ac:parameter ac:name="width">100%</ac:parameter>
  <ac:parameter ac:name="height">800</ac:parameter>
</ac:structured-macro>`;
                    
                    placeholder.innerHTML = `
                        <div class="alert alert-warning" style="backgroundmargin: 30px #f4f5f7; padding: 15px; border-radius: 5px; margin: 10px 0;">50px;">
                            <span class="alert-icon">📋</span>
                            <p><strong>📋 Código<strong>Código do Widget Connector:</strong></p>strong>
                            <pre style="background: white; padding: 10px15px; border-radius: 3px8px; overflow-x: auto; font-size: 12px: auto; font-size: 13px; margin-top: 15px; border: 1px solid #dee2e6;">${widgetCode}</pre>
                            <p style="margin-top: 10px15px; font-size: 12px; color: #666;">
 14px;">
                                <span class="alert-icon">💡</span>
                               💡 <strong>Instruções:</strong> Copie o código acima e cole no editor do Confluence usando o macro "Widget Connector".
                            </p>
                        </div>
                    `;
                } else {
                    // Modo de visualização: usar iframe
                    // Tenta primeiro o preview do Google Docs, se não funcionar, usa o Drive
                    const iframe = document.createElement('iframe');
                    iframe.src = previewUrl;
                    iframe.width = '100%';
                    iframe.height = '800';
                    iframe.style.border = 'none';
                    iframe.style.borderRadius = '5px0';
                    iframe.allow = 'fullscreen';
                    iframe.title = `Dicionário de Dados ${version}`;
                    
                    placeholder.appendChild(iframe);
                }
                
                document.getElementById('loading').style.display = 'none';
            }
            
            // Executar quando a página carregar
            if (document.readyState === 'loading') {
                document.addEventListener('DOMContentLoaded', init);
            } else {
                init();
            }
        })();
    </script>
</body>
</html>