
////////////////////////////////////

function loadScriptapp(urlScr) {
  return new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = urlScr;
    script.async = true;
    script.onload = () => resolve();
    script.onerror = () => reject(new Error(`Failed to load script: ${urlScr}`));
    document.head.appendChild(script);
  });
}
////////////////////////////////////////////////////
////////////////////////////////////////////////////
////////////////////////////////////////////////////
async function creatorport4x4(lapp, upload, codigopdf) {

  let nuevotitulo = "";
  totalUrl = [];
  let pathImages = "";
  let username = localStorage.getItem('username');

  let lModifFoo = false;

  if (lapp) lModifFoo = confirm('Modificar los titulos de cada imagen!.');

  let titulo = document.getElementById("idTitulo").value
  let registro = document.getElementById("idRegistro").value
  registro = registro.trim();

  let arrImages = [];

  if (titulo.length > 40) {
    titulo = titulo.slice(0, 40) + "";
  }
  if (registro.length > 40) {
    registro = registro.slice(0, 40) + "";
  }
  registro = registro.toUpperCase();
  titulo = titulo.toUpperCase();

  let qrTextTitulo = codigopdf + titulo

  let qrTextRegistro = registro;

  qrTextTitulo = qrTextTitulo.toLowerCase()
  qrTextRegistro = qrTextRegistro.toLowerCase()

  //let timestampIni = new Date().toLocaleString('en-GB', { timeZone: 'Europe/Madrid', hour12: true });
  let timestampIni = Date.now();
  qrTextRegistro = timestampIni.toString(36);

  let remplazaQr = / +/gi;
  qrTextTitulo = qrTextTitulo.replace(remplazaQr, "_");
  qrTextTitulo = qrTextTitulo.replace(/[^0-9a-z\s_]/gi, '')

  qrTextRegistro = qrTextRegistro.replace(remplazaQr, "_");
  qrTextRegistro = qrTextRegistro.replace(/[^0-9a-z\s_]/gi, '')

  let nameSave = qrTextTitulo + "_" + qrTextRegistro + ".pdf";

  nuevotitulo = qrTextTitulo + "_" + qrTextRegistro;

  let numImages = 0;
  let totalMp4 = ""; //qrTextTitulo + "_" + qrTextRegistro
  let totalMp4Lite = "";
  let docport;
  //await loadScriptapp('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js')
  await loadScriptapp('../../js/jspdf.umd.min.js')
    .then(() => {
      // Aquí puedes usar las funciones y clases de los scripts cargados
      console.log('Todos los scripts se han cargado correctamente.');
      docport = new window.jspdf.jsPDF({
        /*encryption: {
          userPassword: "rhb",
          ownerPassword: "cst",
          //userPermissions: ["print", "modify", "copy", "annot-forms"]
          ownerPermissions: ["print", "modify", "copy", "annot-forms"]
          // try changing the user permissions granted
        },*/
        orientation: 'portrait', unit: 'mm', format: 'a4', putOnlyUsedFonts: true, compress: true
      });
    })
    .catch(error => console.error('Error al cargar los scripts:', error));

  if (docport === undefined) {
    alert("Presione de nuevo el botón");
    return;
  }

  let width = docport.internal.pageSize.width;
  let height = docport.internal.pageSize.height;
  docport.setLineWidth(0);
  docport.setFontSize(10)
  docport.setDrawColor(155);
  let inicio = 10;
  let celliniw = 20;
  let cellinih = 58;
  let cellmax = 43;
  let cellmin = 33;
  let cellw = cellmax;
  let cellh = cellmax;

  let ipos = 0;
  let dropdownsp = document.getElementsByClassName("qaction-button");
  //console.info(dropdownsp)
  //console.info(dropdownsp.length);
  for (let ii = 0; ii < dropdownsp.length; ii++) {
    let openDropdownp = dropdownsp[ii];
    if (openDropdownp.innerText === "-") {
      numImages++;
      ipos = parseInt(openDropdownp.id.slice(1, openDropdownp.id.length))
      arrImages.push(ipos)
      let nameMp4ini = mainMenu[ipos].titulo
      console.info(nameMp4ini)
      console.info(ipos)
      let nseg = mainMenu[ipos].menu
      let sseg = nseg.toString()
      let numeroExec = parseInt(sseg.substr(0, 3))
      totalMp4 = totalMp4 + ',' + nameMp4ini

      let nameMp4iniLite = mainMenu[ipos].ordenOri
      totalMp4Lite = totalMp4Lite + ',' + nameMp4iniLite

    }
  }

  console.info(arrImages)
  let logo = new Image()
  //logo.src = "../../iconos/cst_20242.png"
  logo.src = "../../iconos/CST_HU4.png"

  ///////////////////////////////////////// INI
  docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST')
  docport.link(celliniw - 10, 10, 75, 18, { url: '' })
  ////////////////////////////////////////////
  if (!lapp) {
    pathImages = servidorURL + "/ias/index.html?";
  }
  else {
    pathImages = servidorURL + "/rhb/index.html?";
  }
  /////////////////////////////////////
  let nameUpload = servidorURL + "/assets/cstpdf/" + nameSave

  let pathPdf = pathImages + username + '#' + qrTextTitulo + '_' + qrTextRegistro + totalMp4Lite;
  let dataUrl = document.querySelector('#qr_code');//.querySelector('img');//.src;

  if (upload) {
    await loadScriptapp('../../js/qrious.min.js')
      .then(() => {
        // Aquí puedes usar las funciones y clases de los scripts cargados
        console.log('Todos los scripts se han cargado correctamente.');
        qrCode = new QRious({
          element: document.getElementById("qr_code"),
          background: '#ffffff',
          backgroundAlpha: 1,
          foreground: "#000000",
          foregroundAlpha: 1,
          level: 'H',
          padding: 0,
          size: 500,
          value: nameUpload,
        });
      })
      .catch(error => console.error('Error al cargar los scripts:', error));
  }
  else {
    await loadScriptapp('../../js/qrious.min.js')
      .then(() => {
        // Aquí puedes usar las funciones y clases de los scripts cargados
        console.log('Todos los scripts se han cargado correctamente.');
        qrCode = new QRious({
          element: document.getElementById("qr_code"),
          background: '#ffffff',
          backgroundAlpha: 1,
          foreground: "#000000",
          foregroundAlpha: 1,
          level: 'H',
          padding: 0,
          size: 500,
          value: pathPdf,
        });
      })
      .catch(error => console.error('Error al cargar los scripts:', error));
  }

  docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
  docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })

  /////////////////////////////////////////
  docport.setFontSize(14)
  //docport.text(celliniw + cellw + 5, 21, titulo + "_" + registro)
  docport.text(celliniw + cellw + 5, 21, titulo)

  //docport.rect(celliniw, 12, cellw * 4, 14);
  //docport.rect(celliniw, 12, cellw * 4, 29);
  //docport.rect(cellw * 4 - 8, 12, 28, 29);

  docport.setFontSize(10)
  let cat1 = "Fer els exercicis sense dolor i realitzar cadascun durant cinc minuts"
  let cast1 = "Hacer los ejercicios sin dolor y realizar cada uno durante cinco minutos"

  docport.text(celliniw + 3, 33, cat1)
  docport.text(celliniw + 3, 38, cast1)

  let clicar = "Cliqueu a les imatges per veure el contingut dels vídeos o al QR / Clique en las imagenes para ver el contenido de los videos o al QR"

  /////////////////////////////////////////////////////////

  docport.setFontSize(8)
  let npc = 0;
  let npf = 0;
  let npk = 0;

  for (let i = 0; i < 16; i++) {
    let ncode = npf * 8
    if (npf == 0 && npc == 0) {  //+ 15 + 10
      docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 16, clicar)
      //docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 16, cellw * 4, 8);
    }
    docport.setFillColor(235, 235, 235);
    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh, 'F');
    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8,);
    docport.setFillColor(255, 255, 255);

    docport.setDrawColor(155); //0


    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh);
    //docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8);
    //npk++
    npc++
    if (npc > 3) {
      npf++;
      npc = 0;
    }
    if (npf > 3) {
      npf = 0;
    }
  }
  npc = 0;
  npf = 0;
  npk = 0;

  docport.setFontSize(7)
  let date = new Date().getFullYear();
  let lic1 = "Aquesta obra està subjecta a una llicència de Reconeixement-NoComercial-SenseObraDerivada https://creativecommons.org/licenses/by-nc-nd/4.0/"
  let lic2 = "Citar aquesta obra com: Exercicis de fisioteràpia. Barcelona: Consorci Sanitari de Terrassa, " + date + ". SERVEI DE REHABILITACIÓ / FISIOTERÀPIA."

  docport.text(celliniw + 4, 270, lic1)
  docport.text(celliniw + 4, 275, lic2)

  docport.setDrawColor(155);
  docport.setFillColor(255, 255, 255);
  //docport.rect(celliniw, 263 - 8, celliniw + cellw * 3 + 23, 8, 'FD')

  //////////////////////////////////////
  docport.setFontSize(7)
  if (!upload) {
    let pieAttachd = new Image()
    pieAttachd.src = "../iconos/64_otros.png";
    docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
    let openQr = "Clicar o escanear el QR, abre su sesión de ejercicios con SEFiR. Clicar o escanejar el QR, obre la sessió d'exercicis amb SEFiR."
    docport.text(celliniw + 4, 260, openQr)
    //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
  }
  else {
    let pieAttachd = new Image()
    pieAttachd.src = "../iconos/pdf4.png";
    docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
    let openQr = "Clicar o escanear el QR, descarga el PDF de ejercicios en su dispositivo. Clicar o escanejar el QR descarrega el PDF d'exercicis al dispositiu."
    docport.text(celliniw + 4, 260, openQr)
    //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
  }
  docport.setFontSize(7)
  ////////////////////////////

  let today = new Date();
  //let newdat = "" + today;
  let newdat = "" + today + " - PEFiR. All rights reserved.";
  docport.text(celliniw + 4, 280, newdat);

  docport.setFontSize(7)
  let pageCurrent = docport.internal.getCurrentPageInfo().pageNumber
  docport.text('Page ' + String(pageCurrent), celliniw + cellw * 4 - 4, 280, null, null, "right");
  /////////////////////////////////// FIN
  ipos = 0;
  for (let ii = 0; ii < arrImages.length; ii++) {
    ipos = arrImages[ii];

    let name = mainMenu[ipos].titulo
    let videoTmp = mainMenu[ipos].videomp4;
    console.info(videoTmp)
    let videomp4 = videoTmp;

    console.info(videomp4)
    let nombre = mainMenu[ipos].nombre;
    let exec = mainMenu[ipos].videomp4;
    let menu = mainMenu[ipos].menu;
    let path = mainMenu[ipos].path;

    if (npk === 16) {
      npc = 0;
      npf = 0;
      //npk = 0;

      inicio = 10;
      celliniw = 20;
      cellinih = 58;
      cellmax = 43;
      cellmin = 33;
      cellw = cellmax;
      cellh = cellmax;

      docport.addPage();
      ///////////////////////////////////////// INI
      docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST')
      docport.link(celliniw - 10, 10, 75, 18, { url: '' })

      ////////////////////////////////
      docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
      docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })
      ///////////////////////////////////

      docport.setFontSize(14)

      //docport.text(celliniw + cellw + 5, 21, titulo + "_" + registro)
      docport.text(celliniw + cellw + 5, 21, titulo)

      //docport.rect(celliniw, 12, 65, 14);
      //docport.rect(celliniw, 12, cellw * 4, 14);

      docport.setFontSize(10)
      //let cat1 = "Fer els exercicis sense dolor i realitzar cadascun durant cinc minuts"
      //let cast1 = "Hacer los ejercicios sin dolor y realizar cada uno durante cinco minutos"

      docport.text(celliniw + 3, 33, cat1)
      docport.text(celliniw + 3, 38, cast1)

      docport.setFontSize(8)
      npc = 0;
      npf = 0;
      //npk = 0;
      for (let i = 0; i < 16; i++) {
        let ncode = npf * 8
        if (npf == 0 && npc == 0) {  //+15 + 10
          docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 16, clicar)
          //docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 16, cellw * 4, 8);
        }
        docport.setFillColor(235, 235, 235);
        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh, 'F');
        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8,);
        docport.setFillColor(255, 255, 255);

        docport.setDrawColor(155); //0

        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh);
        //docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8);
        //npk++
        npc++
        if (npc > 3) {
          npf++;
          npc = 0;
        }
        if (npf > 3) {
          npf = 0;
        }
      }

      docport.setFontSize(7)
      let date2 = new Date().getFullYear();
      lic1 = "Aquesta obra està subjecta a una llicència de Reconeixement-NoComercial-SenseObraDerivada https://creativecommons.org/licenses/by-nc-nd/4.0/"
      lic2 = "Citar aquesta obra com: Exercicis de fisioteràpia. Barcelona: Consorci Sanitari de Terrassa, " + date2 + ". SERVEI DE REHABILITACIÓ / FISIOTERÀPIA."

      docport.text(celliniw + 4, 270, lic1)
      docport.text(celliniw + 4, 275, lic2)

      docport.setDrawColor(155);
      docport.setFillColor(255, 255, 255);
      docport.rect(celliniw, 263 - 8, celliniw + cellw * 3 + 23, 8, 'FD')
      //////////////////////////////////////
      docport.setFontSize(7)
      if (!upload) {
        let pieAttachd = new Image()
        pieAttachd.src = "../iconos/64_otros.png";
        docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
        let openQr = "Clicar o escanear el QR, abre su sesión de ejercicios con SEFiR. Clicar o escanejar el QR, obre la sessió d'exercicis amb SEFiR."
        docport.text(celliniw + 4, 260, openQr)
        //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
      }
      else {
        let pieAttachd = new Image()
        pieAttachd.src = "../iconos/pdf4.png";
        docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
        let openQr = "Clicar o escanear el QR, descarga el PDF de ejercicios en su dispositivo. Clicar o escanejar el QR descarrega el PDF d'exercicis al dispositiu."
        docport.text(celliniw + 4, 260, openQr)
        //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
      }
      docport.setFontSize(7)
      ////////////////////////////
      ///////////////////////////////////////
      let today = new Date();
      let newdat = "" + today;
      docport.text(celliniw + cellw + 4, 280, newdat);
      pageCurrent = docport.internal.getCurrentPageInfo().pageNumber
      docport.text('Page ' + String(pageCurrent), celliniw + cellw * 4 - 4, 280, null, null, "right");
      /////////////////////////////////// FIN
      npc = 0;
      npf = 0;
      npk = 0;
    }
    ////////////////////////////////////////////////////////////////////////////
    let base64Image
    base64Image = await fetchImageAsBase64(name);
    if (base64Image) {
      let ncode = npf * 8
      let rectXp = celliniw + cellw * npc;
      let rectYp = cellinih + cellh * npf + ncode;

      let imgHeight = 0;
      let imgWidth = 0;

      const imgProps = docport.getImageProperties(base64Image);
      if (imgProps !== undefined) {
        if (imgProps.width > imgProps.height) {
          imgWidth = cellmax;
          imgHeight = parseInt((imgProps.height * imgWidth) / imgProps.width);
          imgWidth = imgWidth - 2
          rectYp = parseInt(rectYp + (cellmax - imgHeight) / 2)
          rectXp = rectXp + 1
        }
        else {
          imgHeight = cellmax;
          imgWidth = parseInt((imgProps.width * imgHeight) / imgProps.height);
          imgHeight = imgHeight - 2
          rectXp = parseInt(rectXp + (cellmax - imgWidth) / 2)
          rectYp = rectYp + 1
        }

        docport.addImage(base64Image, 'JPEG', rectXp, rectYp, imgWidth, imgHeight, ipos.toString(), undefined, 'FAST')

        let tipofile = videomp4.slice(videomp4.length - 3, videomp4.length)
        let numfile = videomp4.slice(videomp4.length - 11, videomp4.length - 8);
        if (tipofile === "txt") {
          await leerYAbrirURL2(videomp4, docport, rectXp, rectYp, imgWidth, imgHeight, numfile, nuevotitulo);
        }
        else {
          if (!lapp) {
            let nomUno = mainMenu[ipos].ordenOri; //name.slice(0, 7);
            let urlias = servidorURL + "/ias/index.html?" + username + "#" + qrTextRegistro + "," + nomUno;
            //docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: urlias });
            docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: videomp4 }); // XXXXXXXXXXXXXXXXXXXX
          }
          else {
            docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: videomp4 }); // XXXXXXXXXXXXXXXXXXXX
          }
          totalUrl.push(videomp4)
        }

        let agua = new Image()
        agua.src = "../../iconos/cst.png"
        docport.addImage(agua, "PNG", rectXp + imgWidth - cellmax / 4 - 1, rectYp + imgHeight - 2, cellmax / 4, 1, undefined, 'FAST')

        let paragraph = name.toUpperCase()
        paragraph = paragraph.slice(8, paragraph.length - 4)

        if (paragraph.length > 25) {
          paragraph = paragraph.slice(0, 25) + "";
        }
        let remplaza = /_+/gi;
        paragraph = paragraph.replace(remplaza, " ");
        let foo = paragraph;

        let nseg = menu //mainMenu[ipos].menu
        let sseg = nseg.toString()
        let numeroExec = parseInt(sseg.substr(0, 3))
        let nameMp44 = ""
        //if (numeroExec > 900 && numeroExec < 1000) {
        if (!lapp) {
          pathImages = servidorURL + "/ias/index.html?";
          //let urlias = servidorURL + "/ias/openvideo.html?," + name;
          //let urlias = servidorURL + "/ias/zHand.html?filtro=";
          //urlias = urlias + paragraph; 
          docport.textWithLink(paragraph, celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: videomp4 });
        }
        else {
          pathImages = servidorURL + "/rhb/index.html?";
          //nameMp44 = name
          //nameMp44 = ',' + nameMp44
          if (lModifFoo) foo = prompt('Puede modificar el titulo de la imagen ' + ii.toString() + ": ", foo);
          if (foo) {
            docport.textWithLink(foo.toUpperCase(), celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: '' });
          }
          else {
            docport.textWithLink(paragraph, celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: '' });
          }
        }
      }
      npk++
      npc++
      if (npc > 3) {
        npf++;
        npc = 0;
      }
      if (npf > 3) {
        npf = 0;
      }
    }
  }

  ///////////////////////////////////////////

  ///////////////////////////////////////////////***************************
  docport.addPage();
  ///////////////////////////////////////// INI
  docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST')
  docport.link(celliniw - 10, 10, 75, 18, { url: '' })

  docport.setFontSize(14)
  let titulo3 = qrTextTitulo  //;
  docport.text(celliniw + cellw + 5, 21, titulo3)

  //docport.rect(celliniw, 12, 65, 14);
  //docport.rect(celliniw, 12, cellw * 4, 14);

  docport.setFontSize(10)
  docport.setFontSize(12);

  let ns = 0;
  /*docport.text(celliniw + 4, 40 - ns, "PRIMERA OPCIÓ / PRIMERA OPCIÓN.");
  docport.text(celliniw + 4, 50 - ns, "Per accedir als exercicis mitjançant l'aplicació SEFiR:");
  docport.text(celliniw + 4, 55 - ns, " - Premeu directament al QR superior si disposeu del document pdf al vostre mòbil o pc.");
  docport.text(celliniw + 4, 60 - ns, " - Escanejar el QR superior si només disposeu del document en paper.");

  docport.text(celliniw + 4, 70 - ns, "Para acceder a los ejercicios mediante la aplicación SEFiR:");
  docport.text(celliniw + 4, 75 - ns, " - Pulse directamente en el QR superior si dispone del documento pdf en su móvil o pc.");
  docport.text(celliniw + 4, 80 - ns, " - Escanear el QR superior si sólo dispone del documento en papel.");

  ///////////////////////////////////////////////

  ns = -5;*/
  //docport.text(celliniw + 4, 110 - ns, "SEGONA OPCIÓ / SEGUNDA OPCIÓN.");
  docport.text(celliniw + 4, 70 - ns, "Aquest QR s´ofereix per compatibilitat amb els diferents navegadors.");
  docport.text(celliniw + 4, 75 - ns, "Us permet recrear el pdf al vostre sistema en lloc d'obrir l'aplicació SEFiR.");
  docport.text(celliniw + 4, 80 - ns, "Escanejar el QR superior d'aquesta pàgina y obrir el pdf.");
  //docport.text(celliniw + 4, 135 - ns, " - Premeu directament a cada imatge per veure el vídeo.");

  docport.text(celliniw + 4, 90 - ns, "Este QR se ofrece por compatibilidad con los diferentes navegadores.");
  docport.text(celliniw + 4, 95 - ns, "Le permite recrear el pdf en su sistema en lugar de abrir la aplicación SEFiR.");
  docport.text(celliniw + 4, 100 - ns, "Escanear el QR superior de esta página y abrir el pdf.");
  //docport.text(celliniw + 4, 160 - ns, " - Pulsar directamente en cada imagen para ver el vídeo.");

  docport.setFontSize(7)
  let date4 = new Date().getFullYear();
  lic1 = "Aquesta obra està subjecta a una llicència de Reconeixement-NoComercial-SenseObraDerivada https://creativecommons.org/licenses/by-nc-nd/4.0/"
  lic2 = "Citar aquesta obra com: Exercicis de fisioteràpia. Barcelona: Consorci Sanitari de Terrassa, " + date4 + ". SERVEI DE REHABILITACIÓ / FISIOTERÀPIA."

  docport.text(celliniw + 4, 270, lic1)
  docport.text(celliniw + 4, 275, lic2)

  docport.setDrawColor(155);
  docport.setFillColor(255, 255, 255);
  //docport.rect(celliniw, 263 - 8, celliniw + cellw * 3 + 23, 8, 'FD')


  //////////////////////////////////
  today = new Date();
  newdat = "" + today + " - PEFiR. All rights reserved.";
  //docport.text(celliniw + cellw + 4, 280, newdat);
  docport.text(celliniw + 4, 280, newdat);
  pageCurrent = docport.internal.getCurrentPageInfo().pageNumber
  docport.text('Page ' + String(pageCurrent), celliniw + cellw * 4 - 4, 280, null, null, "right");
  /////////////////////////////////// FIN

  //docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
  //docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })


  /////////////////////////////////////
  let newpathImages = "";
  if (!lapp) {
    newpathImages = servidorURL + "/ias/newpdf.html?";
  }
  else {
    newpathImages = servidorURL + "/rhb/newpdf.html?";
  }
  let newpathPdf = newpathImages + username + '#' + qrTextTitulo + '_' + qrTextRegistro + totalMp4Lite;
  let newdataUrl = document.querySelector('#qr_code');//.querySelector('img');//.src;

  if (!upload) {
    await loadScriptapp('../../js/qrious.min.js')
      .then(() => {
        // Aquí puedes usar las funciones y clases de los scripts cargados
        console.log('Todos los scripts se han cargado correctamente.');
        qrCode = new QRious({
          element: document.getElementById("qr_code"),
          background: '#ffffff',
          backgroundAlpha: 1,
          foreground: "#000000",
          foregroundAlpha: 1,
          level: 'H',
          padding: 0,
          size: 500,
          value: newpathPdf,
        });
      })
      .catch(error => console.error('Error al cargar los scripts:', error));
  }

  docport.addImage(newdataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
  docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: newpathPdf })
  //docport.addImage(newdataUrl, "PNG", celliniw + cellw / 2 + 30, 180, 70, 70, undefined, 'FAST');
  //docport.link(celliniw + cellw / 2 + 30, 180, 70, 70, { url: newpathPdf })
  //////////////////////////////////////////////////////////////////

  /////////////////////////////////////////////////////////////////////////////////////////////////
  console.info(totalUrl)
  let totalAnot = "";
  for (let i = 0; i < totalUrl.length; i++) {
    totalAnot = totalAnot + totalUrl[i] + ",";
  }
  //console.info(totalAnot)
  totalAnot = totalAnot.slice(0, totalAnot.length - 1)

  console.info(totalAnot)
  console.info(totalMp4)
  console.info(pathPdf)

  //totalMp4 = totalMp4.slice(1, totalMp4.length)

  docport.setProperties({
    title: nameSave,
    subject: 'exercicis',
    author: 'CST. Servei de fisioteràpia: ' + username,
    keywords: totalAnot,
    creator: 'Software info. (abeciabuil@gmail.com)',
  });

  let tituloSave = qrTextTitulo + '_' + qrTextRegistro + '.pdf'

  // ── Pàgina 2: QR de recreació ─────────────────────────
  docport.addPage();
  docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST');
  docport.setFontSize(13); docport.setTextColor(40, 40, 40);
  docport.text(qrTextTitulo + '_' + qrTextRegistro, celliniw + 42, 18);
  docport.setFontSize(8);
  docport.text(new Date().toLocaleDateString('ca-ES'), celliniw + 42, 24);
  {
    const _qs = 40, _pw = 210, _qx = (_pw - _qs) / 2, _qy = 60;
    const _qr2 = new QRious({ background: '#ffffff', foreground: '#000000', level: 'H', padding: 0, size: 600, value: newpathPdf });
    docport.addImage(_qr2.toDataURL('image/png'), 'PNG', _qx, _qy, _qs, _qs, undefined, 'FAST');
    docport.link(_qx, _qy, _qs, _qs, { url: newpathPdf });
    docport.setFontSize(10); docport.setTextColor(40, 40, 40);
    const _ty = _qy + _qs + 14;
    ["Aquest QR s'ofereix per compatibilitat amb els diferents navegadors.",
     "Us permet recrear el pdf al vostre sistema en lloc d'obrir l'aplicació SEFiR.",
     "Escanegeu el QR superior d'aquesta pàgina i obriu el pdf.",
     "",
     "Este QR se ofrece por compatibilidad con los diferentes navegadores.",
     "Le permite recrear el pdf en su sistema en lugar de abrir la aplicación SEFiR.",
     "Escanear el QR superior de esta página y abrir el pdf.",
    ].forEach((l, i) => docport.text(l, _pw / 2, _ty + i * 7, { align: 'center' }));
  }

  closeSidenav();

  //let burl = docport.output('bloburl', '_self');
  //window.open(burl);
  let timestampEvent = new Date().toLocaleString('en-GB', { timeZone: 'Europe/Madrid', hour12: true });
  const eventDataPdf = {
    uniqueNumber: Date.now(),
    timestamp: timestampEvent,
    autor: username,
    pdf_nom: qrTextTitulo + '_' + qrTextRegistro,
    qr_nom: pathPdf,
    image_nom: totalMp4,
  };
  console.info(eventDataPdf)
  if (upload) {
    let savepdf = false;
    savepdf = confirm('El archivo esta preparado, puede crearlo!.');
    if (savepdf) {
      if (navigator.onLine) {
        console.log("Tienes conexión a Internet.");
        let username = localStorage.getItem('username'); //*********************//if (username !== "jmab")
        logEventPdf(eventDataPdf)
      } else {
        console.log("No tienes conexión a Internet.");
      }

      // Guardar el PDF antes de subirlo
      let nombreArchivo = qrTextTitulo + '_' + qrTextRegistro + '.pdf';
      await docport.save(nombreArchivo);

      try {
        // Generar el PDF y obtenerlo como Blob
        const pdfBlob = await docport.output("blob");

        // Crear FormData y adjuntar el archivo PDF
        const formData = new FormData();
        formData.append("file", pdfBlob, nombreArchivo);

        const urlphp = servidorURL + '/php/pdf/php_upload_pdf.php?t=' + new Date().getTime();
        // Enviar el archivo PDF al servidor con fetch()

        const response = await fetch(urlphp, {
          method: 'POST',
          body: formData,
        });

        if (!response.ok) {
          throw new Error('Error al subir el archivo.');
        }
        const result = await response.text();
        console.info("Respuesta del servidor:", result);

        // Actualizar el estado en la UI
        const statusElement = document.getElementById('status');
        if (statusElement) {
          statusElement.innerText = result;
          obtenerPdfs();
        }
      } catch (error) {
        console.error("Error al subir el archivo:", error);

        const statusElement = document.getElementById('status');
        if (statusElement) {
          statusElement.innerText = error.message;
        }
      }
    } else {
      alert("Operación cancelada.");
    }
  }
  else {
    if (navigator.onLine) {
      console.log("Tienes conexión a Internet.");
      let username = localStorage.getItem('username'); //*********************//if (username !== "jmab")
      logEventPdf(eventDataPdf)
    } else {
      console.log("No tienes conexión a Internet.");
    }
    ///////////////////////////////////
    let savepdf = false;
    savepdf = confirm('El archivo esta preparado, puede crearlo!.');
    if (savepdf) docport.save(qrTextTitulo + '_' + qrTextRegistro + '.pdf')
  }
}
////////////////////////////////////////////////////
//////////////////////////////////////////////////
///////////////////////////////////////////////////////
async function creatorport4x3(lapp, upload, codigopdf) {

  let textoArea1 = 'Seguiu les indicacions del vostre fisioterapeuta i repetiu la sessió de 2/3 vegades al dia.'
  let textoArea2 = 'Siga las indicaciones de su fisioterapeuta y repita la sesión de 2/3 veces al día.'

  const contenido = document.getElementById('w3review').value;
  const lineasFases = contenido.split('\n');
  console.log(lineasFases); // Array de cada línea

  let sFase1 = lineasFases[0];
  let sFase2 = lineasFases[1];
  let sFase3 = lineasFases[2];
  let sFase4 = lineasFases[3];
  let sFase5 = lineasFases[4];
  let sFase6 = lineasFases[5];

  if (!sFase1) sFase1 = " ";
  if (!sFase2) sFase2 = " ";
  if (!sFase3) sFase3 = " ";
  if (!sFase4) sFase4 = " ";
  if (!sFase5) sFase5 = " ";
  if (!sFase6) sFase6 = " ";

  let nuevotitulo = "";
  totalUrl = [];
  let pathImages = "";
  let username = localStorage.getItem('username');

  let lModifFoo = false;
  if (lapp) lModifFoo = confirm('Modificar los titulos de cada imagen!.');

  let titulo = document.getElementById("idTitulo").value
  let registro = document.getElementById("idRegistro").value
  registro = registro.trim();

  let arrImages = [];

  if (titulo.length > 40) {
    titulo = titulo.slice(0, 40) + "";
  }
  if (registro.length > 40) {
    registro = registro.slice(0, 40) + "";
  }
  registro = registro.toUpperCase();
  titulo = titulo.toUpperCase();

  let qrTextTitulo = codigopdf + titulo

  let qrTextRegistro = registro;

  qrTextTitulo = qrTextTitulo.toLowerCase()
  qrTextRegistro = qrTextRegistro.toLowerCase()

  //let timestampIni = new Date().toLocaleString('en-GB', { timeZone: 'Europe/Madrid', hour12: true });
  let timestampIni = Date.now();
  qrTextRegistro = timestampIni.toString(36);

  let remplazaQr = / +/gi;
  qrTextTitulo = qrTextTitulo.replace(remplazaQr, "_");
  qrTextTitulo = qrTextTitulo.replace(/[^0-9a-z\s_]/gi, '')

  qrTextRegistro = qrTextRegistro.replace(remplazaQr, "_");
  qrTextRegistro = qrTextRegistro.replace(/[^0-9a-z\s_]/gi, '')

  let nameSave = qrTextTitulo + "_" + qrTextRegistro + ".pdf";

  nuevotitulo = qrTextTitulo + "_" + qrTextRegistro;

  let numImages = 0;
  let totalMp4 = ""; //qrTextTitulo + "_" + qrTextRegistro
  let totalMp4Lite = "";
  let docport;
  //await loadScriptapp('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js')
  await loadScriptapp('../../js/jspdf.umd.min.js')
    .then(() => {
      // Aquí puedes usar las funciones y clases de los scripts cargados
      console.log('Todos los scripts se han cargado correctamente.');
      docport = new window.jspdf.jsPDF({
        /*encryption: {
          userPassword: "rhb",
          ownerPassword: "cst",
          //userPermissions: ["print", "modify", "copy", "annot-forms"]
          ownerPermissions: ["print", "modify", "copy", "annot-forms"]
          // try changing the user permissions granted
        },*/
        orientation: 'portrait', unit: 'mm', format: 'a4', putOnlyUsedFonts: true, compress: true
      });
    })
    .catch(error => console.error('Error al cargar los scripts:', error));

  if (docport === undefined) {
    alert("Presione de nuevo el botón");
    return;
  }

  let width = docport.internal.pageSize.width;
  let height = docport.internal.pageSize.height;
  docport.setLineWidth(0);
  docport.setFontSize(10)
  docport.setDrawColor(155);
  let inicio = 10;
  let celliniw = 20;
  let cellinih = 58;
  let cellmax = 43;
  let cellmin = 33;
  let cellw = cellmax;
  let cellh = cellmax;

  let ipos = 0;
  let dropdownsp = document.getElementsByClassName("qaction-button");
  //console.info(dropdownsp)
  //console.info(dropdownsp.length);
  for (let ii = 0; ii < dropdownsp.length; ii++) {
    let openDropdownp = dropdownsp[ii];
    if (openDropdownp.innerText === "-") {
      numImages++;
      ipos = parseInt(openDropdownp.id.slice(1, openDropdownp.id.length))
      arrImages.push(ipos)
      let nameMp4ini = mainMenu[ipos].titulo
      console.info(nameMp4ini)
      console.info(ipos)
      let nseg = mainMenu[ipos].menu
      let sseg = nseg.toString()
      let numeroExec = parseInt(sseg.substr(0, 3))
      totalMp4 = totalMp4 + ',' + nameMp4ini

      let nameMp4iniLite = mainMenu[ipos].ordenOri
      totalMp4Lite = totalMp4Lite + ',' + nameMp4iniLite

    }
  }

  console.info(arrImages)
  let logo = new Image()
  //logo.src = "../../iconos/cst_20242.png"
  logo.src = "../../iconos/CST_HU4.png"

  ///////////////////////////////////////// INI
  docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST')
  docport.link(celliniw - 10, 10, 75, 18, { url: '' })
  ////////////////////////////////////////////
  if (!lapp) {
    pathImages = servidorURL + "/ias/index.html?";
  }
  else {
    pathImages = servidorURL + "/rhb/index.html?";
  }
  /////////////////////////////////////
  let nameUpload = servidorURL + "/assets/cstpdf/" + nameSave

  let pathPdf = pathImages + username + '#' + qrTextTitulo + '_' + qrTextRegistro + totalMp4Lite;
  let dataUrl = document.querySelector('#qr_code');//.querySelector('img');//.src;

  if (upload) {
    await loadScriptapp('../../js/qrious.min.js')
      .then(() => {
        // Aquí puedes usar las funciones y clases de los scripts cargados
        console.log('Todos los scripts se han cargado correctamente.');
        qrCode = new QRious({
          element: document.getElementById("qr_code"),
          background: '#ffffff',
          backgroundAlpha: 1,
          foreground: "#000000",
          foregroundAlpha: 1,
          level: 'H',
          padding: 0,
          size: 500,
          value: nameUpload,
        });
      })
      .catch(error => console.error('Error al cargar los scripts:', error));
  }
  else {
    await loadScriptapp('../../js/qrious.min.js')
      .then(() => {
        // Aquí puedes usar las funciones y clases de los scripts cargados
        console.log('Todos los scripts se han cargado correctamente.');
        qrCode = new QRious({
          element: document.getElementById("qr_code"),
          background: '#ffffff',
          backgroundAlpha: 1,
          foreground: "#000000",
          foregroundAlpha: 1,
          level: 'H',
          padding: 0,
          size: 500,
          value: pathPdf,
        });
      })
      .catch(error => console.error('Error al cargar los scripts:', error));
  }

  docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
  docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })

  /////////////////////////////////////////
  docport.setFontSize(14)

  //docport.text(celliniw + cellw + 5, 21, titulo + "_" + registro)
  docport.text(celliniw + cellw + 5, 21, titulo)

  //docport.rect(celliniw, 12, cellw * 4, 14);
  //docport.rect(celliniw, 12, cellw * 4, 29);
  //docport.rect(cellw * 4 - 8, 12, 28, 29);

  docport.setFontSize(10)
  let cat1 = "Fer els exercicis sense dolor i realitzar cadascun durant cinc minuts"
  let cast1 = "Hacer los ejercicios sin dolor y realizar cada uno durante cinco minutos"

  docport.text(celliniw + 3, 33, cat1)
  docport.text(celliniw + 3, 38, cast1)

  let clicar = "Cliqueu a les imatges per veure el contingut dels vídeos o al QR / Clique en las imagenes para ver el contenido de los videos o al QR"

  /////////////////////////////////////////////////////////

  docport.setFontSize(8)
  let npc = 0;
  let npf = 0;
  let npk = 0;
  let nplus = 0;

  for (let i = 0; i < 12; i++) {
    let ncode = npf * 8 + nplus
    if (npf == 0 && npc == 0) {  //+ 15 + 10
      docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 16, clicar)
      //docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 16, cellw * 4, 8);
      nplus = 8
      docport.setFontSize(12)
      docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase1)
      docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
    }

    if (npf == 1 && npc == 0) {
      nplus = 16
      docport.setFontSize(12)
      docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase2)
      docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
    }

    if (npf == 2 && npc == 0) {
      nplus = 24
      docport.setFontSize(12)
      docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase3)
      docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
    }

    docport.setFontSize(8)
    ncode = npf * 8 + nplus

    docport.setFillColor(235, 235, 235);
    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh, 'F');
    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8,);
    docport.setFillColor(255, 255, 255);

    docport.setDrawColor(155); //0

    docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh);
    //docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8);
    //npk++
    npc++
    if (npc > 3) {
      npf++;
      npc = 0;
    }
    if (npf > 2) {
      npf = 0;
    }
  }
  npc = 0;
  npf = 0;
  npk = 0;

  docport.setFontSize(7)
  let date = new Date().getFullYear();
  let lic1 = "Aquesta obra està subjecta a una llicència de Reconeixement-NoComercial-SenseObraDerivada https://creativecommons.org/licenses/by-nc-nd/4.0/"
  let lic2 = "Citar aquesta obra com: Exercicis de fisioteràpia. Barcelona: Consorci Sanitari de Terrassa, " + date + ". SERVEI DE REHABILITACIÓ / FISIOTERÀPIA."

  docport.text(celliniw + 4, 270, lic1)
  docport.text(celliniw + 4, 275, lic2)

  docport.setDrawColor(155);
  docport.setFillColor(255, 255, 255);
  //docport.rect(celliniw, 263 - 8, celliniw + cellw * 3 + 23, 8, 'FD')
  //////////////////////////////////////
  docport.setFontSize(7)
  if (!upload) {
    let pieAttachd = new Image()
    pieAttachd.src = "../iconos/64_otros.png";
    docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
    let openQr = "Clicar o escanear el QR, abre su sesión de ejercicios con SEFiR. Clicar o escanejar el QR, obre la sessió d'exercicis amb SEFiR."
    docport.text(celliniw + 4, 260, openQr)
    //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
  }
  else {
    let pieAttachd = new Image()
    pieAttachd.src = "../iconos/pdf4.png";
    docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
    let openQr = "Clicar o escanear el QR, descarga el PDF de ejercicios en su dispositivo. Clicar o escanejar el QR descarrega el PDF d'exercicis al dispositiu."
    docport.text(celliniw + 4, 260, openQr)
    //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
  }
  /////////////////////////////////
  //let lin = 175;
  //var splitTitle = docport.splitTextToSize(textoArea, 170); //docport.splitTextToSize(content.value, 170);
  //docport.setFontSize(12)
  //docport.text(celliniw + cellw + 5, 21 + lin, titulo)
  //let titulo2 = "RECOMANACIONS / RECOMENDACIONES"; //+ " ." + String(numImages);
  //docport.text(celliniw + 3, 64 + lin, titulo2)
  docport.setFontSize(10);
  /*docport.text(splitTitle, celliniw + 3, 68 + lin, {
    maxWidth: 170,  // Ancho máximo
    align: 'left'   // También puedes usar 'left' 'center' o 'justify'
  });*/

  docport.text(textoArea1, celliniw + 3, 240);
  docport.text(textoArea2, celliniw + 3, 245);

  docport.setFontSize(7)
  docport.setDrawColor(155);
  docport.setFillColor(255, 255, 255);

  //////////////////////////////////
  docport.setFontSize(7)

  let today = new Date();
  //let newdat = "" + today;
  let newdat = "" + today + " - PEFiR. All rights reserved.";
  docport.text(celliniw + 4, 280, newdat);

  docport.setFontSize(7)
  let pageCurrent = docport.internal.getCurrentPageInfo().pageNumber
  docport.text('Page ' + String(pageCurrent), celliniw + cellw * 4 - 4, 280, null, null, "right");
  /////////////////////////////////// FIN
  ipos = 0;
  for (let ii = 0; ii < arrImages.length; ii++) {
    ipos = arrImages[ii];

    let name = mainMenu[ipos].titulo
    let videoTmp = mainMenu[ipos].videomp4;
    console.info(videoTmp)
    let videomp4 = videoTmp;

    console.info(videomp4)
    let nombre = mainMenu[ipos].nombre;
    let exec = mainMenu[ipos].videomp4;
    let menu = mainMenu[ipos].menu;
    let path = mainMenu[ipos].path;

    if (npk === 12) {
      npc = 0;
      npf = 0;
      //npk = 0;

      inicio = 10;
      celliniw = 20;
      cellinih = 58;
      cellmax = 43;
      cellmin = 33;
      cellw = cellmax;
      cellh = cellmax;

      docport.addPage();
      ///////////////////////////////////////// INI
      docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST')
      docport.link(celliniw - 10, 10, 75, 18, { url: '' })

      ////////////////////////////////
      docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
      docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })
      ///////////////////////////////////

      docport.setFontSize(14)

      //docport.text(celliniw + cellw + 5, 21, titulo + "_" + registro)
      docport.text(celliniw + cellw + 5, 21, titulo)

      //docport.rect(celliniw, 12, 65, 14);
      //docport.rect(celliniw, 12, cellw * 4, 14);

      docport.setFontSize(10)
      //let cat1 = "Fer els exercicis sense dolor i realitzar cadascun durant cinc minuts"
      //let cast1 = "Hacer los ejercicios sin dolor y realizar cada uno durante cinco minutos"

      docport.text(celliniw + 3, 33, cat1)
      docport.text(celliniw + 3, 38, cast1)

      docport.setFontSize(8)
      npc = 0;
      npf = 0;
      nplus = 0;
      //npk = 0;
      for (let i = 0; i < 12; i++) {
        let ncode = npf * 8 + nplus
        if (npf == 0 && npc == 0) {  //+15 + 10
          docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 16, clicar)
          //docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 16, cellw * 4, 8);
          nplus = 8
          docport.setFontSize(12)
          docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase4)
          docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
        }

        if (npf == 1 && npc == 0) {
          nplus = 16
          docport.setFontSize(12)
          docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase5)
          docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
        }

        if (npf == 2 && npc == 0) {
          nplus = 24
          docport.setFontSize(12)
          docport.text(celliniw + cellh * npc + 3, cellinih + cellh * npf + ncode + 5 - 8, sFase6)
          docport.rect(celliniw + cellh * npc, cellinih + cellh * npf + ncode - 8, cellw * 4, 8);
        }

        docport.setFontSize(8)
        ncode = npf * 8 + nplus

        docport.setFillColor(235, 235, 235);
        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh, 'F');
        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8,);
        docport.setFillColor(255, 255, 255);
        docport.setDrawColor(155); //0
        docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode, cellw, cellh);
        //docport.rect(celliniw + cellw * npc, cellinih + cellh * npf + ncode - 8, cellw, 8);
        //npk++
        npc++
        if (npc > 3) {
          npf++;
          npc = 0;
        }
        if (npf > 2) {
          npf = 0;
        }
      }

      docport.setFontSize(7)
      let date2 = new Date().getFullYear();
      lic1 = "Aquesta obra està subjecta a una llicència de Reconeixement-NoComercial-SenseObraDerivada https://creativecommons.org/licenses/by-nc-nd/4.0/"
      lic2 = "Citar aquesta obra com: Exercicis de fisioteràpia. Barcelona: Consorci Sanitari de Terrassa, " + date2 + ". SERVEI DE REHABILITACIÓ / FISIOTERÀPIA."

      docport.text(celliniw + 4, 270, lic1)
      docport.text(celliniw + 4, 275, lic2)

      docport.setDrawColor(155);
      docport.setFillColor(255, 255, 255);
      //docport.rect(celliniw, 263 - 8, celliniw + cellw * 3 + 23, 8, 'FD')
      //////////////////////////////////////
      docport.setFontSize(7)
      if (!upload) {
        let pieAttachd = new Image()
        pieAttachd.src = "../iconos/64_otros.png";
        docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
        let openQr = "Clicar o escanear el QR, abre su sesión de ejercicios con SEFiR. Clicar o escanejar el QR, obre la sessió d'exercicis amb SEFiR."
        docport.text(celliniw + 4, 260, openQr)
        //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
      }
      else {
        let pieAttachd = new Image()
        pieAttachd.src = "../iconos/pdf4.png";
        docport.addImage(pieAttachd, "PNG", celliniw + cellw * 4 - 9, 263 - 7.5, 7, 7, undefined, 'FAST')
        let openQr = "Clicar o escanear el QR, descarga el PDF de ejercicios en su dispositivo. Clicar o escanejar el QR descarrega el PDF d'exercicis al dispositiu."
        docport.text(celliniw + 4, 260, openQr)
        //docport.link(celliniw + cellw * 4 - 9, 263 - 8, 10, 10, { url: servidorURL + "/rhb/index.html?" + qrTextTitulo + '_' + qrTextRegistro + totalMp4 });
      }
      /////////////////////////////////
      //let lin = 175;
      //var splitTitle = docport.splitTextToSize(textoArea, 170); //docport.splitTextToSize(content.value, 170);
      //docport.setFontSize(12)
      //docport.text(celliniw + cellw + 5, 21 + lin, titulo)
      //let titulo2 = "RECOMANACIONS / RECOMENDACIONES"; //+ " ." + String(numImages);
      //docport.text(celliniw + 3, 64 + lin, titulo2)
      docport.setFontSize(10);
      /*docport.text(splitTitle, celliniw + 3, 68 + lin, {
        maxWidth: 170,  // Ancho máximo
        align: 'left'   // También puedes usar 'left' 'center' o 'justify'
      });*/
      docport.text(textoArea1, celliniw + 3, 240);
      docport.text(textoArea2, celliniw + 3, 245);
      docport.setFontSize(7)
      docport.setDrawColor(155);
      docport.setFillColor(255, 255, 255);
      //////////////////////////////////
      docport.setFontSize(7)
      ////////////////////////////
      let today = new Date();
      let newdat = "" + today;
      docport.text(celliniw + cellw + 4, 280, newdat);
      pageCurrent = docport.internal.getCurrentPageInfo().pageNumber
      docport.text('Page ' + String(pageCurrent), celliniw + cellw * 4 - 4, 280, null, null, "right");
      /////////////////////////////////// FIN
      npc = 0;
      npf = 0;
      npk = 0;
    }
    ////////////////////////////////////////////////////////////////////////////
    let base64Image;
    nplus = 8;
    if (npf == 0) {  //+15 + 10
      nplus = 8
    }
    if (npf == 1) {
      nplus = 16
    }
    if (npf == 2) {
      nplus = 24
    }
    base64Image = await fetchImageAsBase64(name);
    if (base64Image) {

      //let ncode = npf * 8
      let ncode = npf * 8 + nplus

      let rectXp = celliniw + cellw * npc;
      let rectYp = cellinih + cellh * npf + ncode;

      let imgHeight = 0;
      let imgWidth = 0;

      const imgProps = docport.getImageProperties(base64Image);
      if (imgProps !== undefined) {
        if (imgProps.width > imgProps.height) {
          imgWidth = cellmax;
          imgHeight = parseInt((imgProps.height * imgWidth) / imgProps.width);
          imgWidth = imgWidth - 2
          rectYp = parseInt(rectYp + (cellmax - imgHeight) / 2)
          rectXp = rectXp + 1
        }
        else {
          imgHeight = cellmax;
          imgWidth = parseInt((imgProps.width * imgHeight) / imgProps.height);
          imgHeight = imgHeight - 2
          rectXp = parseInt(rectXp + (cellmax - imgWidth) / 2)
          rectYp = rectYp + 1
        }

        docport.addImage(base64Image, 'JPEG', rectXp, rectYp, imgWidth, imgHeight, ipos.toString(), undefined, 'FAST')

        let tipofile = videomp4.slice(videomp4.length - 3, videomp4.length)
        let numfile = videomp4.slice(videomp4.length - 11, videomp4.length - 8);
        if (tipofile === "txt") {
          await leerYAbrirURL2(videomp4, docport, rectXp, rectYp, imgWidth, imgHeight, numfile, nuevotitulo);
        }
        else {
          if (!lapp) {
            let nomUno = mainMenu[ipos].ordenOri; //name.slice(0, 7);
            let urlias = servidorURL + "/ias/index.html?" + username + "#" + qrTextRegistro + "," + nomUno;
            //docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: urlias });
            docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: videomp4 }); // XXXXXXXXXXXXXXXXXXXXXX
          }
          else {
            docport.link(rectXp, rectYp, imgWidth, imgHeight, { url: videomp4 }); // XXXXXXXXXXXXXXXXXXXXXX
          }
          totalUrl.push(videomp4)
        }

        let agua = new Image()
        agua.src = "../../iconos/cst.png"
        docport.addImage(agua, "PNG", rectXp + imgWidth - cellmax / 4 - 1, rectYp + imgHeight - 2, cellmax / 4, 1, undefined, 'FAST')

        let paragraph = name.toUpperCase()
        paragraph = paragraph.slice(8, paragraph.length - 4)

        if (paragraph.length > 25) {
          paragraph = paragraph.slice(0, 25) + "";
        }
        let remplaza = /_+/gi;
        paragraph = paragraph.replace(remplaza, " ");
        let foo = paragraph;

        let nseg = menu //mainMenu[ipos].menu
        let sseg = nseg.toString()
        let numeroExec = parseInt(sseg.substr(0, 3))
        let nameMp44 = ""
        //if (numeroExec > 900 && numeroExec < 1000) {
        if (!lapp) {
          pathImages = servidorURL + "/ias/index.html?";
          //let urlias = servidorURL + "/ias/openvideo.html?," + name;
          //let urlias = servidorURL + "/ias/zHand.html?filtro=";
          //urlias = urlias + paragraph;
          docport.textWithLink(paragraph, celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: videomp4 });
        }
        else {
          pathImages = servidorURL + "/rhb/index.html?";
          //nameMp44 = name
          //nameMp44 = ',' + nameMp44
          if (lModifFoo) foo = prompt('Puede modificar el titulo de la imagen ' + ii.toString() + ": ", foo);
          if (foo) {
            docport.textWithLink(foo.toUpperCase(), celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: '' });
          }
          else {
            docport.textWithLink(paragraph, celliniw + cellw * npc + 2, cellinih + cellh * npf + ncode - 3.5, { url: '' });
          }
        }
      }
      npk++
      npc++
      if (npc > 3) {
        npf++;
        npc = 0;
      }
      if (npf > 2) {
        npf = 0;
      }
    }
  }

  //////////////////////////////////////////////////////////////////

  docport.addImage(dataUrl, "PNG", celliniw + cellw * 3.75 - 20, 10, 31, 31, undefined, 'FAST');
  docport.link(celliniw + cellw * 3.75 - 20, 10, 31, 31, { url: pathPdf })

  /////////////////////////////////////////////////////////////////////////////////////
  console.info(totalUrl)
  let totalAnot = "";
  for (let i = 0; i < totalUrl.length; i++) {
    totalAnot = totalAnot + totalUrl[i] + ",";
  }
  //console.info(totalAnot)
  totalAnot = totalAnot.slice(0, totalAnot.length - 1)

  console.info(totalAnot)
  console.info(totalMp4)
  console.info(pathPdf)

  //totalMp4 = totalMp4.slice(1, totalMp4.length)

  docport.setProperties({
    title: nameSave,
    subject: 'exercicis',
    author: 'CST. Servei de fisioteràpia: ' + username,
    keywords: totalAnot,
    creator: 'Software info. (abeciabuil@gmail.com)',
  });

  let tituloSave = qrTextTitulo + '_' + qrTextRegistro + '.pdf'

  // ── Pàgina 2: QR de recreació ─────────────────────────
  const _newpathPdf2 = (lapp ? servidorURL + '/rhb/newpdf.html?' : servidorURL + '/ias/newpdf.html?')
    + username + '#' + qrTextTitulo + '_' + qrTextRegistro + totalMp4Lite;
  docport.addPage();
  docport.addImage(logo, 'PNG', celliniw + 2, 10, 36, 18, undefined, 'FAST');
  docport.setFontSize(13); docport.setTextColor(40, 40, 40);
  docport.text(qrTextTitulo + '_' + qrTextRegistro, celliniw + 42, 18);
  docport.setFontSize(8);
  docport.text(new Date().toLocaleDateString('ca-ES'), celliniw + 42, 24);
  {
    const _qs = 40, _pw = 210, _qx = (_pw - _qs) / 2, _qy = 60;
    const _qr2 = new QRious({ background: '#ffffff', foreground: '#000000', level: 'H', padding: 0, size: 600, value: _newpathPdf2 });
    docport.addImage(_qr2.toDataURL('image/png'), 'PNG', _qx, _qy, _qs, _qs, undefined, 'FAST');
    docport.link(_qx, _qy, _qs, _qs, { url: _newpathPdf2 });
    docport.setFontSize(10); docport.setTextColor(40, 40, 40);
    const _ty = _qy + _qs + 14;
    ["Aquest QR s'ofereix per compatibilitat amb els diferents navegadors.",
     "Us permet recrear el pdf al vostre sistema en lloc d'obrir l'aplicació SEFiR.",
     "Escanegeu el QR superior d'aquesta pàgina i obriu el pdf.",
     "",
     "Este QR se ofrece por compatibilidad con los diferentes navegadores.",
     "Le permite recrear el pdf en su sistema en lugar de abrir la aplicación SEFiR.",
     "Escanear el QR superior de esta página y abrir el pdf.",
    ].forEach((l, i) => docport.text(l, _pw / 2, _ty + i * 7, { align: 'center' }));
  }

  closeSidenav();

  //let burl = docport.output('bloburl', '_self');
  //window.open(burl);
  let timestampEvent = new Date().toLocaleString('en-GB', { timeZone: 'Europe/Madrid', hour12: true });
  const eventDataPdf = {
    uniqueNumber: Date.now(),
    timestamp: timestampEvent,
    autor: username,
    pdf_nom: qrTextTitulo + '_' + qrTextRegistro,
    qr_nom: pathPdf,
    image_nom: totalMp4,
  };
  console.info(eventDataPdf)
  if (upload) {
    let savepdf = false;
    savepdf = confirm('El archivo esta preparado, puede crearlo!.');
    if (savepdf) {
      if (navigator.onLine) {
        console.log("Tienes conexión a Internet.");
        let username = localStorage.getItem('username'); //*********************//if (username !== "jmab")
        logEventPdf(eventDataPdf)
      } else {
        console.log("No tienes conexión a Internet.");
      }

      // Guardar el PDF antes de subirlo
      let nombreArchivo = qrTextTitulo + '_' + qrTextRegistro + '.pdf';
      await docport.save(nombreArchivo);

      try {
        // Generar el PDF y obtenerlo como Blob
        const pdfBlob = await docport.output("blob");

        // Crear FormData y adjuntar el archivo PDF
        const formData = new FormData();
        formData.append("file", pdfBlob, nombreArchivo);

        const urlphp = servidorURL + '/php/pdf/php_upload_pdf.php?t=' + new Date().getTime();
        // Enviar el archivo PDF al servidor con fetch()

        const response = await fetch(urlphp, {
          method: 'POST',
          body: formData,
        });

        if (!response.ok) {
          throw new Error('Error al subir el archivo.');
        }
        const result = await response.text();
        console.info("Respuesta del servidor:", result);

        // Actualizar el estado en la UI
        const statusElement = document.getElementById('status');
        if (statusElement) {
          statusElement.innerText = result;
          obtenerPdfs();
        }
      } catch (error) {
        console.error("Error al subir el archivo:", error);

        const statusElement = document.getElementById('status');
        if (statusElement) {
          statusElement.innerText = error.message;
        }
      }
    } else {
      alert("Operación cancelada.");
    }
  }
  else {
    if (navigator.onLine) {
      console.log("Tienes conexión a Internet.");
      let username = localStorage.getItem('username'); //*********************//if (username !== "jmab")
      logEventPdf(eventDataPdf)
    } else {
      console.log("No tienes conexión a Internet.");
    }
    ///////////////////////////////////
    let savepdf = false;
    savepdf = confirm('El archivo esta preparado, puede crearlo!.');
    if (savepdf) docport.save(qrTextTitulo + '_' + qrTextRegistro + '.pdf')
  }
}
///////////////////////////////////
///////////////////////////////////
//////////////////////////////////
async function fetchImageAsBase64(name) {
  let base64Image;

  console.info(servidorURL)
  try {
    //const url = servidorURL + `/php/pdf/php_get_image.php?image_name=${encodeURIComponent(name)}`;
    const url = servidorURL + `/php/pdf/php_get_image.php?image_name=${encodeURIComponent(name)}`;
    console.info(url)
    // Obtener la imagen como un Blob
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error('Error al obtener la imagen.');
    }
    const blob = await response.blob();
    // Leer el blob como una data URL (base64)
    base64Image = await readBlobAsDataURL(blob);
  } catch (error) {
    console.error('Error:', error);
  }
  return base64Image;
}

