text:
typedef struct
{
    //
    // The operation; 1 is a request, 2 is a reply.
    //
    uint8_t ui8Op;

    //
    // The hardware type; 1 is Ethernet.
    //
    uint8_t ui8HType;

    //
    // The hardware address length; for Ethernet this will be 6, the length of
    // the MAC address.
    //
    uint8_t ui8HLen;

    //
    // Hop count, used by gateways for cross-gateway booting.
    //
    uint8_t ui8Hops;

    //
    // The transaction ID.
    //
    uint32_t ui32XID;

    //
    // The number of seconds elapsed since the client started trying to boot.
    //
    uint16_t ui16Secs;

    //
    // The BOOTP flags.
    //
    uint16_t ui16Flags;

    //
    // The client's IP address, if it knows it.
    //
    uint32_t ui32CIAddr;

    //
    // The client's IP address, as assigned by the BOOTP server.
    //
    uint32_t ui32YIAddr;

    //
    // The TFTP server's IP address.
    //
    uint32_t ui32SIAddr;

    //
    // The gateway IP address, if booting cross-gateway.
    //
    uint32_t ui32GIAddr;

    //
    // The hardware address; for Ethernet this is the MAC address.
    //
    uint8_t pui8CHAddr[16];

    //
    // The name, or nickname, of the server that should handle this BOOTP
    // request.
    //
    char pcSName[64];

    //
    // The name of the boot file to be loaded via TFTP.
    //
    char pcFile[128];

    //
    // Optional vendor-specific area; not used for BOOTP.
    //
    uint8_t pui8Vend[64];
}
tBOOTPPacket;

//*****************************************************************************
//
// The BOOTP commands.
//
//*****************************************************************************
#define BOOTP_REQUEST           1
#define BOOTP_REPLY             2

//*****************************************************************************
//
// The TFTP commands.
//
//*****************************************************************************
#define TFTP_RRQ                1
#define TFTP_WRQ                2
#define TFTP_DATA               3
#define TFTP_ACK                4
#define TFTP_ERROR              5

//*****************************************************************************
//
// The UDP ports used by the BOOTP protocol.
//
//*****************************************************************************
#define BOOTP_SERVER_PORT       67
#define BOOTP_CLIENT_PORT       68

//*****************************************************************************
//
// The UDP port for the TFTP server.
//
//*****************************************************************************
#define TFTP_PORT               69

//*****************************************************************************
//
// The UDP port used to send the remote firmware update request signal. This
// is the well-known port associated with "discard" function and is also used
// by some Wake-On-LAN implementations.
//
//*****************************************************************************
#define MPACKET_PORT             9

//*****************************************************************************
//
// The length of the remote firmware update request magic packet. This contains
// a 6 byte header followed by 4 copies of the target MAC address.
//
//*****************************************************************************
#define MPACKET_HEADER_LEN 6
#define MPACKET_MAC_REP    4
#define MPACKET_MAC_LEN    6

#define MPACKET_LEN (MPACKET_HEADER_LEN + (MPACKET_MAC_REP * MPACKET_MAC_LEN))

//*****************************************************************************
//
// The marker byte used at the start of the magic packet. This is repeated
// MPACKET_HEADER_LEN times.
//
//*****************************************************************************
#define MPACKET_MARKER     0xAA

//*****************************************************************************
//
// A flag that is true if the BOOTP server should be aborted even though the
// update has not completed.
//
//*****************************************************************************
static uint32_t g_bAbortBOOTP;

