<% /*
     $Revision$
     $Id$

     File:               MLD/mld_flexkenmerk.inc
     Description:        Functie die html code genereert voor de presentatie van de flexvelden
     Parameters:         urole                Rol van de gebruiker (frontend, frontoffice, backoffice, management info)
                         opdr_type            Opdracht type
                         reado                Readonly
                         flexcolumns          aantal kolommen voor flexkenmerken
                         advanced             Geadvanceerd
                         prs_key              Perslid key
     Context:            Functie wordt aangeroepen door
                         1) load_kenmerk.asp
                         2) mld_melding.asp die initieel serverside deze html code invoegd.
    Note:
*/ %>

<!-- #include file="../Shared/kenmerk_common.inc" -->
<%
function generateFlexKenmerkBlock(params)
{
    if (!params.fnpre) // Mobile geeft die zelf mee
    {
        if (params.advanced)
        {
            params.fnpre = function () { BLOCK_START("mldAdvancedFlex"); }; // zolang het maar geen mldFlex is, die heeft float:right
            params.fnpost = BLOCK_END;
        }
        else
        {
            params.fnpre = function () { BLOCK_START((params.opdr_type>0?"opdrFlex":"mldFlex")+(S("mld_flexcolumns")!=1?"2":""),
                                                      L("lcl_mld_flexblok")); };
            params.fnpost = BLOCK_END;
        }
    }
      // Merk op: alleen bij geavanceerd zoeken kunnen deze array's meerdere records bevatten
      //          in alle andere gevallen hebben te maken met één waarde.
      var stdm_arr = (params.stdm_arr? params.stdm_arr : []);
      var disc_arr = (params.disc_arr? params.disc_arr : []);
      var srtdisc  = (params.srtdisc? params.srtdisc : []);
      var mld_key = (params.mld_key? params.mld_key : -1);
      var opdr_type = (params.opdr_type? params.opdr_type : -1);
      var opdr_type_org = (params.opdr_type_org? params.opdr_type_org : -1);
      var opdr_key = (params.opdr_key? params.opdr_key : -1);
      var reado = (params.reado? params.reado : false);
      var showClose = (params.showClose? params.showClose : false);
      var copy = (params.copy? params.copy : false);
      var opdr_status = (params.opdr_status? params.opdr_status : -1);
      var advanced = (params.advanced? params.advanced : false); // Geavanceerd
      var prs_key = (params.prs_key? params.prs_key : -1); // Perslid key

      // opdrman true betekent: user mag opdracht flexkenmerken > 900 zien/editen
      var authparamsORDSUP = user.checkAutorisation("WEB_ORDSUP", true);
      var opdrman = authparamsORDSUP && (authparamsORDSUP.PRSreadlevel < 9 || authparamsORDSUP.PRSwritelevel < 9 || authparamsORDSUP.ALGreadlevel < 9 || authparamsORDSUP.ALGwritelevel < 9)
      var flexcolumns = (params.flexcolumns? params.flexcolumns : 1);

      if (stdm_arr.length != 0 && disc_arr.length == 0)
      {
        var sql = "SELECT mld_ins_discipline_key"
                + "  FROM mld_stdmelding s"
                + " WHERE s.mld_stdmelding_key IN (" + stdm_arr.join(",") + ")";
        var oRs = Oracle.Execute(sql);
        disc_arr = [(oRs("mld_ins_discipline_key").Value)];
      }

      if (mld_key < 0 || disc_arr.length > 1)
      { // Het is een nieuwe melding
        var my_mldrechten = user.func_enabled("MLD", disc_arr.join(",")); // mld.func_enabled_melding is nauwkeuriger maar overkill?
        my_mldrechten.canFEwrite = my_mldrechten.canWrite("WEB_MLDUSE"); // Er moet ook gelden dat het mijn melding is. Dat is het geval want het is een nieuwe melding die ik zelf invoer en aanmaak.
      }
      else
        var my_mldrechten = mld.func_enabled_melding(mld_key);

      var otherKenmerkPath = "null";
      var sql_waarde = "";

      // Load existing or default values. Try to maintain values when changing type as well
      // Onderscheid vier gevallen:
      // 1) wijzigen opdracht of geavanceerd,
      // 2) wijzigen melding,
      // 3) aanmaken opdracht,
      // 4) aanmaken melding of geavanceerd.
      var changeOpdracht = false;
      var changeMelding = false;
      var newOpdracht = false;
      var newMelding = false;
      var advancedOpdracht = false;
      var advancedMelding = false;

      if (opdr_type > 0 && opdr_key > 0)
        changeOpdracht = true;                   // Wijzigen opdracht
      else if (stdm_arr.length != 0 && mld_key > 0)
        changeMelding = true;                    // Wijzigen melding
      else if (opdr_type > 0 && mld_key > 0)
        newOpdracht = true;                      // Aanmaken opdracht
      else if (opdr_type > 0 && advanced && opdr_key < 0 && mld_key < 0)
        advancedOpdracht = true;                 // Opvragen opdracht kenmerken voor lijsten (Geavanceerd)
      else if ((stdm_arr.length != 0 || disc_arr.length != 0 || srtdisc.length != 0) && advanced && opdr_key < 0 && mld_key < 0)
        advancedMelding = true;                  // Opvragen melding kenmerken voor lijsten (Geavanceerd)
      else // (stdm_arr.length != 0 && mld_key < 0)
        newMelding = true;                       // Aanmaken melding

      // 1) Wijzigen opdracht of geavanceerd
      if (changeOpdracht || advancedOpdracht)
      { // Bestaande opdrachtkenmerk waarden of kopiëren
        if (copy || (opdr_type_org > 0 && opdr_type_org != opdr_type))
        { // Kopieeer eventueel flexfiles
          otherKenmerkPath = "(SELECT 'MLD/" + subfolderKey("O", opdr_key) + "/' || mld_kenmerk_key"
                          + " FROM  mld_kenmerk k2, mld_srtkenmerk t2"
                          + " WHERE k2.mld_typeopdr_key = " + opdr_type_org
                          + "   AND k2.mld_kenmerk_niveau = 'O'"
                          + "   AND k2.mld_kenmerk_verwijder IS NULL"
                          + "   AND k2.mld_srtkenmerk_key = t2.mld_srtkenmerk_key"
                          + "   AND k2.mld_kenmerk_groep = k.mld_kenmerk_groep"
                          + "   AND t2.mld_srtkenmerk_verwijder IS NULL"
      	                  + "   AND t2.mld_srtkenmerk_key = t.mld_srtkenmerk_key)";
        }

        // Doordat we in de query controleren tegen opdr_type_org is er het gewenste
        // neveneffect dat de waardes behouden blijven bij (achteraf) wisselen
        // van type opdracht
        // Die check is trouwens redelijk redundant ware het niet dat er wat
        // datavervuiling is wat een 'subselect return more than one row' kan
        // geven in extreme situaties
        sql_waarde = " (SELECT v.mld_kenmerkopdr_waarde"
                   + "   FROM mld_kenmerkopdr v"
                   + "      , mld_kenmerk vk"
                   + "  WHERE v.mld_opdr_key = " + opdr_key
                   + "    AND v.mld_kenmerk_key = vk.mld_kenmerk_key"
                   + "    AND vk.mld_typeopdr_key = " + opdr_type_org
                   + "    AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
                   + "    AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
                   + "    AND v.mld_kenmerkopdr_verwijder IS NULL)";

        sql_filter = "       mld_typeopdr s"
                   + " WHERE s.mld_typeopdr_key = " + opdr_type
                   + "   AND (k.mld_typeopdr_key = s.mld_typeopdr_key"
                   + "   AND k.mld_kenmerk_niveau = 'O')";

      }
      // 2) Wijzigen melding
      else if (changeMelding)
      { // Existing melding kenmerk values. stdm_arr heeft nu 1 waarde
        // Doordat we in de query controleren tegen old_stdm is er het gewenste
        // neveneffect dat de waardes behouden blijven bij (achteraf) wisselen
        // van standaardmelding
        oRs = Oracle.Execute("SELECT mld_stdmelding_key FROM mld_melding where mld_melding_key = " + mld_key);
        old_stdm = oRs(0).value;
        if (old_stdm != stdm_arr)
          __Log("Old MLD_STDMELDING_KEY: " + old_stdm + " New: " + stdm_arr.join(","));
        sql_waarde = " (SELECT v.mld_kenmerkmelding_waarde"
                   + "     FROM mld_kenmerkmelding v"
                   + "        , mld_kenmerk vk"
                   + "    WHERE v.mld_melding_key = " + mld_key
                   + "      AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
                   + "      AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
      	           + "      AND vk.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
        		       //+ "    AND vk.mld_stdmelding_key = " + old_stdm
                   + "      AND v.mld_kenmerk_key = vk.mld_kenmerk_key"
                   + "      AND v.mld_kenmerkmelding_verwijder IS NULL)";

        sql_filter = "       mld_stdmelding s, mld_discipline d"
                   + " WHERE s.mld_stdmelding_key IN (" + stdm_arr.join(",") + ")"
                   + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
                   + "   AND ((k.mld_stdmelding_key = s.mld_stdmelding_key"
                   + "            AND k.mld_kenmerk_niveau = 'S')"
                   + "        OR (k.mld_stdmelding_key = s.mld_ins_discipline_key"
                   + "            AND k.mld_kenmerk_niveau = 'D')"
                   + "        OR (k.mld_stdmelding_key = d.ins_srtdiscipline_key"
                   + "            AND k.mld_kenmerk_niveau = 'T'))"
                   + (copy
                     ? " AND t.mld_srtkenmerk_kenmerktype NOT IN ('E', 'F', 'M')" // Bij kopieren melding niet de flexbestanden kopieren.
                     : "");

      }
      // 3) Aanmaken opdracht
      else if (newOpdracht)
      { // New opdr, copy parent's melding kenmerk values or take default
        __Log("About to copy kenmerk values from parent: " + mld_key);
        sql_waarde = " COALESCE((SELECT v.mld_kenmerkmelding_waarde"
                   + "              FROM mld_kenmerkmelding v"
                   + "                 , mld_kenmerk vk"
                   + "                 , mld_srtkenmerk vt"
                   + "             WHERE v.mld_melding_key = " + mld_key
                   + "               AND vk.mld_srtkenmerk_key = vt.mld_srtkenmerk_key"
                   + "               AND vk.mld_srtkenmerk_key = k.mld_srtkenmerk_key"
                   + "               AND vk.mld_kenmerk_groep = k.mld_kenmerk_groep"
      	           // NIET! + "               AND vk.mld_kenmerk_niveau = k.mld_kenmerk_niveau"
      	           + "               AND v.mld_kenmerk_key = vk.mld_kenmerk_key"
                   + "               AND v.mld_kenmerkmelding_verwijder IS NULL), " + lcl.xsql('k.mld_kenmerk_default','k.mld_kenmerk_key') + ")";

        // Kopieeer eventueel flexfiles
        otherKenmerkPath = " (SELECT 'MLD/" + subfolderKey("M", mld_key) + "/' || mld_kenmerk_key "
                        + "     FROM mld_melding m"
                        + "        , mld_kenmerk k2"
                        + "        , mld_srtkenmerk t2"
                        + "        , mld_stdmelding s"
                        + "        , mld_discipline d"
                        + "    WHERE m.mld_melding_key = " + mld_key
                        + "      AND s.mld_stdmelding_key = m.mld_stdmelding_key"
                        + "      AND k2.mld_kenmerk_groep = k.mld_kenmerk_groep"
                        + "      AND s.mld_ins_discipline_key = d.ins_discipline_key"
                        + "      AND ((k2.mld_stdmelding_key = s.mld_stdmelding_key"
                        + "           AND k2.mld_kenmerk_niveau = 'S')"
                        + "       OR (k2.mld_stdmelding_key = s.mld_ins_discipline_key"
                        + "           AND k2.mld_kenmerk_niveau = 'D')"
                        + "       OR (k2.mld_stdmelding_key = d.ins_srtdiscipline_key"
                        + "           AND k2.mld_kenmerk_niveau = 'T'))"
                        + "      AND k2.mld_kenmerk_verwijder IS NULL"
                        + "      AND k2.mld_srtkenmerk_key = t2.mld_srtkenmerk_key"
                        + "      AND t2.mld_srtkenmerk_verwijder IS NULL"
                        + "      AND t2.mld_srtkenmerk_key = t.mld_srtkenmerk_key)";

        sql_filter = "       mld_typeopdr s"
                   + " WHERE s.mld_typeopdr_key = " + opdr_type
                   + "   AND (k.mld_typeopdr_key = s.mld_typeopdr_key"
                   + "   AND k.mld_kenmerk_niveau = 'O')";
        if (newOpdracht && params.mobile)
          sql_filter += " AND t.mld_srtkenmerk_kenmerktype <> 'M'"
      }
      // 4) Aanmaken melding of of geavanceerd
      else
      { // Dan blijf een nieuwe melding over of geavanceerd meldingen: gebruik default waarden
        sql_waarde = " "+ lcl.xsql('k.mld_kenmerk_default','k.mld_kenmerk_key');

        if (stdm_arr.length != 0 || newMelding)
        {
          var x_key = "s.mld_stdmelding_key";
          if (stdm_arr.length)
              var x_arr = stdm_arr;
          else
              var x_arr = [-1]; // Vals spelen
        }
        else if (disc_arr.length != 0)
        {
          var x_key = "s.mld_ins_discipline_key";
          var x_arr = disc_arr;
        }
        else if (srtdisc.length != 0)
        {
          var x_key = "d.ins_srtdiscipline_key";
          var x_arr = srtdisc;
        }
        sql_filter = "       mld_stdmelding s, mld_discipline d"
                   + " WHERE " + x_key + " IN (" + x_arr.join(",") + ")"
                   + "   AND s.mld_ins_discipline_key = d.ins_discipline_key"
                   + "   AND ((k.mld_stdmelding_key = d.ins_srtdiscipline_key"
                   + "            AND k.mld_kenmerk_niveau = 'T')"
                   + (advanced || disc_arr.length != 0 || stdm_arr.length != 0
                     ? "      OR (k.mld_stdmelding_key = s.mld_ins_discipline_key"
                       + "        AND k.mld_kenmerk_niveau = 'D')"
                     : "")
                   + (advanced || stdm_arr.length != 0
                     ? "      OR (k.mld_stdmelding_key = s.mld_stdmelding_key"
                       + "        AND k.mld_kenmerk_niveau = 'S')"
                     : "")
                   + "       )";
      }

      // Bij 'advanced' groeperen we op mld_srtkenmerk_key ipv mld_kenmerk_key
      // in de zoek-html komt uiteindelijk de srtkenmerk_key te staan
      // in getkenmerksql.inc wordt dat voor MLD weer intelligent opgepikt
      var sql = "SELECT DISTINCT " + (advanced&&!params.wfbuilder?"k.mld_srtkenmerk_key":"k.mld_kenmerk_key") + "  kenmerk_key, "
              + "k.mld_kenmerk_niveau,"
              + (Session("logging")>0?" k.mld_kenmerk_niveau || ':' ||":"") // Lettertje ervoor bij logging
              + lcl.xsql('t.mld_srtkenmerk_omschrijving', 't.mld_srtkenmerk_key') +" kenmerk_omschrijving, "
              + "       t.mld_srtkenmerk_kenmerktype     kenmerk_kenmerktype, "
              + "       t.fac_kenmerkdomein_key          kenmerkdomein_key, "
              + "       t.mld_srtkenmerk_lengte          kenmerk_lengte, "
              + "       t.mld_srtkenmerk_dec             kenmerk_dec, "
              + "       t.mld_srtkenmerk_nmin            kenmerk_nmin, "
              + "       t.mld_srtkenmerk_nmax            kenmerk_nmax, "
              + sql_waarde + "                           kenmerk_waarde, "
              + "       k.mld_kenmerk_volgnummer         kenmerk_volgnr, "
              + "       k.mld_kenmerk_groep              kenmerk_groep, "
              + lcl.xsql('t.mld_srtkenmerk_dimensie', 't.mld_srtkenmerk_key') +" kenmerk_dimensie, "
              + lcl.xsql('k.mld_kenmerk_hint', 't.mld_srtkenmerk_key') +" kenmerk_hint, "
              + lcl.xsql('k.mld_kenmerk_default','k.mld_kenmerk_key') +" kenmerk_default, "
              + "       k.mld_kenmerk_verplicht          kenmerk_verplicht, "
              + "       " + otherKenmerkPath + " otherpath,"   // corresponderende pad voor copy/move folder
              + "       k.mld_kenmerk_toonbaar           kenmerk_toonbaar,"         //  1=Alleen toonbaar (readonly)
              + "       k.mld_kenmerk_uniek              kenmerk_uniek,"
              + "       k.mld_kenmerk_regexp             kenmerk_regexp"
              + "  FROM mld_srtkenmerk t"
              + "     , mld_kenmerk k"
              + "  ," + sql_filter
              + "   AND k.mld_kenmerk_verwijder IS NULL"
              + "   AND k.mld_srtkenmerk_key=t.mld_srtkenmerk_key"
              + "   AND t.mld_srtkenmerk_verwijder IS NULL";

      var sql1 = "";

      if (changeOpdracht || newOpdracht || advancedOpdracht)
      {
        // PF/MGE 29-09-09: Ook bij nieuw opdrachten mag ik afmeld-kenmerken tussen de 100..900 niet zien
        if ((showClose || (opdr_status == 6 || opdr_status == 7)) && changeOpdracht && !copy)
        { // dan wil ik ze wel zien
        }
        else
        { // Alleen bij of na afmelden mogen afmeld-kenmerken tussen de 100..900
          sql1 = " AND (k.mld_kenmerk_volgnummer <= 100 OR k.mld_kenmerk_volgnummer >= 900)";
        }
        // Alleen met opdrman rechten mag ik opdracht flexkenmerken boven de 900 zien
        if (!opdrman)
          sql1 += " AND k.mld_kenmerk_volgnummer <= 900";
      }
      else
      { // changeMelding || newMelding || advancedMelding
        // Alleen met mldbof rechten mag ik melding flexkenmerken boven de 900 zien. New feature 02-02-2010
        if (!my_mldrechten.canRead("WEB_MLDBOF"))
          sql1 += " AND k.mld_kenmerk_volgnummer <= 900";

        if (!my_mldrechten.canRead("WEB_MLDBOF") && !my_mldrechten.canRead("WEB_MLDFOF") &&
            !my_mldrechten.canRead("WEB_MLDBO2") && !my_mldrechten.canRead("WEB_MLDBO3") &&
            !my_mldrechten.canRead("WEB_MLDORD") && !my_mldrechten.canRead("WEB_MLDBAC"))
        { // Met alleen WEB_MLDUSE rechten mag ik kenmerken tussen 800 en 900 niet zien
          sql1 += " AND (k.mld_kenmerk_volgnummer <= 800 OR k.mld_kenmerk_volgnummer >= 900)";
        }
      }

      sql = sql + sql1;

     if (advanced) // Nog harder de dubbelen er uit filteren. Een kenmerk kan bijvoorbeeld bij verschillende
     {             // objectsoorten een ander volgnummer hebben en dat interesseert ons echt niet.
        sql = "SELECT kenmerk_key, "
            + "       MIN(mld_kenmerk_niveau)   mld_kenmerk_niveau, "
            + "       MIN(kenmerk_omschrijving) kenmerk_omschrijving, "
            + "       MIN(kenmerk_kenmerktype ) kenmerk_kenmerktype, "
            + "       MIN(kenmerkdomein_key   ) kenmerkdomein_key, "
            + "       MIN(kenmerk_lengte      ) kenmerk_lengte, "
            + "       MIN(kenmerk_dec         ) kenmerk_dec, "
            + "       MIN(kenmerk_nmin        ) kenmerk_nmin, "
            + "       MIN(kenmerk_nmax        ) kenmerk_nmax, "
            + "       MIN(kenmerk_waarde      ) kenmerk_waarde, "
            + "       MIN(kenmerk_volgnr      ) kenmerk_volgnr, "
            + "       MIN(kenmerk_groep       ) kenmerk_groep, "
            + "       MIN(kenmerk_dimensie    ) kenmerk_dimensie, "
            + "       MIN(kenmerk_hint        ) kenmerk_hint, "
            + "       MIN(kenmerk_default     ) kenmerk_default, "
            + "       MIN(otherpath           ) otherpath, "
            + "       MIN(kenmerk_verplicht   ) kenmerk_verplicht, "
            + "       MIN(kenmerk_toonbaar    ) kenmerk_toonbaar, "
            + "       MIN(kenmerk_uniek       ) kenmerk_uniek,"
            + "       MIN(kenmerk_regexp      ) kenmerk_regexp"
            + "  FROM (" + sql + ")"
            + " GROUP BY kenmerk_key";
      }
	  // Specifieke kenmerk_keys opgevraagd?
      if (params.kenmerk_keys && params.kenmerk_keys.length)
      {
        sql += " AND k.mld_kenmerk_key IN (" + params.kenmerk_keys.join(",") + ")"
      }
      sql = sql + " ORDER BY kenmerk_volgnr, UPPER(kenmerk_omschrijving), DECODE(mld_kenmerk_niveau,'T',0,'D',1,'S',2)";
      // ik hoef hierna dus nooit kenmerken te onderdrukken, hooguit readonly maken

      if (changeOpdracht || newOpdracht || advancedOpdracht)
      {
        var kenmerk_module = "O";
        var key = opdr_key;
      }
      else
      {
        var kenmerk_module = "M";
        var key = mld_key;
      }

      function isReadonly (volgnummer)
      {
        if (reado) return true;  // Als meegegeven dan altijd readonly
        if (changeMelding || newMelding) // Advanced zoeken (advancedOpdracht) is nooit readonly
        { // JGL: een en ander kan veel compacter beschreven worden maar dat
          //      is dan niet meer te begrijpen.
          // Voor bestaande meldingen zou eigenlijk my_mldrechten.canFlexChange meegenomen moeten worden.
          // Maar daar zorgt de parameter reado nu al voor.
          if (volgnummer <= 800)
          {
            if (my_mldrechten.canWrite("WEB_MLDFOF") || my_mldrechten.canFEwrite)
                return false; // ik mag schrijven
            return true;
          }
          if (volgnummer > 800 && volgnummer < 900)
          {
            if (my_mldrechten.canWrite("WEB_MLDFOF"))
                return false; //ik mag schrijven
            return true; // niet
          }
          if (volgnummer == 900)
          {
            if (my_mldrechten.canWrite("WEB_MLDFOF") || my_mldrechten.canWrite("WEB_MLDBOF"))
                return false;
            return true;
          }
          if (volgnummer > 900) // het enige wat overblijft
          {
            if (my_mldrechten.canWrite("WEB_MLDBOF"))
                return false; // ik mag
            return true; // niet
          }
        }
        if (changeOpdracht || newOpdracht) // Advanced zoeken (advancedOpdracht) is nooit readonly
        {
          if (opdr_status == 7)
            return true; // bij AV mag je nooit wijzigen
          if (opdr_status != 7 && volgnummer >= 900 && opdrman)
            return false; // bij TV en opdrman mag je nog boven de 900 flexkenmerken aanpassen
          if (volgnummer > 100 && volgnummer <= 900)
            return !showClose; // afmeld-kenmerken mag je alleen tijdens het afmelden wijzigen
          // uiteindelijk dan nog de flexkenmerken <= 100 (vermoeden is dat MLDBOF hier eigenlijk niet bij hoort)
          return !my_mldrechten.canWrite("WEB_MLDBOF") && !my_mldrechten.canWrite("WEB_ORDBO2") && !my_mldrechten.canWrite("WEB_ORDBOF");
        }
        return false; // 'k vind het wel best
      }

      listKenmerk(sql,
                  "MLD",
                  key,
                  { flexcolumns: flexcolumns,
                    kenmerk_search: advanced,
                    kenmerk_extraTD: (changeOpdracht || newOpdracht), // Voor opdrachten een extra TD erachter TODO: (MGE) klopt dit nog
                    fnIsReadonly: isReadonly,
                    prs_key: prs_key, // Wordt alleen gebruikt als geldt (!kenmerk_search && !multiMode)
                    parentKey: key,
                    parent_list: params.parent_list,
                    fnpre: params.fnpre,
                    fnpost: params.fnpost,
                    mobile: params.mobile,
                    sqldefaultnotrequired: params.act_key > 0,
                    hideVervallen: newMelding||newOpdracht,
                    niveau: kenmerk_module,
                    wfbuilder: params.wfbuilder
                  }
                 );
} %>