function readBlobAsDataURL(blob) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onloadend = function () {
      resolve(reader.result);
    };
    reader.onerror = function (error) {
      reject(error);
    };
    reader.readAsDataURL(blob);
  });
}

async function logEventPdf(eventData) {

  const response = await fetch(servidorURL + '/php/logs/php_log_pdf.php?t=' + new Date().getTime(), {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json; charset=utf-8'
    },
    body: JSON.stringify(eventData)
  });

  const result = await response.json();
  console.log(result);
}

////////////////////////////////////////////
async function leerYAbrirURL2(txtUrl, doc, rectXp, rectYp, imgWidth, imgHeight, numfile, nuevotitulo) {

  // URL del archivo .txt en el servidor
  const archivoURL = txtUrl;  // Cambia esto por la URL de tu archivo
  console.info(txtUrl)
  // Usamos fetch() para obtener el contenido del archivo .txt
  await fetch(archivoURL)
    .then(response => {
      if (!response.ok) {
        throw new Error('No se pudo obtener el archivo');
      }
      return response.text();  // Leemos el archivo como texto
    })
    .then(contenido => {
      const urlTxt = contenido.trim(); // Extraemos la URL y quitamos espacios innecesarios

      // Verificamos si el contenido es una URL válida
      if (isValidUrl(urlTxt)) {
        console.log('URL extraída:', urlTxt);
        let newnew = urlTxt;
        //let urlOrin = newnew.slice(0, 21);

        //if (urlOrin == servidorURL + "") {
        if (parseInt(numfile[0]) == 8 && parseInt(numfile[1]) == 9 && parseInt(numfile[2]) == 9) {
          newnew = urlTxt + '?' + nuevotitulo;
        } else {
          if (parseInt(numfile[0]) == 8 && parseInt(numfile[1]) == 8 && parseInt(numfile[2]) == 9) {
            newnew = servidorURL + "/viewpdf.html" + '#' + urlTxt;
          }
        }
        console.info(newnew);
        //urlTxt = newnew;
        doc.link(rectXp, rectYp, imgWidth, imgHeight, { url: newnew }); //
        totalUrl.push(newnew)
        //return urlTxt;
        //window.open(url, '_blank');  // Abrimos la URL en una nueva ventana
      } else {
        //urlTxt = "";
        alert('El archivo no contiene una URL válida');
        //return txtUrl;
      }
      //return urlTxt;
    })
    .catch(error => {
      console.error('Error al leer el archivo:', error);
      alert('Hubo un error al leer el archivo');
    });

}

// Función para verificar si la URL es válida (básica)
function isValidUrl(url) {
  const regex = /^(http|https):\/\/[^\s/$.?#].[^\s]*$/i;
  return regex.test(url);
}
/////////////////////////////////