//*****************************************************************************
//
// Creates a UDP socket and binds it to a particular port.
//
//*****************************************************************************
static SOCKET
CreateSocket(uint32_t ui32Address, uint32_t ui32Port,
             bool bBroadcast, bool bBind)
{
    struct sockaddr_in sAddr;
    SOCKET sRet;

    //
    // Create a socket.
    //
    if((sRet = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
    {
        return(INVALID_SOCKET);
    }

    //
    // Set the broadcast flag as specified.
    //
    if(setsockopt(sRet, SOL_SOCKET, SO_BROADCAST, (const char *)&bBroadcast,
               sizeof(uint32_t)) == SOCKET_ERROR)
    {
        int32_t i32Tmp = WSAGetLastError();
        closesocket(sRet);
        return(INVALID_SOCKET);
    }

    //
    // Bind the socket to the given port.
    //
    if(bBind)
    {
        memset(&sAddr, 0, sizeof(sAddr));
        sAddr.sin_family = AF_INET;
        sAddr.sin_addr.s_addr = ui32Address;
        sAddr.sin_port = (USHORT)ui32Port;
        if(bind(sRet, (struct sockaddr *)&sAddr, sizeof(sAddr)) == SOCKET_ERROR)
        {
            int32_t i32Tmp = WSAGetLastError();
            closesocket(sRet);
            return(INVALID_SOCKET);
        }
    }

    //
    // Return the created socket.
    //
    return(sRet);
}

//*****************************************************************************
//
// Builds a TFTP data packet.
//
//*****************************************************************************
static uint32_t
BuildTFTPDataPacket(char *pcFileData, uint32_t ui32FileLen,
                    uint8_t *pui8PacketData, uint32_t ui32BlockNum)
{
    uint32_t ui32Length;

    //
    // Determine the number of bytes to place into this packet.
    //
    if(ui32FileLen < (ui32BlockNum * 512))
    {
        ui32Length = ui32FileLen & 511;
    }
    else
    {
        ui32Length = 512;
    }

    //
    // Fill in the packet header.
    //
    pui8PacketData[0] = (TFTP_DATA >> 8) & 0xff;
    pui8PacketData[1] = TFTP_DATA & 0xff;
    pui8PacketData[2] = (uint8_t)((ui32BlockNum >> 8) & 0xff);
    pui8PacketData[3] = (uint8_t)(ui32BlockNum & 0xff);

    //
    // Copy the file data into the packet.
    //
    memcpy(pui8PacketData + 4, pcFileData + ((ui32BlockNum - 1) * 512), ui32Length);

    //
    // Return the length of the packet.
    //
    return(ui32Length + 4);
}

//*****************************************************************************
//
// Sends a magic packet to the client whose MAC address is supplied. This
// packet informs the client that a remote firmware update is being requested.
//
// sSocket is the socket that the magic packet is to be sent on. This must be
// a UDP broadcast socket bound to port 9 (well-known port which is supposed
// to discard all packets sent to it. This port is used by some wake-on-LAN
// implementations).
//
// pui8MACAddr is the MAC address of the device to which the magic packet will
// be sent.
//
// This functions sends a UDP broadcast packet to the client identified by
// pui8MACAddr. The packet is based on the wake-on-LAN magic packet but altered
// to ensure that it will not be recognized by WOL LAN adapters. The structure
// is as follows:
//
// AA AA AA AA AA AA followed by the target MAC repeated 4 times.
//
// (a WOL packet uses 6 bytes of FF as a start marker followed by the MAC
// address repeated 16 times. We reduce this to 4 repetitions here to reduce
// the buffering requirement on the target).
//
// On receipt of this packet, a client may chose to pass control to the boot
// loader which will issue a BOOTP request to indicate that it is ready to
// start a remote firmware update.
//
// Returns TRUE on success of FALSE on error.
//
//*****************************************************************************
bool
SendFirmwareUpdateMagicPacket(SOCKET sSocket, uint8_t *pui8MACAddr)
{
    uint8_t pui8Packet[MPACKET_LEN];
    int32_t i32Loop, i32MACLoop, i32Written;
    struct sockaddr_in sAddr;

    //
    // Build the magic packet. Start with the 6 marker bytes.
    //
    for(i32Loop = 0; i32Loop < MPACKET_HEADER_LEN; i32Loop++)
    {
        pui8Packet[i32Loop] = MPACKET_MARKER;
    }

    //
    // Populate the rest of the packet with 8 copies of the target MAC
    // address.
    //
    for(i32Loop = 0; i32Loop < MPACKET_MAC_REP; i32Loop++)
    {
        for(i32MACLoop = 0; i32MACLoop < MPACKET_MAC_LEN; i32MACLoop++)
        {
            pui8Packet[MPACKET_HEADER_LEN +
                      (i32Loop * MPACKET_MAC_LEN) + i32MACLoop] =
                                                    pui8MACAddr[i32MACLoop];
        }
    }

    //
    // Set up the target address.
    //
    sAddr.sin_port = htons(MPACKET_PORT);
    sAddr.sin_addr.s_addr = INADDR_BROADCAST;
    sAddr.sin_family = AF_INET;

    //
    // Now send the packet.
    //
    i32Written = sendto(sSocket, (const char *)pui8Packet, MPACKET_LEN, 0,
                      (SOCKADDR *)&sAddr, sizeof(sAddr));

    //
    // Tell the caller whether or not we were successful.
    //
    return((i32Written == MPACKET_LEN) ? TRUE : FALSE);
}

//*****************************************************************************
//
// Provides a simple BOOTP and TFTP server for use by the boot loader to
// perform a firmware update.
//
// pui8MACAddr is the MAC address of the device for which BOOTP requests will
// be serviced.  If this is 0, then a BOOTP request from any source will be
// processed.
//
// ulLocalAddress it the IP address of the local machine.  This must be the
// address associated with the interface card used to communicate with the
// target.
//
// ui32RemoteAddr is the IP address to be given to the target.
//
// pcFilename is the name of the local file to be sent to the target; it should
// be a binary firmare image.
//
// pfnCallback is the function that is periodically called to provide a
// completion percentage.  If this is 0, then the callback is disabled.
//
//*****************************************************************************
uint32_t
StartBOOTPUpdate(uint8_t *pui8MACAddr, uint32_t ui32LocalAddr,
                 uint32_t ui32RemoteAddr, char *pcFilename,
                 tfnCallback pfnCallback)
{
    uint32_t ui32FileLen, ui32BlockNum, ui32Len, ui32Count;
    uint8_t pui8PacketData[700];
    char *pcFileData;
    SOCKET sBOOTP, sTFTP, sTFTPData, sUpdateSocket;
    struct sockaddr_in sAddr;
    tBOOTPPacket *psPacket;
    fd_set sDescriptors;
    TIMEVAL sTime;
    int32_t i32AddrLen;
    FILE *pFile;
    bool bBOOTPPacketSeen = false;

    //
    // Open the file to be used as the update image.
    //
    VPRINTF(("Reading file (%s) to be downloaded\n", pcFilename));
    pFile = fopen(pcFilename, "rb");
    if(!pFile)
    {
        EPRINTF(("File (%s) not found\n", pcFilename));
        return(ERROR_FILE);
    }

    //
    // Get the length of the file.
    //
    fseek(pFile, 0, SEEK_END);
    ui32FileLen = ftell(pFile);
    fseek(pFile, 0, SEEK_SET);

    //
    // Allocate a buffer to hold the file contents.
    //
    VPRINTF(("... Allocating buffer for file length %u\n", ui32FileLen));
    pcFileData = (char *)malloc(ui32FileLen);
    if(!pcFileData)
    {
        EPRINTF(("Cannot allocate memory for file\n"));
        fclose(pFile);
        return(ERROR_FILE);
    }

    //
    // Read the file contents into the buffer.
    //
    VPRINTF(("... Reading the file\n"));
    if(fread(pcFileData, 1, ui32FileLen, pFile) != ui32FileLen)
    {
        free(pcFileData);
        fclose(pFile);
        return(ERROR_FILE);
    }

    //
    // Close the file.
    //
    fclose(pFile);

    //
    // Create a socket for the BOOTP server.
    //
    VPRINTF(("Setting up network connections\n"));
    VPRINTF(("... Creating sockete for BOOTP server\n"));
    sBOOTP = CreateSocket(ui32LocalAddr, htons(BOOTP_SERVER_PORT), 1, TRUE);
    if(sBOOTP == INVALID_SOCKET)
    {
        EPRINTF(("Cannot allocate socket\n"));
        free(pcFileData);
        return(ERROR_BOOTPD);
    }

    //
    // Create a socket for the TFTP server.
    //
    VPRINTF(("... Creating sockete for TFTP server\n"));
    sTFTP = CreateSocket(ui32LocalAddr, htons(TFTP_PORT), 0, TRUE);
    if(sTFTP == INVALID_SOCKET)
    {
        EPRINTF(("Cannot allocate socket\n"));
        free(pcFileData);
        closesocket(sBOOTP);
        return(ERROR_TFTPD);
    }

    //
    // Create the socket we use to send remote firmware update magic packets.
    VPRINTF(("... Creating sockete for MAGIG packet transmission\n"));
    sUpdateSocket = CreateSocket(ui32LocalAddr, htons(MPACKET_PORT), 1, FALSE);
    if(sUpdateSocket == INVALID_SOCKET)
    {
        EPRINTF(("Cannot allocate socket\n"));
        free(pcFileData);
        closesocket(sTFTP);
        closesocket(sBOOTP);
        return(ERROR_MPACKET);
    }

    //
    // Start off with no TFTP data socket.
    //
    sTFTPData = INVALID_SOCKET;

    //
    // Create a pointer to the packet data to use for interpreting it as a
    // BOOTP request.
    //
    psPacket = (tBOOTPPacket *)pui8PacketData;

    //
    // Clear the flag that indicates that the BOOTP server should be aborted.
    //
    g_bAbortBOOTP = 0;

    //
    // Send an initial remote firmware magic packet.
    //
    VPRINTF(("Sending \"Magic\" packet to initiate Ethernet Boot Loader\n"));
    SendFirmwareUpdateMagicPacket(sUpdateSocket, pui8MACAddr);

    //
    // Loop until the BOOTP server is aborted.  Additionally, once the update
    // has completed, the server will exit on its own.
    //
    VPRINTF(("Starting BOOTP/TFTP Server\n"));
    while(!g_bAbortBOOTP)
    {
        //
        // Set the file descriptor set to the currently opened sockets.
        //
        FD_ZERO(&sDescriptors);
        FD_SET(sBOOTP, &sDescriptors);
        FD_SET(sTFTP, &sDescriptors);
        i32AddrLen = (sTFTP > sBOOTP) ? sTFTP : sBOOTP;
        if(sTFTPData != INVALID_SOCKET)
        {
            FD_SET(sTFTPData, &sDescriptors);
            i32AddrLen = (sTFTPData > i32AddrLen) ? sTFTPData : i32AddrLen;
        }

        //
        // Set a timeout of 500ms.
        //
        sTime.tv_sec = 0;
        sTime.tv_usec = 500000;

        //
        // Display additional status about what type of packet we are
        // waiting on.
        //
        VPRINTF(("Waiting for packet ...\n"));

        //
        // Wait until there is a packet to be read on one of the open sockets.
        //
        if(select(i32AddrLen + 1, &sDescriptors, 0, 0, &sTime) != 0)
        {
            //
            // See if there is a packet waiting to be read from the BOOTP port.
            //
            if(FD_ISSET(sBOOTP, &sDescriptors))
            {
                //
                // Read the packet from the BOOTP port.
                //
                VPRINTF(("... Reading BOOTP packet\n"));
                i32AddrLen = sizeof(sAddr);
                if(recvfrom(sBOOTP, (char *)pui8PacketData,
                            sizeof(pui8PacketData), 0, (struct sockaddr *)&sAddr,
                            &i32AddrLen) != SOCKET_ERROR)
                {
                    //
                    // Make sure this is a valid BOOTP request.
                    //
                    VPRINTF(("... Verifying BOOTP packet\n"));
                    if((psPacket->ui8Op == BOOTP_REQUEST) &&
                       (psPacket->ui8HType == 1) &&
                       (psPacket->ui8HLen == 6) &&
                       (pui8MACAddr ?
                        memcmp(psPacket->pui8CHAddr, pui8MACAddr, 6) == 0 : 1) &&
                       ((stricmp(psPacket->pcSName, "stellaris") == 0) ||
                        (stricmp(psPacket->pcSName, "tiva") == 0)))
                    {
                        VPRINTF(("... Generating BOOTP response\n"));
                        //
                        // Change the operation code from BOOTP request to
                        // BOOTP response.
                        //
                        psPacket->ui8Op = BOOTP_REPLY;

                        //
                        // Fill in the client's address and our address (i.e.
                        // the TFTP server address) in the BOOTP response.
                        //
                        psPacket->ui32YIAddr = ui32RemoteAddr;
                        psPacket->ui32SIAddr = ui32LocalAddr;

                        //
                        // Provide a image filename to the client.  This is
                        // ignored by our TFTP server, but some string is
                        // required.
                        //
                        strcpy(psPacket->pcFile, "firmware.bin");

                        //
                        // Remember that we have seen a BOOTP request from the
                        // client so that we don't send any more firmware
                        // update magic packets.
                        //
                        bBOOTPPacketSeen = TRUE;

                        //
                        // Send the response back to the client using a
                        // broadcast message.
                        //
                        VPRINTF(("... Sending BOOTP response\n"));
                        sAddr.sin_addr.s_addr = INADDR_BROADCAST;
                        sendto(sBOOTP, (char *)pui8PacketData,
                               sizeof(tBOOTPPacket), 0,
                               (struct sockaddr *)&sAddr, i32AddrLen);
                    }
                }
            }

            //
            // See if there is a packet waiting to be read from the TFTP port.
            //
            if(FD_ISSET(sTFTP, &sDescriptors))
            {
                //
                // Read the packet from the TFTP port.
                //
                VPRINTF(("... Reading TFTP packet\n"));
                i32AddrLen = sizeof(sAddr);
                if(recvfrom(sTFTP, (char *)pui8PacketData, sizeof(pui8PacketData),
                            0, (struct sockaddr *)&sAddr, &i32AddrLen) !=
                        SOCKET_ERROR)
                {
                    //
                    // Make sure this is a RRQ request.
                    //
                    VPRINTF(("... Verifying TFTP RRQ request\n"));
                    if((pui8PacketData[0] != ((TFTP_RRQ >> 8) & 0xff)) ||
                       (pui8PacketData[1] != (TFTP_RRQ & 0xff)))
                    {
                        //
                        // Construct an error packet since only RRQ is
                        // supported by this simple TFTP server.
                        //
                        VPRINTF(("... Generate ERROR packet since RRQ\n"));
                        VPRINTF(("... packet not received\n"));
                        pui8PacketData[0] = (TFTP_ERROR >> 8) & 0xff;
                        pui8PacketData[1] = TFTP_ERROR & 0xff;
                        pui8PacketData[2] = 0;
                        pui8PacketData[3] = 4;
                        strcpy((char *)pui8PacketData + 4,
                               "Only RRQ is supported!");

                        //
                        // Send the error packet back to the client.
                        //
                        sendto(sTFTP, (char *)pui8PacketData,
                               strlen((char *)pui8PacketData + 4) + 5, 0,
                               (struct sockaddr *)&sAddr, i32AddrLen);
                    }
                    else
                    {
                        //
                        // If there is already a TFTP data connection, then
                        // close it now (i.e. restart).
                        //
                        if(sTFTPData != INVALID_SOCKET)
                        {
                            VPRINTF(("... Restarting TFTP session\n"));
                            closesocket(sTFTPData);
                        }

                        //
                        // Create a TFTP data socket.
                        //
                        VPRINTF(("... Create TFTP data socket\n"));
                        while((sTFTPData =
                            CreateSocket(ui32LocalAddr,
                                         htons(32768 + (rand() & 8191)), 0,
                                         TRUE)) == INVALID_SOCKET)
                        {
                        }

                        //
                        // Start by sending block number one.
                        //
                        ui32BlockNum = 1;

                        //
                        // Generate the TFTP data packet.
                        //
                        VPRINTF(("... Building TFTP packet (Block %d)\n",
                                ui32BlockNum));
                        ui32Len = BuildTFTPDataPacket(pcFileData, ui32FileLen,
                                                    pui8PacketData, ui32BlockNum);

                        //
                        // Send the TFTP data packet.
                        //
                        VPRINTF(("... Sending TFTP data packet (Block %d)\n",
                                ui32BlockNum));
                        sendto(sTFTPData, (char *)pui8PacketData, ui32Len, 0,
                               (struct sockaddr *)&sAddr, i32AddrLen);

                        //
                        // Set the count of timeouts that we've waited for the
                        // ACK for this data packet.
                        //
                        ui32Count = 0;
                    }
                }
            }

            //
            // See if there is a packet waiting to be read from the TFTP data
            // port.
            //
            if((sTFTPData != INVALID_SOCKET) &&
               FD_ISSET(sTFTPData, &sDescriptors))
            {
                //
                // Read the packet from the TFTP data port.
                //
                VPRINTF(("... Reading TFTP data packet\n"));
                i32AddrLen = sizeof(sAddr);
                if(recvfrom(sTFTPData, (char *)pui8PacketData,
                            sizeof(pui8PacketData), 0, (struct sockaddr *)&sAddr,
                            &i32AddrLen) != SOCKET_ERROR)
                {
                    //
                    // See if this is an ACK.
                    //
                    VPRINTF(("... Verify TFTP packet is ACK\n"));
                    if((pui8PacketData[0] == ((TFTP_ACK >> 8) & 0xff)) &&
                       (pui8PacketData[1] == (TFTP_ACK & 0xff)) &&
                       (pui8PacketData[2] == ((ui32BlockNum >> 8) & 0xff)) &&
                       (pui8PacketData[3] == (ui32BlockNum & 0xff)))
                    {
                        //
                        // Exit if this is the ACK for the last data packet.
                        //
                        if(ui32FileLen < (ui32BlockNum * 512))
                        {
                            if(pfnCallback)
                            {
                                pfnCallback(100);
                            }
                            break;
                        }

                        //
                        // Update the completion percentage.
                        //
                        if(pfnCallback)
                        {
                            pfnCallback((ui32BlockNum * 512 * 100) / ui32FileLen);
                        }

                        //
                        // Go to the next block of data.
                        //
                        ui32BlockNum++;

                        //
                        // Generate the TFTP data packet.
                        //
                        VPRINTF(("... Building TFTP packet (Block %d)\n",
                                ui32BlockNum));
                        ui32Len = BuildTFTPDataPacket(pcFileData, ui32FileLen,
                                                    pui8PacketData, ui32BlockNum);

                        //
                        // Send the TFTP data packet.
                        //
                        VPRINTF(("... Sending TFTP data packet (Block %d)\n",
                                ui32BlockNum));
                        sendto(sTFTPData, (char *)pui8PacketData, ui32Len, 0,
                               (struct sockaddr *)&sAddr, i32AddrLen);

                        //
                        // Set the count of timeouts that we've waited for the
                        // ACK for this data packet.
                        //
                        ui32Count = 0;
                    }
                }
            }
        }
        else
        {
            //
            // Increment the count of timeouts that we've waited for an ACK.
            //
            ui32Count++;

            //
            // See if there is a TFTP data socket and the timeout count has
            // exceeded 1 (i.e. that we've waited for a second for the ACK).
            //
            if((sTFTPData != INVALID_SOCKET) && (ui32Count > 1))
            {
                //
                // Generate a TFTP data packet for the most recently sent
                // block.
                //
                VPRINTF(("... Rebuilding TFTP data packet (Block %d)\n",
                        ui32BlockNum));
                ui32Len = BuildTFTPDataPacket(pcFileData, ui32FileLen,
                                            pui8PacketData, ui32BlockNum);

                //
                // Resend the most recent TFTP data packet.
                //
                VPRINTF(("Resending TFTP data packet (Block %d)\n",
                        ui32BlockNum));
                sendto(sTFTPData, (char *)pui8PacketData, ui32Len, 0,
                       (struct sockaddr *)&sAddr, i32AddrLen);

                //
                // Set the count of timeouts that we've waited for the ACK for
                // this data packet.
                //
                ui32Count = 0;
            }

            //
            // If we have not seen a BOOTP request yet, send the firmare
            // update magic packet again.
            //
            if(!bBOOTPPacketSeen)
            {
                VPRINTF(("... Resending \"Magic\" packet.\n"));
                SendFirmwareUpdateMagicPacket(sUpdateSocket, pui8MACAddr);
            }
        }
    }

    //
    // Free the buffer used to hold the file contents.
    //
    free(pcFileData);

    //
    // Close the sockets.
    //
    VPRINTF(("Closing network connections\n"));
    closesocket(sTFTPData);
    closesocket(sTFTP);
    closesocket(sBOOTP);
    closesocket(sUpdateSocket);

    //
    // Return success.
    //
    return(ERROR_NONE);
}

//*****************************************************************************
//
// Abort an in-progress BOOTP update.
//
//*****************************************************************************
void
AbortBOOTPUpdate(void)
{
    //
    // Set the flag to tell the BOOTP/TFTP servers to exit.
    //
    g_bAbortBOOTP = 1;
}


text:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

///¹¦ÄÜ£º×Ô¶¨ÒådatagridviewÖеÄcolÀà±ð£¬Ö÷ÒªÓÃÓÚ½ø¶ÈÏÔʾ
namespace V5_WinControls.DataGrid {
    public class DataGridViewProgressBarColumn : DataGridViewTextBoxColumn {

        public DataGridViewProgressBarColumn() {
            this.CellTemplate = new DataGridViewProgressBarCell();
        }

        public override DataGridViewCell CellTemplate {
            get { return base.CellTemplate; }

            set {
                if (!(value is DataGridViewProgressBarCell)) {
                    throw new InvalidCastException("DataGridViewProgressBarCell ´íÎó");
                }
                base.CellTemplate = value;
            }

        }

        public int Maximum {
            get {
                return ((DataGridViewProgressBarCell)this.CellTemplate).Maximum;
            }
            set {
                if (this.Maximum == value)
                    return;
                ((DataGridViewProgressBarCell)this.CellTemplate).Maximum = value;

                if (this.DataGridView == null)
                    return;

                int rowCount = this.DataGridView.RowCount;

                for (int i = 0; i < rowCount; i++) {
                    DataGridViewRow r = this.DataGridView.Rows.SharedRow(i);

                    ((DataGridViewProgressBarCell)r.Cells[this.Index]).Maximum = value;

                }
            }
        }

        public int Mimimum {
            get {
                return ((DataGridViewProgressBarCell)this.CellTemplate).Mimimum;
            }

            set {
                if (this.Mimimum == value)

                    return;
                ((DataGridViewProgressBarCell)this.CellTemplate).Mimimum = value;

                if (this.DataGridView == null)
                    return;

                int rowCount = this.DataGridView.RowCount;

                for (int i = 0; i < rowCount; i++) {

                    DataGridViewRow r = this.DataGridView.Rows.SharedRow(i);

                    ((DataGridViewProgressBarCell)r.Cells[this.Index]).Mimimum = value;

                }

            }

        }

    }

    public class DataGridViewProgressBarCell : DataGridViewTextBoxCell {

        public DataGridViewProgressBarCell() {
            this.maximumValue = 100;
            this.mimimumValue = 0;
        }

        private int maximumValue;
        public int Maximum {
            get { return this.maximumValue; }
            set { this.maximumValue = value; }
        }

        private int mimimumValue;
        public int Mimimum {
            get { return this.mimimumValue; }
            set { this.mimimumValue = value; }
        }

        public override Type ValueType {
            get { return typeof(int); }
        }

        public override object DefaultNewRowValue {
            get { return 0; }
        }

        public override object Clone() {
            DataGridViewProgressBarCell cell = (DataGridViewProgressBarCell)base.Clone();
            cell.Maximum = this.Maximum;
            cell.Mimimum = this.Mimimum;
            return cell;

        }

        protected override void Paint(Graphics graphics,
            Rectangle clipBounds, Rectangle cellBounds,
            int rowIndex, DataGridViewElementStates cellState,
            object value, object formattedValue, string errorText,
            DataGridViewCellStyle cellStyle,
            DataGridViewAdvancedBorderStyle advancedBorderStyle,
            DataGridViewPaintParts paintParts) {
            int intValue = 0;
            if (value is int)
                intValue = (int)value;

            if (intValue < this.mimimumValue)
                intValue = this.mimimumValue;

            if (intValue > this.maximumValue)
                intValue = this.maximumValue;

            double rate = (double)(intValue - this.mimimumValue) / (this.maximumValue - this.mimimumValue);

            if ((paintParts & DataGridViewPaintParts.Border) == DataGridViewPaintParts.Border) {
                this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);
            }

            Rectangle borderRect = this.BorderWidths(advancedBorderStyle);
            Rectangle paintRect = new Rectangle(cellBounds.Left + borderRect.Left, cellBounds.Top + borderRect.Top,
                cellBounds.Width - borderRect.Right, cellBounds.Height - borderRect.Bottom);

            bool isSelected = (cellState & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected;

            Color bkColor;

            if (isSelected && (paintParts & DataGridViewPaintParts.SelectionBackground) == DataGridViewPaintParts.SelectionBackground) {
                bkColor = cellStyle.SelectionBackColor;
            }
            else {
                bkColor = cellStyle.BackColor;
            }

            if ((paintParts & DataGridViewPaintParts.Background) == DataGridViewPaintParts.Background) {
                using (SolidBrush backBrush = new SolidBrush(bkColor)) {
                    graphics.FillRectangle(backBrush, paintRect);
                }
            }

            paintRect.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top);
            paintRect.Width -= cellStyle.Padding.Horizontal;
            paintRect.Height -= cellStyle.Padding.Vertical;

            if ((paintParts & DataGridViewPaintParts.ContentForeground) == DataGridViewPaintParts.ContentForeground) {
                if (ProgressBarRenderer.IsSupported) {
                    ProgressBarRenderer.DrawHorizontalBar(graphics, paintRect);
                    Rectangle barBounds = new Rectangle(paintRect.Left + 3, paintRect.Top + 1, paintRect.Width - 4, paintRect.Height - 2);

                    barBounds.Width = (int)Math.Round(barBounds.Width * rate);
                    ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds);
                }

                else {
                    graphics.FillRectangle(Brushes.White, paintRect);
                    graphics.DrawRectangle(Pens.DarkGray, paintRect);

                    Rectangle barBounds = new Rectangle(paintRect.Left + 1, paintRect.Top + 2, paintRect.Width - 1, paintRect.Height - 4);

                    barBounds.Width = (int)Math.Round(barBounds.Width * rate);
                    graphics.FillRectangle(Brushes.YellowGreen, barBounds);
                }
            }

            if (this.DataGridView.CurrentCellAddress.X == this.ColumnIndex && this.DataGridView.CurrentCellAddress.Y == this.RowIndex &&
                (paintParts & DataGridViewPaintParts.Focus) == DataGridViewPaintParts.Focus && this.DataGridView.Focused) {
                Rectangle focusRect = paintRect;
                focusRect.Inflate(-3, -3);
                ControlPaint.DrawFocusRectangle(graphics, focusRect);
            }

            if ((paintParts & DataGridViewPaintParts.ContentForeground) == DataGridViewPaintParts.ContentForeground) {
                string txt = string.Format("{0}%", Math.Round(rate * 100));
                TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter;

                Color fColor = cellStyle.ForeColor;
                paintRect.Inflate(-2, -2);
                TextRenderer.DrawText(graphics, txt, cellStyle.Font,
                    paintRect, fColor, flags);

            }

            if ((paintParts & DataGridViewPaintParts.ErrorIcon) == DataGridViewPaintParts.ErrorIcon &&
                this.DataGridView.ShowCellErrors && !string.IsNullOrEmpty(errorText)) {
                Rectangle iconBounds = this.GetErrorIconBounds(graphics, cellStyle, rowIndex);
                iconBounds.Offset(cellBounds.X, cellBounds.Y);
                this.PaintErrorIcon(graphics, iconBounds, cellBounds, errorText);

            }

        }

    }
}

redpajama_set_name: RedPajamaGithub


text:
$( document ).ready(function()
{
    page_module.buttons_insert();
	page_module.createTable();
	firebase.database().ref("Names").once('value',function(snapshot)
	{
		snapshot.forEach(function(childSnapshot)
		{
			let obj = new Object();
			obj.id = childSnapshot.key;
			obj.nick = childSnapshot.val();
			page_module.users.push(obj);
		});
	}).then(page_module.db_rendering);
	//db_rendering();

});

Date.prototype.toDateInputValue = (function() { // fixes fixes date to minute compared to local, meaning year, month,day,hour,minute only (data)
    var local = new Date(this);
    local.setMinutes(this.getMinutes() - this.getTimezoneOffset());
    return local.toJSON().slice(0,10);
});

var page_module = (function ()
{
	let users = [];
	const createTable = function()
	{
		let table = document.createElement("table");
		table.id = "table";
		table.style.width = "100%";
		let div = document.createElement("div");
		div.id = "table_div";
		div.className = "table_div" ;
		document.body.appendChild(div);
		div.appendChild(table);
		let row = table.insertRow(0);
		row.id = "row0";
		let cell1 = row.insertCell(0);
		let cell2 = row.insertCell(1);
		let cell3 = row.insertCell(2);
		let cell4 = row.insertCell(3);
		let cell5 = row.insertCell(4);
		let cell6 = row.insertCell(5);
		let cell7 = row.insertCell(6);
		let cell8 = row.insertCell(7);
		let cell9 = row.insertCell(8);
		let cell10 = row.insertCell(9);
    let cell11 = row.insertCell(10);
		cell1.innerHTML = "Event name";
    cell2.innerHTML = "Event's location";
		cell3.innerHTML = "Status";
		cell4.innerHTML = "By";
		cell5.innerHTML = "Start Date";
		cell6.innerHTML = "Start time";
		cell7.innerHTML = "End Date";
		cell8.innerHTML = "End time";
		cell9.innerHTML = "URL";
		cell10.innerHTML = "update button";
		cell11.innerHTML = "Delete button";
		let formdiv = document.createElement("div");
		formdiv.className = "new_date_form";
		formdiv.id = "new_date_form";
		document.body.appendChild(formdiv);
	};

	const db_rendering = function()
	{
		let i = 1;
		let table = document.getElementById("table");
		let is_admin = 0;
		let admin_req = firebase.database();
		admin_req = admin_req.ref("admin");
		admin_req.once('value').then(function(snapshot) // verifies user is admin
		{
			if(firebase.auth().currentUser.email == snapshot.val() + "@gmail.com" ) // adds admin only buttons
			{
				is_admin=1;

				let manage_users_btn = document.createElement("button");
				manage_users_btn.type = "button";
				manage_users_btn.className = "manage_users_btn";
				manage_users_btn.innerHTML = "Manage users";
				manage_users_btn.addEventListener("click",function()
				{
					window.location = "../manage_users/manage_users.html";
				});
				document.getElementById("top_buttons_div").appendChild(manage_users_btn);
			}
		});
		let database = firebase.database();
		let leadsRef = database.ref('Events');

		leadsRef.once('value').then(function(snapshot)  // scans event database
		{
			snapshot.forEach(function(childSnapshot)  // renders event
			{
				if(is_admin == 1 || childSnapshot.val().id == firebase.auth().currentUser.email.substring(0,firebase.auth().currentUser.email.indexOf("@")))
				{	 // checks that user is admin (view all events possiblity) or user is event author before displaying on table
					let row = table.insertRow(i);
					let cell1 = row.insertCell(0);
					let cell2 = row.insertCell(1);
					let cell3 = row.insertCell(2);
					let cell4 = row.insertCell(3);
					let cell5 = row.insertCell(4);
					let cell6 = row.insertCell(5);
					let cell7 = row.insertCell(6);
					let cell8 = row.insertCell(7);
					let cell9 = row.insertCell(8);
					let cell10 = row.insertCell(9);
          let cell11 = row.insertCell(10);
					cell1.innerHTML = childSnapshot.val().name;
          let location = document.createElement("INPUT");
          location.setAttribute("type","input");
          //location.id = "location";
          //location.className = "location";
          location.value = childSnapshot.val().location;
          cell2.appendChild(location);

					if(childSnapshot.val().approve == 1) // displaying approve status
					{
						let txt = "Approved";
						cell3.innerHTML = txt.fontcolor('green');
					}
					else
					{
						let txt = "Pending";
            if(is_admin == 1)
            {
              let approve_btn = document.createElement('input'); // admin can "approve" pages, so he gets an approve button
							approve_btn.type = "button";
							approve_btn.style.backgroundColor = "orange";
							//approve_btn.setAttribute("onClick","approve("+ '"' + childSnapshot.key+ '"'+"," + i +");"); // approve button linking
              approve_btn.onclick = function()
              {
                let obj = childSnapshot.val();
                obj.approve = 1;
                firebase.database().ref("Events/" + childSnapshot.key).set(obj);
                while (cell3.hasChildNodes())
                {
                    cell3.removeChild(cell3.lastChild);
                }
                let txt2 = "Approved";
                cell3.innerHTML = txt2.fontcolor("green");

              };
              approve_btn.value = "Approve";
              cell3.appendChild(approve_btn);

            }
            else
            {
              cell3.innerHTML = txt.fontcolor('orange');
            }

					}
					users.forEach(function(val) // nickname
					{
						if(val.id == childSnapshot.val().id)
						{
							cell4.innerHTML = val.nick;
						}

					});
					let s = new Date(childSnapshot.val().start_time); // grabs the start time on Date format
					let e = new Date(childSnapshot.val().end_time); // grabs the end time on Date format
					let start_date = document.createElement("input");
					start_date.required = "true";
					start_date.setAttribute("type","date");
					let date_str_1 = s.getFullYear() + "-";
					if(s.getMonth() >= 9) // renders the month to be two digit
					{
						let month = 1 + s.getMonth();
						date_str_1 += month + "-";
					}
					else
					{
						let month = 1 + s.getMonth();
						date_str_1 += "0" + month + "-";
					}
					if(s.getDate() >= 9) // renders the day to be two digit
					{
						let date = s.getDate() + 1
						date_str_1 += date;
					}
					else
					{
						let date = s.getDate() + 1
						date_str_1 += "0" + date;
					}
					start_date.value = date_str_1;
					cell5.appendChild(start_date);

					let start_time = document.createElement("input"); // start time input field
					start_time.required = "true";
					start_time.setAttribute("type","time");
					let time_str_1 = "";
					if(s.getHours() < 10)
						time_str_1 += "0" + s.getHours()+ ":";
					else
						time_str_1 += s.getHours()+ ":";
					if(s.getMinutes() < 10)
						time_str_1 += "0" + s.getMinutes();
					else
						time_str_1 += s.getMinutes();
					start_time.value = time_str_1;
					cell6.appendChild(start_time);

					let end_date = document.createElement("input"); // end time input field
					end_date.required = "true";
					end_date.setAttribute("type","date");
					date_str_1 = s.getFullYear() + "-";
					if(e.getMonth() >= 9)
					{
						let month = 1 + e.getMonth();
						date_str_1 += month + "-";
					}
					else
					{
						let month = 1 + e.getMonth();
						date_str_1 += "0" + month + "-";
					}
					if(e.getDate() >= 9)
					{
						let date = e.getDate() + 1
						date_str_1 += date;
					}
					else
					{
						let date = e.getDate() + 1
						date_str_1 += "0" + date;
					}
					end_date.value = date_str_1;
					cell7.appendChild(end_date);

					let end_time = document.createElement("input");
					end_time.required = "true";
					end_time.setAttribute("type","time");
					time_str_1 = "";
					if(e.getHours() < 10)
						time_str_1 += "0" + e.getHours()+ ":";
					else
						time_str_1 += e.getHours()+ ":";
					if(e.getMinutes() < 10)
						time_str_1 += "0" + e.getMinutes();
					else
						time_str_1 += e.getMinutes();
					end_time.value = time_str_1;
					cell8.appendChild(end_time);

					let url = document.createElement("INPUT"); // appends URL
					url.setAttribute("type", "input");
					url.value = childSnapshot.val().url;
					cell9.appendChild(url);

					let update_btn = document.createElement("button"); // updates the entire data from the row!
					update_btn.type = "button";
					update_btn.innerHTML = "Update";
					update_btn.addEventListener("click",function()
					{
						let start_date_val = start_date.value;
						let end_date_val = end_date.value;
						let start_time_val = start_time.value;
						let end_time_val = end_time.value
						let events_name_val = cell1.innerHTML;
						let url_val = url.value;
            let location_val = location.value;
						if(start_date_val.length == 0 || end_date_val.length == 0 || start_time_val.length == 0 || end_time_val.length == 0 || events_name_val.length == 0 || location_val.length == 0)
							return false;
						let year_start = start_date_val.substring(0,start_date_val.indexOf("-"));
						let second_part1 = start_date_val.substring(start_date_val.indexOf("-")+1,start_date_val.length);
						let month_start = second_part1.substring(0,second_part1.indexOf("-"));
						let day_start = second_part1.substring(second_part1.indexOf("-")+1,second_part1.length);
						let hour_start = start_time_val.substring(0,start_time_val.indexOf(":"));
						let min_start = start_time_val.substring(start_time_val.indexOf(":")+1,start_time_val.length);

						let year_end = end_date_val.substring(0,end_date_val.indexOf("-"));
						let second_part2 = end_date_val.substring(end_date_val.indexOf("-")+1,end_date_val.length);
						let month_end = second_part2.substring(0,second_part2.indexOf("-"));
						let day_end = second_part2.substring(second_part2.indexOf("-")+1,second_part1.length);
						let hour_end = end_time_val.substring(0,end_time_val.indexOf(":"));
						let min_end = end_time_val.substring(end_time_val.indexOf(":")+1,end_time_val.length);

						let s = new Date(year_start,month_start,day_start,hour_start,min_start,0,0);// start date on Date format
						let e = new Date(year_end,month_end,day_end,hour_end,min_end,0,0); // end date on Date format
						s.setMonth(month_start-1);
						e.setMonth(month_end-1);

						if(s.valueOf() - e.valueOf() > 0)
						{

							alert("Start time can't be after end time");
							return false;
						}

						let obj = new Object();
						obj.start_time = s.valueOf();
						obj.end_time = e.valueOf();
						obj.name = events_name_val;
						obj.url = url_val;
						obj.id = childSnapshot.val().id;
						obj.approve = childSnapshot.val().approve;
            obj.location = location_val;
						firebase.database().ref("Events/" + childSnapshot.key).set(obj);

						alert("successfull");
						return false;
					});
					cell10.appendChild(update_btn);
					let delete_button = document.createElement("button");
					delete_button.type = "button";
					delete_button.innerHTML = "Delete";
					delete_button.addEventListener("click",function()
					{
						firebase.database().ref("Events/" + childSnapshot.key).remove();
						table.deleteRow(row.rowIndex);
					});
					cell11.appendChild(delete_button);

					i++;
				}
			});
		});

		const add_new_event_ui = function()
		{

			let div = document.getElementById("new_date_form");

			let form_obj = document.createElement("FORM");
			form_obj.id = "form";
			form_obj.autocomplete = "false"; // turns on auto complete on form
			form_obj.acceptCharset = "UTF-8"; // utilizes english-only with special characters incl @

			div.appendChild(form_obj);

			let event_name = document.createElement("INPUT");
			event_name.setAttribute("type", "input");
			event_name.required = "true";
			event_name.autocomplete = "false";
			event_name.form = form_obj;
			event_name.id = "name";
			event_name.className = "name";

			div.appendChild(document.createTextNode("Event's name: "));
			div.appendChild(event_name);

      let location = document.createElement("INPUT");
      location.setAttribute("type","input");
      location.required = "true";
      location.autocomplete = "false";
      location.form = form_obj;
      location.id = "location";
      location.className = "location";

      div.appendChild(document.createElement("br"));
      div.appendChild(document.createTextNode("Event's location: "));
      div.appendChild(location);

			div.appendChild(document.createElement("br"));
			users.forEach(function(val) // to get user nickname
			{
				if(val.id == firebase.auth().currentUser.email.substring(0,firebase.auth().currentUser.email.indexOf("@")))
				{
					let txt = document.createTextNode("By :" + val.nick);
					div.appendChild(txt);
				}
			});

			div.appendChild(document.createElement("br"));

			div.appendChild(document.createTextNode("Start date: "));
			let start_date = document.createElement("input");
			start_date.required = "true";
			start_date.setAttribute("type","date");
			start_date.id = "start_date";

			div.appendChild(start_date);

			div.appendChild(document.createElement("br"));
			div.appendChild(document.createTextNode("Start time: "));
			let start = document.createElement("INPUT");
			start.setAttribute("type", "time");
			start.id = "start";
			start.required = "true";
			start.form = form_obj;
			div.appendChild(start);

			div.appendChild(document.createElement("br"));
			div.appendChild(document.createTextNode("End date: "));
			let end_date = document.createElement("input");
			end_date.required = "true";
			end_date.setAttribute("type","date");
			end_date.id = "end_date";

			div.appendChild(end_date);

			div.appendChild(document.createElement("br"));
			div.appendChild(document.createTextNode("End time: "));
			let end = document.createElement("INPUT");
			end.setAttribute("type", "time");
			end.id = "end";
			end.required = "true";
			end.form = form_obj;
			div.appendChild(end);

			div.appendChild(document.createElement("br"));

			let url = document.createElement("INPUT");
			url.setAttribute("type", "input");
			url.required = "true";
			url.autocomplete = "false";
			url.form = form_obj;
			url.id = "url";
			url.className = "url";
			div.appendChild(document.createTextNode("URL (optional): "));
			div.appendChild(url);

			const add_event = function()
			{
				let start_date_val = start_date.value;
				let end_date_val = end_date.value;
				let start_time_val = start.value;
				let end_time_val = end.value
				let events_name_val = event_name.value;
				let url_val = url.value;
        let location_val = location.value;
				if(start_date_val.length == 0 || end_date_val.length == 0 || start_time_val.length == 0 || end_time_val.length == 0 || events_name_val.length == 0 || location_val.length == 0)
					return false;
				let year_start = start_date_val.substring(0,start_date_val.indexOf("-"));
				let second_part1 = start_date_val.substring(start_date_val.indexOf("-")+1,start_date_val.length);
				let month_start = second_part1.substring(0,second_part1.indexOf("-"));
				let day_start = second_part1.substring(second_part1.indexOf("-")+1,second_part1.length);
				let hour_start = start_time_val.substring(0,start_time_val.indexOf(":"));
				let min_start = start_time_val.substring(start_time_val.indexOf(":")+1,start_time_val.length);

				let year_end = end_date_val.substring(0,end_date_val.indexOf("-"));
				let second_part2 = end_date_val.substring(end_date_val.indexOf("-")+1,end_date_val.length);
				let month_end = second_part2.substring(0,second_part2.indexOf("-"));
				let day_end = second_part2.substring(second_part2.indexOf("-")+1,second_part1.length);
				let hour_end = end_time_val.substring(0,end_time_val.indexOf(":"));
				let min_end = end_time_val.substring(end_time_val.indexOf(":")+1,end_time_val.length);

				let s = new Date(year_start,month_start,day_start,hour_start,min_start,0,0);
				let e = new Date(year_end,month_end,day_end,hour_end,min_end,0,0);
				s.setMonth(month_start-1);
				e.setMonth(month_end-1);

				if(s.valueOf() - e.valueOf() > 0)
				{

					alert("Start time can't be after end time");
					return false;
				}

				let obj = new Object();
				obj.start_time = s.valueOf();
				obj.end_time = e.valueOf();
				obj.name = events_name_val;
				obj.url = url_val;
        obj.location = location_val;
				obj.id = firebase.auth().currentUser.email.substring(0,firebase.auth().currentUser.email.indexOf("@"));
				firebase.database().ref("Auto_approve").once('value',function(snapshot)
				{
					snapshot.forEach(function(childSnapshot)
					{
						if(childSnapshot.key == firebase.auth().currentUser.email.substring(0,firebase.auth().currentUser.email.indexOf("@")))
						{
							obj.approve = childSnapshot.val();
							firebase.database().ref("Events").push(obj);
						}
					});
				});

				alert("successfull, refreshing");
				window.location.reload();
				return false;
			};

			div.appendChild(document.createElement("br"));
			let btn = document.createElement("button");
			btn.form = form_obj;
			btn.formNoValidate = false; // validate data
			btn.type = "submit";
			btn.name = "submit";
			btn.className = "Submit_button";
			btn.innerHTML = "Add new";
			btn.onclick = add_event;
			div.appendChild(btn);

		};

		add_new_event_ui();
	};

	const buttons_insert = function()
	{
		let div = document.createElement("div");
		div.id = "top_buttons_div";
		div.className = "top_buttons_div";

		let link = document.createElement("a");
		//var txt= document.createTextNode("back to calendar");
		let backpic = document.createElement("IMG");
		backpic.src = "../buttons/back.png";
		backpic.height = 40;
		backpic.width = 40;
		link.appendChild(backpic);
		link.href = "../index.html";
		div.appendChild(link);

		let link2 = document.createElement("a");
		let dbpic = document.createElement("IMG");
		dbpic.src = "../buttons/facebook.png";
		dbpic.height = 40;
		dbpic.width = 40;
		link2.appendChild(dbpic);
		link2.href = "../admin_page/admin.html";
		div.appendChild(link2);

		let btn = document.createElement("button");
		btn.type = "button";
		btn.name = "log out";
		let log_out_pic = document.createElement("IMG");
		log_out_pic.src = "../buttons/log_out.png";
		log_out_pic.height = 40;
		log_out_pic.width = 40;
		btn.appendChild(log_out_pic);
		btn.addEventListener("click", function() { firebase.auth().signOut(); window.location = "../index.html"; });
		div.appendChild(btn);

		document.body.appendChild(div);
	};
	return {buttons_insert,createTable,db_rendering,users,};

}());


text:
<?xml version="1.0" encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
                            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
	<class name="org.mifos.application.accounts.financial.business.COAHierarchyEntity" table="COAHIERARCHY">
		<id name="accountId" column="COA_ID" access="field">
			<generator class="foreign">
				<param name="property">coa</param>
			</generator>
		</id>

		<one-to-one name="coa" class="org.mifos.application.accounts.financial.business.COABO"
			fetch="join" access="field" />
		<many-to-one name="parentAccount" column="PARENT_COAID"
			class="org.mifos.application.accounts.financial.business.COAHierarchyEntity"
			fetch="join" cascade="none" unique="true" access="field" />

	</class>
</hibernate-mapping>