/**
  ******************************************************************************
  * @file    stm32f4xx_ll_fsmc.h
  * @author  MCD Application Team
  * @version V1.7.0
  * @date    17-February-2017
  * @brief   Header file of FSMC HAL module.
  ******************************************************************************
  * @attention
  *
  *
© COPYRIGHT(c) 2017 STMicroelectronics

  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_LL_FSMC_H
#define __STM32F4xx_LL_FSMC_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal_def.h"

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */

/** @addtogroup FSMC_LL
  * @{
  */

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F412Zx) ||\
    defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F413xx) || defined(STM32F423xx)
/* Private types -------------------------------------------------------------*/
/** @defgroup FSMC_LL_Private_Types FSMC Private Types
  * @{
  */

/**
  * @brief FSMC NORSRAM Configuration Structure definition
  */
typedef struct
{
  uint32_t NSBank;                       /*!< Specifies the NORSRAM memory device that will be used.
                                              This parameter can be a value of @ref FSMC_NORSRAM_Bank                     */

  uint32_t DataAddressMux;               /*!< Specifies whether the address and data values are
                                              multiplexed on the data bus or not.
                                              This parameter can be a value of @ref FSMC_Data_Address_Bus_Multiplexing    */

  uint32_t MemoryType;                   /*!< Specifies the type of external memory attached to
                                              the corresponding memory device.
                                              This parameter can be a value of @ref FSMC_Memory_Type                      */

  uint32_t MemoryDataWidth;              /*!< Specifies the external memory device width.
                                              This parameter can be a value of @ref FSMC_NORSRAM_Data_Width               */

  uint32_t BurstAccessMode;              /*!< Enables or disables the burst access mode for Flash memory,
                                              valid only with synchronous burst Flash memories.
                                              This parameter can be a value of @ref FSMC_Burst_Access_Mode                */

  uint32_t WaitSignalPolarity;           /*!< Specifies the wait signal polarity, valid only when accessing
                                              the Flash memory in burst mode.
                                              This parameter can be a value of @ref FSMC_Wait_Signal_Polarity             */

  uint32_t WrapMode;                     /*!< Enables or disables the Wrapped burst access mode for Flash
                                              memory, valid only when accessing Flash memories in burst mode.
                                              This parameter can be a value of @ref FSMC_Wrap_Mode
                                              This mode is available only for the STM32F405/407/4015/417xx devices        */

  uint32_t WaitSignalActive;             /*!< Specifies if the wait signal is asserted by the memory one
                                              clock cycle before the wait state or during the wait state,
                                              valid only when accessing memories in burst mode.
                                              This parameter can be a value of @ref FSMC_Wait_Timing                      */

  uint32_t WriteOperation;               /*!< Enables or disables the write operation in the selected device by the FSMC.
                                              This parameter can be a value of @ref FSMC_Write_Operation                  */

  uint32_t WaitSignal;                   /*!< Enables or disables the wait state insertion via wait
                                              signal, valid for Flash memory access in burst mode.
                                              This parameter can be a value of @ref FSMC_Wait_Signal                      */

  uint32_t ExtendedMode;                 /*!< Enables or disables the extended mode.
                                              This parameter can be a value of @ref FSMC_Extended_Mode                    */

  uint32_t AsynchronousWait;             /*!< Enables or disables wait signal during asynchronous transfers,
                                              valid only with asynchronous Flash memories.
                                              This parameter can be a value of @ref FSMC_AsynchronousWait                 */

  uint32_t WriteBurst;                   /*!< Enables or disables the write burst operation.
                                              This parameter can be a value of @ref FSMC_Write_Burst                      */

  uint32_t ContinuousClock;              /*!< Enables or disables the FMC clock output to external memory devices.
                                              This parameter is only enabled through the FMC_BCR1 register, and don't care
                                              through FMC_BCR2..4 registers.
                                              This parameter can be a value of @ref FMC_Continous_Clock
                                              This mode is available only for the STM32F412Vx/Zx/Rx devices                 */

  uint32_t WriteFifo;                    /*!< Enables or disables the write FIFO used by the FMC controller.
                                              This parameter is only enabled through the FMC_BCR1 register, and don't care
                                              through FMC_BCR2..4 registers.
                                              This parameter can be a value of @ref FMC_Write_FIFO
                                              This mode is available only for the STM32F412Vx/Vx devices                    */

  uint32_t PageSize;                     /*!< Specifies the memory page size.
                                              This parameter can be a value of @ref FMC_Page_Size                   */
}FSMC_NORSRAM_InitTypeDef;

/**
  * @brief FSMC NORSRAM Timing parameters structure definition
  */
typedef struct
{
  uint32_t AddressSetupTime;             /*!< Defines the number of HCLK cycles to configure
                                              the duration of the address setup time.
                                              This parameter can be a value between Min_Data = 0 and Max_Data = 15.
                                              @note This parameter is not used with synchronous NOR Flash memories.      */

  uint32_t AddressHoldTime;              /*!< Defines the number of HCLK cycles to configure
                                              the duration of the address hold time.
                                              This parameter can be a value between Min_Data = 1 and Max_Data = 15.
                                              @note This parameter is not used with synchronous NOR Flash memories.      */

  uint32_t DataSetupTime;                /*!< Defines the number of HCLK cycles to configure
                                              the duration of the data setup time.
                                              This parameter can be a value between Min_Data = 1 and Max_Data = 255.
                                              @note This parameter is used for SRAMs, ROMs and asynchronous multiplexed
                                              NOR Flash memories.                                                        */

  uint32_t BusTurnAroundDuration;        /*!< Defines the number of HCLK cycles to configure
                                              the duration of the bus turnaround.
                                              This parameter can be a value between Min_Data = 0 and Max_Data = 15.
                                              @note This parameter is only used for multiplexed NOR Flash memories.      */

  uint32_t CLKDivision;                  /*!< Defines the period of CLK clock output signal, expressed in number of
                                              HCLK cycles. This parameter can be a value between Min_Data = 2 and Max_Data = 16.
                                              @note This parameter is not used for asynchronous NOR Flash, SRAM or ROM
                                              accesses.                                                                  */

  uint32_t DataLatency;                  /*!< Defines the number of memory clock cycles to issue
                                              to the memory before getting the first data.
                                              The parameter value depends on the memory type as shown below:
                                              - It must be set to 0 in case of a CRAM
                                              - It is don't care in asynchronous NOR, SRAM or ROM accesses
                                              - It may assume a value between Min_Data = 2 and Max_Data = 17 in NOR Flash memories
                                                with synchronous burst mode enable                                       */

  uint32_t AccessMode;                   /*!< Specifies the asynchronous access mode.
                                              This parameter can be a value of @ref FSMC_Access_Mode                      */

}FSMC_NORSRAM_TimingTypeDef;

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
/**
  * @brief FSMC NAND Configuration Structure definition
  */
typedef struct
{
  uint32_t NandBank;               /*!< Specifies the NAND memory device that will be used.
                                        This parameter can be a value of @ref FSMC_NAND_Bank                   */

  uint32_t Waitfeature;            /*!< Enables or disables the Wait feature for the NAND Memory device.
                                        This parameter can be any value of @ref FSMC_Wait_feature              */

  uint32_t MemoryDataWidth;        /*!< Specifies the external memory device width.
                                        This parameter can be any value of @ref FSMC_NAND_Data_Width           */

  uint32_t EccComputation;         /*!< Enables or disables the ECC computation.
                                        This parameter can be any value of @ref FSMC_ECC                       */

  uint32_t ECCPageSize;            /*!< Defines the page size for the extended ECC.
                                        This parameter can be any value of @ref FSMC_ECC_Page_Size             */

  uint32_t TCLRSetupTime;          /*!< Defines the number of HCLK cycles to configure the
                                        delay between CLE low and RE low.
                                        This parameter can be a value between Min_Data = 0 and Max_Data = 255  */

  uint32_t TARSetupTime;           /*!< Defines the number of HCLK cycles to configure the
                                        delay between ALE low and RE low.
                                        This parameter can be a number between Min_Data = 0 and Max_Data = 255 */

}FSMC_NAND_InitTypeDef;

/**
  * @brief FSMC NAND/PCCARD Timing parameters structure definition
  */
typedef struct
{
  uint32_t SetupTime;            /*!< Defines the number of HCLK cycles to setup address before
                                      the command assertion for NAND-Flash read or write access
                                      to common/Attribute or I/O memory space (depending on
                                      the memory space timing to be configured).
                                      This parameter can be a value between Min_Data = 0 and Max_Data = 255    */

  uint32_t WaitSetupTime;        /*!< Defines the minimum number of HCLK cycles to assert the
                                      command for NAND-Flash read or write access to
                                      common/Attribute or I/O memory space (depending on the
                                      memory space timing to be configured).
                                      This parameter can be a number between Min_Data = 0 and Max_Data = 255   */

  uint32_t HoldSetupTime;        /*!< Defines the number of HCLK clock cycles to hold address
                                      (and data for write access) after the command de-assertion
                                      for NAND-Flash read or write access to common/Attribute
                                      or I/O memory space (depending on the memory space timing
                                      to be configured).
                                      This parameter can be a number between Min_Data = 0 and Max_Data = 255   */

  uint32_t HiZSetupTime;         /*!< Defines the number of HCLK clock cycles during which the
                                      data bus is kept in HiZ after the start of a NAND-Flash
                                      write access to common/Attribute or I/O memory space (depending
                                      on the memory space timing to be configured).
                                      This parameter can be a number between Min_Data = 0 and Max_Data = 255   */

}FSMC_NAND_PCC_TimingTypeDef;

/**
  * @brief  FSMC NAND Configuration Structure definition
  */
typedef struct
{
  uint32_t Waitfeature;            /*!< Enables or disables the Wait feature for the PCCARD Memory device.
                                        This parameter can be any value of @ref FSMC_Wait_feature              */

  uint32_t TCLRSetupTime;          /*!< Defines the number of HCLK cycles to configure the
                                        delay between CLE low and RE low.
                                        This parameter can be a value between Min_Data = 0 and Max_Data = 255  */

  uint32_t TARSetupTime;           /*!< Defines the number of HCLK cycles to configure the
                                        delay between ALE low and RE low.
                                        This parameter can be a number between Min_Data = 0 and Max_Data = 255 */

}FSMC_PCCARD_InitTypeDef;
/**
  * @}
  */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

/* Private constants ---------------------------------------------------------*/
/** @defgroup FSMC_LL_Private_Constants FSMC Private Constants
  * @{
  */

/** @defgroup FSMC_LL_NOR_SRAM_Controller FSMC NOR/SRAM Controller
  * @{
  */
/** @defgroup FSMC_NORSRAM_Bank FSMC NOR/SRAM Bank
  * @{
  */
#define FSMC_NORSRAM_BANK1                       0x00000000U
#define FSMC_NORSRAM_BANK2                       0x00000002U
#define FSMC_NORSRAM_BANK3                       0x00000004U
#define FSMC_NORSRAM_BANK4                       0x00000006U
/**
  * @}
  */

/** @defgroup FSMC_Data_Address_Bus_Multiplexing FSMC Data Address Bus Multiplexing
  * @{
  */
#define FSMC_DATA_ADDRESS_MUX_DISABLE            0x00000000U
#define FSMC_DATA_ADDRESS_MUX_ENABLE             0x00000002U
/**
  * @}
  */

/** @defgroup FSMC_Memory_Type FSMC Memory Type
  * @{
  */
#define FSMC_MEMORY_TYPE_SRAM                    0x00000000U
#define FSMC_MEMORY_TYPE_PSRAM                   0x00000004U
#define FSMC_MEMORY_TYPE_NOR                     0x00000008U
/**
  * @}
  */

/** @defgroup FSMC_NORSRAM_Data_Width FSMC NOR/SRAM Data Width
  * @{
  */
#define FSMC_NORSRAM_MEM_BUS_WIDTH_8             0x00000000U
#define FSMC_NORSRAM_MEM_BUS_WIDTH_16            0x00000010U
#define FSMC_NORSRAM_MEM_BUS_WIDTH_32            0x00000020U
/**
  * @}
  */

/** @defgroup FSMC_NORSRAM_Flash_Access FSMC NOR/SRAM Flash Access
  * @{
  */
#define FSMC_NORSRAM_FLASH_ACCESS_ENABLE         0x00000040U
#define FSMC_NORSRAM_FLASH_ACCESS_DISABLE        0x00000000U
/**
  * @}
  */

/** @defgroup FSMC_Burst_Access_Mode FSMC Burst Access Mode
  * @{
  */
#define FSMC_BURST_ACCESS_MODE_DISABLE           0x00000000U
#define FSMC_BURST_ACCESS_MODE_ENABLE            0x00000100U
/**
  * @}
  */

/** @defgroup FSMC_Wait_Signal_Polarity FSMC Wait Signal Polarity
  * @{
  */
#define FSMC_WAIT_SIGNAL_POLARITY_LOW            0x00000000U
#define FSMC_WAIT_SIGNAL_POLARITY_HIGH           0x00000200U
/**
  * @}
  */

/** @defgroup FSMC_Wrap_Mode FSMC Wrap Mode
  * @note  These values are available only for the STM32F405/415/407/417xx devices.
  * @{
  */
#define FSMC_WRAP_MODE_DISABLE                   0x00000000U
#define FSMC_WRAP_MODE_ENABLE                    0x00000400U
/**
  * @}
  */

/** @defgroup FSMC_Wait_Timing FSMC Wait Timing
  * @{
  */
#define FSMC_WAIT_TIMING_BEFORE_WS               0x00000000U
#define FSMC_WAIT_TIMING_DURING_WS               0x00000800U
/**
  * @}
  */

/** @defgroup FSMC_Write_Operation FSMC Write Operation
  * @{
  */
#define FSMC_WRITE_OPERATION_DISABLE             0x00000000U
#define FSMC_WRITE_OPERATION_ENABLE              0x00001000U
/**
  * @}
  */

/** @defgroup FSMC_Wait_Signal FSMC Wait Signal
  * @{
  */
#define FSMC_WAIT_SIGNAL_DISABLE                 0x00000000U
#define FSMC_WAIT_SIGNAL_ENABLE                  0x00002000U
/**
  * @}
  */

/** @defgroup FSMC_Extended_Mode FSMC Extended Mode
  * @{
  */
#define FSMC_EXTENDED_MODE_DISABLE               0x00000000U
#define FSMC_EXTENDED_MODE_ENABLE                0x00004000U
/**
  * @}
  */

/** @defgroup FSMC_AsynchronousWait FSMC Asynchronous Wait
  * @{
  */
#define FSMC_ASYNCHRONOUS_WAIT_DISABLE           0x00000000U
#define FSMC_ASYNCHRONOUS_WAIT_ENABLE            0x00008000U
/**
  * @}
  */

/** @defgroup FSMC_Page_Size FSMC Page Size
  * @{
  */
#define FSMC_PAGE_SIZE_NONE           0x00000000U
#define FSMC_PAGE_SIZE_128            ((uint32_t)FSMC_BCR1_CPSIZE_0)
#define FSMC_PAGE_SIZE_256            ((uint32_t)FSMC_BCR1_CPSIZE_1)
#define FSMC_PAGE_SIZE_512            ((uint32_t)(FSMC_BCR1_CPSIZE_0 | FSMC_BCR1_CPSIZE_1))
#define FSMC_PAGE_SIZE_1024           ((uint32_t)FSMC_BCR1_CPSIZE_2)
/**
  * @}
  */

/** @defgroup FSMC_Write_FIFO FSMC Write FIFO
  * @note  These values are available only for the STM32F412Vx/Zx/Rx devices.
  * @{
  */
#define FSMC_WRITE_FIFO_DISABLE           ((uint32_t)FSMC_BCR1_WFDIS)
#define FSMC_WRITE_FIFO_ENABLE            0x00000000U
/**
  * @}
  */

/** @defgroup FSMC_Write_Burst FSMC Write Burst
  * @{
  */
#define FSMC_WRITE_BURST_DISABLE                 0x00000000U
#define FSMC_WRITE_BURST_ENABLE                  0x00080000U
/**
  * @}
  */

/** @defgroup FSMC_Continous_Clock FSMC Continous Clock
  * @note  These values are available only for the STM32F412Vx/Zx/Rx devices.
  * @{
  */
#define FSMC_CONTINUOUS_CLOCK_SYNC_ONLY          0x00000000U
#define FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC         0x00100000U
/**
  * @}
  */

/** @defgroup FSMC_Access_Mode FSMC Access Mode
  * @{
  */
#define FSMC_ACCESS_MODE_A                        0x00000000U
#define FSMC_ACCESS_MODE_B                        0x10000000U
#define FSMC_ACCESS_MODE_C                        0x20000000U
#define FSMC_ACCESS_MODE_D                        0x30000000U
/**
  * @}
  */
/**
  * @}
  */

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
/** @defgroup FSMC_LL_NAND_Controller FSMC NAND and PCCARD Controller
  * @{
  */
/** @defgroup FSMC_NAND_Bank FSMC NAND Bank
  * @{
  */
#define FSMC_NAND_BANK2                          0x00000010U
#define FSMC_NAND_BANK3                          0x00000100U
/**
  * @}
  */

/** @defgroup FSMC_Wait_feature FSMC Wait feature
  * @{
  */
#define FSMC_NAND_PCC_WAIT_FEATURE_DISABLE           0x00000000U
#define FSMC_NAND_PCC_WAIT_FEATURE_ENABLE            0x00000002U
/**
  * @}
  */

/** @defgroup FSMC_PCR_Memory_Type FSMC PCR Memory Type
  * @{
  */
#define FSMC_PCR_MEMORY_TYPE_PCCARD        0x00000000U
#define FSMC_PCR_MEMORY_TYPE_NAND          0x00000008U
/**
  * @}
  */

/** @defgroup FSMC_NAND_Data_Width FSMC NAND Data Width
  * @{
  */
#define FSMC_NAND_PCC_MEM_BUS_WIDTH_8                0x00000000U
#define FSMC_NAND_PCC_MEM_BUS_WIDTH_16               0x00000010U
/**
  * @}
  */

/** @defgroup FSMC_ECC FSMC ECC
  * @{
  */
#define FSMC_NAND_ECC_DISABLE                    0x00000000U
#define FSMC_NAND_ECC_ENABLE                     0x00000040U
/**
  * @}
  */

/** @defgroup FSMC_ECC_Page_Size FSMC ECC Page Size
  * @{
  */
#define FSMC_NAND_ECC_PAGE_SIZE_256BYTE          0x00000000U
#define FSMC_NAND_ECC_PAGE_SIZE_512BYTE          0x00020000U
#define FSMC_NAND_ECC_PAGE_SIZE_1024BYTE         0x00040000U
#define FSMC_NAND_ECC_PAGE_SIZE_2048BYTE         0x00060000U
#define FSMC_NAND_ECC_PAGE_SIZE_4096BYTE         0x00080000U
#define FSMC_NAND_ECC_PAGE_SIZE_8192BYTE         0x000A0000U
/**
  * @}
  */
/**
  * @}
  */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

/** @defgroup FSMC_LL_Interrupt_definition FSMC Interrupt definition
  * @{
  */
#define FSMC_IT_RISING_EDGE                0x00000008U
#define FSMC_IT_LEVEL                      0x00000010U
#define FSMC_IT_FALLING_EDGE               0x00000020U
#define FSMC_IT_REFRESH_ERROR              0x00004000U
/**
  * @}
  */

/** @defgroup FSMC_LL_Flag_definition  FSMC Flag definition
  * @{
  */
#define FSMC_FLAG_RISING_EDGE                    0x00000001U
#define FSMC_FLAG_LEVEL                          0x00000002U
#define FSMC_FLAG_FALLING_EDGE                   0x00000004U
#define FSMC_FLAG_FEMPT                          0x00000040U
/**
  * @}
  */

/** @defgroup FSMC_LL_Alias_definition  FSMC Alias definition
  * @{
  */
#define FSMC_NORSRAM_TypeDef                  FSMC_Bank1_TypeDef
#define FSMC_NORSRAM_EXTENDED_TypeDef         FSMC_Bank1E_TypeDef
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
#define FSMC_NAND_TypeDef                     FSMC_Bank2_3_TypeDef
#define FSMC_PCCARD_TypeDef                   FSMC_Bank4_TypeDef
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

#define FSMC_NORSRAM_DEVICE                   FSMC_Bank1
#define FSMC_NORSRAM_EXTENDED_DEVICE          FSMC_Bank1E
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
#define FSMC_NAND_DEVICE                      FSMC_Bank2_3
#define FSMC_PCCARD_DEVICE                    FSMC_Bank4
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

#define FMC_NORSRAM_MEM_BUS_WIDTH_8           FSMC_NORSRAM_MEM_BUS_WIDTH_8
#define FMC_NORSRAM_MEM_BUS_WIDTH_16          FSMC_NORSRAM_MEM_BUS_WIDTH_16
#define FMC_NORSRAM_MEM_BUS_WIDTH_32          FSMC_NORSRAM_MEM_BUS_WIDTH_32

#define FMC_NORSRAM_TypeDef                   FSMC_NORSRAM_TypeDef
#define FMC_NORSRAM_EXTENDED_TypeDef          FSMC_NORSRAM_EXTENDED_TypeDef
#define FMC_NORSRAM_InitTypeDef               FSMC_NORSRAM_InitTypeDef
#define FMC_NORSRAM_TimingTypeDef             FSMC_NORSRAM_TimingTypeDef

#define FMC_NORSRAM_Init                      FSMC_NORSRAM_Init
#define FMC_NORSRAM_Timing_Init               FSMC_NORSRAM_Timing_Init
#define FMC_NORSRAM_Extended_Timing_Init      FSMC_NORSRAM_Extended_Timing_Init
#define FMC_NORSRAM_DeInit                    FSMC_NORSRAM_DeInit
#define FMC_NORSRAM_WriteOperation_Enable     FSMC_NORSRAM_WriteOperation_Enable
#define FMC_NORSRAM_WriteOperation_Disable    FSMC_NORSRAM_WriteOperation_Disable

#define __FMC_NORSRAM_ENABLE                  __FSMC_NORSRAM_ENABLE
#define __FMC_NORSRAM_DISABLE                 __FSMC_NORSRAM_DISABLE

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
#define FMC_NAND_InitTypeDef                  FSMC_NAND_InitTypeDef
#define FMC_PCCARD_InitTypeDef                FSMC_PCCARD_InitTypeDef
#define FMC_NAND_PCC_TimingTypeDef            FSMC_NAND_PCC_TimingTypeDef

#define FMC_NAND_Init                         FSMC_NAND_Init
#define FMC_NAND_CommonSpace_Timing_Init      FSMC_NAND_CommonSpace_Timing_Init
#define FMC_NAND_AttributeSpace_Timing_Init   FSMC_NAND_AttributeSpace_Timing_Init
#define FMC_NAND_DeInit                       FSMC_NAND_DeInit
#define FMC_NAND_ECC_Enable                   FSMC_NAND_ECC_Enable
#define FMC_NAND_ECC_Disable                  FSMC_NAND_ECC_Disable
#define FMC_NAND_GetECC                       FSMC_NAND_GetECC
#define FMC_PCCARD_Init                       FSMC_PCCARD_Init
#define FMC_PCCARD_CommonSpace_Timing_Init    FSMC_PCCARD_CommonSpace_Timing_Init
#define FMC_PCCARD_AttributeSpace_Timing_Init FSMC_PCCARD_AttributeSpace_Timing_Init
#define FMC_PCCARD_IOSpace_Timing_Init        FSMC_PCCARD_IOSpace_Timing_Init
#define FMC_PCCARD_DeInit                     FSMC_PCCARD_DeInit

#define __FMC_NAND_ENABLE                     __FSMC_NAND_ENABLE
#define __FMC_NAND_DISABLE                    __FSMC_NAND_DISABLE
#define __FMC_PCCARD_ENABLE                   __FSMC_PCCARD_ENABLE
#define __FMC_PCCARD_DISABLE                  __FSMC_PCCARD_DISABLE
#define __FMC_NAND_ENABLE_IT                  __FSMC_NAND_ENABLE_IT
#define __FMC_NAND_DISABLE_IT                 __FSMC_NAND_DISABLE_IT
#define __FMC_NAND_GET_FLAG                   __FSMC_NAND_GET_FLAG
#define __FMC_NAND_CLEAR_FLAG                 __FSMC_NAND_CLEAR_FLAG
#define __FMC_PCCARD_ENABLE_IT                __FSMC_PCCARD_ENABLE_IT
#define __FMC_PCCARD_DISABLE_IT               __FSMC_PCCARD_DISABLE_IT
#define __FMC_PCCARD_GET_FLAG                 __FSMC_PCCARD_GET_FLAG
#define __FMC_PCCARD_CLEAR_FLAG               __FSMC_PCCARD_CLEAR_FLAG
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

#define FMC_NORSRAM_TypeDef                   FSMC_NORSRAM_TypeDef
#define FMC_NORSRAM_EXTENDED_TypeDef          FSMC_NORSRAM_EXTENDED_TypeDef
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
#define FMC_NAND_TypeDef                      FSMC_NAND_TypeDef
#define FMC_PCCARD_TypeDef                    FSMC_PCCARD_TypeDef
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

#define FMC_NORSRAM_DEVICE                    FSMC_NORSRAM_DEVICE
#define FMC_NORSRAM_EXTENDED_DEVICE           FSMC_NORSRAM_EXTENDED_DEVICE
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
#define FMC_NAND_DEVICE                       FSMC_NAND_DEVICE
#define FMC_PCCARD_DEVICE                     FSMC_PCCARD_DEVICE

#define FMC_NAND_BANK2                        FSMC_NAND_BANK2
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

#define FMC_NORSRAM_BANK1                     FSMC_NORSRAM_BANK1
#define FMC_NORSRAM_BANK2                     FSMC_NORSRAM_BANK2
#define FMC_NORSRAM_BANK3                     FSMC_NORSRAM_BANK3

#define FMC_IT_RISING_EDGE                    FSMC_IT_RISING_EDGE
#define FMC_IT_LEVEL                          FSMC_IT_LEVEL
#define FMC_IT_FALLING_EDGE                   FSMC_IT_FALLING_EDGE
#define FMC_IT_REFRESH_ERROR                  FSMC_IT_REFRESH_ERROR

#define FMC_FLAG_RISING_EDGE                  FSMC_FLAG_RISING_EDGE
#define FMC_FLAG_LEVEL                        FSMC_FLAG_LEVEL
#define FMC_FLAG_FALLING_EDGE                 FSMC_FLAG_FALLING_EDGE
#define FMC_FLAG_FEMPT                        FSMC_FLAG_FEMPT
/**
  * @}
  */

/**
  * @}
  */

/* Private macro -------------------------------------------------------------*/
/** @defgroup FSMC_LL_Private_Macros FSMC Private Macros
  * @{
  */

/** @defgroup FSMC_LL_NOR_Macros FSMC NOR/SRAM Exported Macros
 *  @brief macros to handle NOR device enable/disable and read/write operations
 *  @{
 */
/**
  * @brief  Enable the NORSRAM device access.
  * @param  __INSTANCE__: FSMC_NORSRAM Instance
  * @param  __BANK__: FSMC_NORSRAM Bank
  * @retval none
  */
#define __FSMC_NORSRAM_ENABLE(__INSTANCE__, __BANK__)  ((__INSTANCE__)->BTCR[(__BANK__)] |= FSMC_BCR1_MBKEN)

/**
  * @brief  Disable the NORSRAM device access.
  * @param  __INSTANCE__: FSMC_NORSRAM Instance
  * @param  __BANK__: FSMC_NORSRAM Bank
  * @retval none
  */
#define __FSMC_NORSRAM_DISABLE(__INSTANCE__, __BANK__) ((__INSTANCE__)->BTCR[(__BANK__)] &= ~FSMC_BCR1_MBKEN)
/**
  * @}
  */

/** @defgroup FSMC_LL_NAND_Macros FSMC NAND Macros
 *  @brief macros to handle NAND device enable/disable
 *  @{
 */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
/**
  * @brief  Enable the NAND device access.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__: FSMC_NAND Bank
  * @retval none
  */
#define __FSMC_NAND_ENABLE(__INSTANCE__, __BANK__)  (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 |= FSMC_PCR2_PBKEN): \
                                                    ((__INSTANCE__)->PCR3 |= FSMC_PCR3_PBKEN))

/**
  * @brief  Disable the NAND device access.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__: FSMC_NAND Bank
  * @retval none
  */
#define __FSMC_NAND_DISABLE(__INSTANCE__, __BANK__) (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->PCR2 &= ~FSMC_PCR2_PBKEN): \
                                                   ((__INSTANCE__)->PCR3 &= ~FSMC_PCR3_PBKEN))
/**
  * @}
  */

/** @defgroup FSMC_LL_PCCARD_Macros FSMC PCCARD Macros
  *  @brief macros to handle SRAM read/write operations
  *  @{
  */
/**
  * @brief  Enable the PCCARD device access.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @retval none
  */
#define __FSMC_PCCARD_ENABLE(__INSTANCE__)  ((__INSTANCE__)->PCR4 |= FSMC_PCR4_PBKEN)

/**
  * @brief  Disable the PCCARD device access.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @retval none
  */
#define __FSMC_PCCARD_DISABLE(__INSTANCE__) ((__INSTANCE__)->PCR4 &= ~FSMC_PCR4_PBKEN)
/**
  * @}
  */

/** @defgroup FSMC_LL_Flag_Interrupt_Macros FSMC Flag&Interrupt Macros
 *  @brief macros to handle FSMC flags and interrupts
 * @{
 */
/**
  * @brief  Enable the NAND device interrupt.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__: FSMC_NAND Bank
  * @param  __INTERRUPT__: FSMC_NAND interrupt
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
  *            @arg FSMC_IT_LEVEL: Interrupt level.
  *            @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
  * @retval None
  */
#define __FSMC_NAND_ENABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__)  (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 |= (__INTERRUPT__)): \
                                                                                ((__INSTANCE__)->SR3 |= (__INTERRUPT__)))

/**
  * @brief  Disable the NAND device interrupt.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__: FSMC_NAND Bank
  * @param  __INTERRUPT__: FSMC_NAND interrupt
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
  *            @arg FSMC_IT_LEVEL: Interrupt level.
  *            @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
  * @retval None
  */
#define __FSMC_NAND_DISABLE_IT(__INSTANCE__, __BANK__, __INTERRUPT__)  (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__INTERRUPT__)): \
                                                                                ((__INSTANCE__)->SR3 &= ~(__INTERRUPT__)))

/**
  * @brief  Get flag status of the NAND device.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__    : FSMC_NAND Bank
  * @param  __FLAG__    : FSMC_NAND flag
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
  *            @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
  *            @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
  *            @arg FSMC_FLAG_FEMPT: FIFO empty flag.
  * @retval The state of FLAG (SET or RESET).
  */
#define __FSMC_NAND_GET_FLAG(__INSTANCE__, __BANK__, __FLAG__)  (((__BANK__) == FSMC_NAND_BANK2)? (((__INSTANCE__)->SR2 &(__FLAG__)) == (__FLAG__)): \
                                                                                (((__INSTANCE__)->SR3 &(__FLAG__)) == (__FLAG__)))

/**
  * @brief  Clear flag status of the NAND device.
  * @param  __INSTANCE__: FSMC_NAND Instance
  * @param  __BANK__: FSMC_NAND Bank
  * @param  __FLAG__: FSMC_NAND flag
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
  *            @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
  *            @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
  *            @arg FSMC_FLAG_FEMPT: FIFO empty flag.
  * @retval None
  */
#define __FSMC_NAND_CLEAR_FLAG(__INSTANCE__, __BANK__, __FLAG__)  (((__BANK__) == FSMC_NAND_BANK2)? ((__INSTANCE__)->SR2 &= ~(__FLAG__)): \
                                                                                ((__INSTANCE__)->SR3 &= ~(__FLAG__)))

/**
  * @brief  Enable the PCCARD device interrupt.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @param  __INTERRUPT__: FSMC_PCCARD interrupt
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
  *            @arg FSMC_IT_LEVEL: Interrupt level.
  *            @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
  * @retval None
  */
#define __FSMC_PCCARD_ENABLE_IT(__INSTANCE__, __INTERRUPT__)  ((__INSTANCE__)->SR4 |= (__INTERRUPT__))

/**
  * @brief  Disable the PCCARD device interrupt.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @param  __INTERRUPT__: FSMC_PCCARD interrupt
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_IT_RISING_EDGE: Interrupt rising edge.
  *            @arg FSMC_IT_LEVEL: Interrupt level.
  *            @arg FSMC_IT_FALLING_EDGE: Interrupt falling edge.
  * @retval None
  */
#define __FSMC_PCCARD_DISABLE_IT(__INSTANCE__, __INTERRUPT__)  ((__INSTANCE__)->SR4 &= ~(__INTERRUPT__))

/**
  * @brief  Get flag status of the PCCARD device.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @param  __FLAG__: FSMC_PCCARD flag
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
  *            @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
  *            @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
  *            @arg FSMC_FLAG_FEMPT: FIFO empty flag.
  * @retval The state of FLAG (SET or RESET).
  */
#define __FSMC_PCCARD_GET_FLAG(__INSTANCE__, __FLAG__)  (((__INSTANCE__)->SR4 &(__FLAG__)) == (__FLAG__))

/**
  * @brief  Clear flag status of the PCCARD device.
  * @param  __INSTANCE__: FSMC_PCCARD Instance
  * @param  __FLAG__: FSMC_PCCARD flag
  *         This parameter can be any combination of the following values:
  *            @arg FSMC_FLAG_RISING_EDGE: Interrupt rising edge flag.
  *            @arg FSMC_FLAG_LEVEL: Interrupt level edge flag.
  *            @arg FSMC_FLAG_FALLING_EDGE: Interrupt falling edge flag.
  *            @arg FSMC_FLAG_FEMPT: FIFO empty flag.
  * @retval None
  */
#define __FSMC_PCCARD_CLEAR_FLAG(__INSTANCE__, __FLAG__)  ((__INSTANCE__)->SR4 &= ~(__FLAG__))
/**
  * @}
  */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

/** @defgroup FSMC_LL_Assert_Macros FSMC Assert Macros
  * @{
  */
#define IS_FSMC_NORSRAM_BANK(__BANK__) (((__BANK__) == FSMC_NORSRAM_BANK1) || \
                                        ((__BANK__) == FSMC_NORSRAM_BANK2) || \
                                        ((__BANK__) == FSMC_NORSRAM_BANK3) || \
                                        ((__BANK__) == FSMC_NORSRAM_BANK4))

#define IS_FSMC_MUX(__MUX__) (((__MUX__) == FSMC_DATA_ADDRESS_MUX_DISABLE) || \
                              ((__MUX__) == FSMC_DATA_ADDRESS_MUX_ENABLE))

#define IS_FSMC_MEMORY(__MEMORY__) (((__MEMORY__) == FSMC_MEMORY_TYPE_SRAM) || \
                                    ((__MEMORY__) == FSMC_MEMORY_TYPE_PSRAM)|| \
                                    ((__MEMORY__) == FSMC_MEMORY_TYPE_NOR))

#define IS_FSMC_NORSRAM_MEMORY_WIDTH(__WIDTH__) (((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_8)  || \
                                                 ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_16) || \
                                                 ((__WIDTH__) == FSMC_NORSRAM_MEM_BUS_WIDTH_32))

#define IS_FSMC_ACCESS_MODE(__MODE__) (((__MODE__) == FSMC_ACCESS_MODE_A) || \
                                       ((__MODE__) == FSMC_ACCESS_MODE_B) || \
                                       ((__MODE__) == FSMC_ACCESS_MODE_C) || \
                                       ((__MODE__) == FSMC_ACCESS_MODE_D))

#define IS_FSMC_NAND_BANK(BANK) (((BANK) == FSMC_NAND_BANK2) || \
                                ((BANK) == FSMC_NAND_BANK3))

#define IS_FSMC_WAIT_FEATURE(FEATURE) (((FEATURE) == FSMC_NAND_PCC_WAIT_FEATURE_DISABLE) || \
                                      ((FEATURE) == FSMC_NAND_PCC_WAIT_FEATURE_ENABLE))

#define IS_FSMC_NAND_MEMORY_WIDTH(WIDTH) (((WIDTH) == FSMC_NAND_PCC_MEM_BUS_WIDTH_8) || \
                                         ((WIDTH) == FSMC_NAND_PCC_MEM_BUS_WIDTH_16))

#define IS_FSMC_ECC_STATE(STATE) (((STATE) == FSMC_NAND_ECC_DISABLE) || \
                                 ((STATE) == FSMC_NAND_ECC_ENABLE))

#define IS_FSMC_ECCPAGE_SIZE(SIZE) (((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_256BYTE)  || \
                                   ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_512BYTE)  || \
                                   ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_1024BYTE) || \
                                   ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_2048BYTE) || \
                                   ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_4096BYTE) || \
                                   ((SIZE) == FSMC_NAND_ECC_PAGE_SIZE_8192BYTE))

#define IS_FSMC_TCLR_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_TAR_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_SETUP_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_WAIT_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_HOLD_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_HIZ_TIME(TIME) ((TIME) <= 255U)

#define IS_FSMC_NORSRAM_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_DEVICE)

#define IS_FSMC_NORSRAM_EXTENDED_DEVICE(__INSTANCE__) ((__INSTANCE__) == FSMC_NORSRAM_EXTENDED_DEVICE)

#define IS_FSMC_NAND_DEVICE(INSTANCE) ((INSTANCE) == FSMC_NAND_DEVICE)

#define IS_FSMC_PCCARD_DEVICE(INSTANCE) ((INSTANCE) == FSMC_PCCARD_DEVICE)

#define IS_FSMC_BURSTMODE(__STATE__) (((__STATE__) == FSMC_BURST_ACCESS_MODE_DISABLE) || \
                                      ((__STATE__) == FSMC_BURST_ACCESS_MODE_ENABLE))

#define IS_FSMC_WAIT_POLARITY(__POLARITY__) (((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_LOW) || \
                                             ((__POLARITY__) == FSMC_WAIT_SIGNAL_POLARITY_HIGH))

#define IS_FSMC_WRAP_MODE(__MODE__) (((__MODE__) == FSMC_WRAP_MODE_DISABLE) || \
                                     ((__MODE__) == FSMC_WRAP_MODE_ENABLE))

#define IS_FSMC_WAIT_SIGNAL_ACTIVE(__ACTIVE__) (((__ACTIVE__) == FSMC_WAIT_TIMING_BEFORE_WS) || \
                                                ((__ACTIVE__) == FSMC_WAIT_TIMING_DURING_WS))

#define IS_FSMC_WRITE_OPERATION(__OPERATION__) (((__OPERATION__) == FSMC_WRITE_OPERATION_DISABLE) || \
                                                ((__OPERATION__) == FSMC_WRITE_OPERATION_ENABLE))

#define IS_FSMC_WAITE_SIGNAL(__SIGNAL__) (((__SIGNAL__) == FSMC_WAIT_SIGNAL_DISABLE) || \
                                          ((__SIGNAL__) == FSMC_WAIT_SIGNAL_ENABLE))

#define IS_FSMC_EXTENDED_MODE(__MODE__) (((__MODE__) == FSMC_EXTENDED_MODE_DISABLE) || \
                                         ((__MODE__) == FSMC_EXTENDED_MODE_ENABLE))

#define IS_FSMC_ASYNWAIT(__STATE__) (((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_DISABLE) || \
                                     ((__STATE__) == FSMC_ASYNCHRONOUS_WAIT_ENABLE))

#define IS_FSMC_DATA_LATENCY(__LATENCY__) (((__LATENCY__) > 1U) && ((__LATENCY__) <= 17U))

#define IS_FSMC_WRITE_BURST(__BURST__) (((__BURST__) == FSMC_WRITE_BURST_DISABLE) || \
                                        ((__BURST__) == FSMC_WRITE_BURST_ENABLE))

#define IS_FSMC_ADDRESS_SETUP_TIME(__TIME__) ((__TIME__) <= 15U)

#define IS_FSMC_ADDRESS_HOLD_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 15U))

#define IS_FSMC_DATASETUP_TIME(__TIME__) (((__TIME__) > 0U) && ((__TIME__) <= 255U))

#define IS_FSMC_TURNAROUND_TIME(__TIME__) ((__TIME__) <= 15U)

#define IS_FSMC_CONTINOUS_CLOCK(CCLOCK) (((CCLOCK) == FSMC_CONTINUOUS_CLOCK_SYNC_ONLY) || \
                                         ((CCLOCK) == FSMC_CONTINUOUS_CLOCK_SYNC_ASYNC))

#define IS_FSMC_CLK_DIV(DIV) (((DIV) > 1U) && ((DIV) <= 16U))

#define IS_FSMC_PAGESIZE(SIZE) (((SIZE) == FSMC_PAGE_SIZE_NONE) || \
                                ((SIZE) == FSMC_PAGE_SIZE_128)  || \
                                ((SIZE) == FSMC_PAGE_SIZE_256)  || \
                                ((SIZE) == FSMC_PAGE_SIZE_512)  || \
                                ((SIZE) == FSMC_PAGE_SIZE_1024))

#define IS_FSMC_WRITE_FIFO(FIFO) (((FIFO) == FSMC_WRITE_FIFO_DISABLE) || \
                                  ((FIFO) == FSMC_WRITE_FIFO_ENABLE))

/**
  * @}
  */
/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/
/** @defgroup FSMC_LL_Private_Functions FSMC LL Private Functions
  *  @{
  */

/** @defgroup FSMC_LL_NORSRAM  NOR SRAM
  *  @{
  */

/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group1 NOR SRAM Initialization/de-initialization functions
  *  @{
  */
HAL_StatusTypeDef  FSMC_NORSRAM_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_InitTypeDef *Init);
HAL_StatusTypeDef  FSMC_NORSRAM_Timing_Init(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NORSRAM_Extended_Timing_Init(FSMC_NORSRAM_EXTENDED_TypeDef *Device, FSMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode);
HAL_StatusTypeDef  FSMC_NORSRAM_DeInit(FSMC_NORSRAM_TypeDef *Device, FSMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank);
/**
  * @}
  */

/** @defgroup FSMC_LL_NORSRAM_Private_Functions_Group2 NOR SRAM Control functions
  *  @{
  */
HAL_StatusTypeDef  FSMC_NORSRAM_WriteOperation_Enable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NORSRAM_WriteOperation_Disable(FSMC_NORSRAM_TypeDef *Device, uint32_t Bank);
/**
  * @}
  */
/**
  * @}
  */

#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)
/** @defgroup FSMC_LL_NAND NAND
  *  @{
  */
/** @defgroup FSMC_LL_NAND_Private_Functions_Group1 NAND Initialization/de-initialization functions
  *  @{
  */
HAL_StatusTypeDef  FSMC_NAND_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_InitTypeDef *Init);
HAL_StatusTypeDef  FSMC_NAND_CommonSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NAND_AttributeSpace_Timing_Init(FSMC_NAND_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NAND_DeInit(FSMC_NAND_TypeDef *Device, uint32_t Bank);
/**
  * @}
  */

/** @defgroup FSMC_LL_NAND_Private_Functions_Group2 NAND Control functions
  *  @{
  */
HAL_StatusTypeDef  FSMC_NAND_ECC_Enable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NAND_ECC_Disable(FSMC_NAND_TypeDef *Device, uint32_t Bank);
HAL_StatusTypeDef  FSMC_NAND_GetECC(FSMC_NAND_TypeDef *Device, uint32_t *ECCval, uint32_t Bank, uint32_t Timeout);
/**
  * @}
  */
/**
  * @}
  */

/** @defgroup FSMC_LL_PCCARD PCCARD
  *  @{
  */
/** @defgroup FSMC_LL_PCCARD_Private_Functions_Group1 PCCARD Initialization/de-initialization functions
  *  @{
  */
HAL_StatusTypeDef  FSMC_PCCARD_Init(FSMC_PCCARD_TypeDef *Device, FSMC_PCCARD_InitTypeDef *Init);
HAL_StatusTypeDef  FSMC_PCCARD_CommonSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
HAL_StatusTypeDef  FSMC_PCCARD_AttributeSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
HAL_StatusTypeDef  FSMC_PCCARD_IOSpace_Timing_Init(FSMC_PCCARD_TypeDef *Device, FSMC_NAND_PCC_TimingTypeDef *Timing);
HAL_StatusTypeDef  FSMC_PCCARD_DeInit(FSMC_PCCARD_TypeDef *Device);
/**
  * @}
  */
/**
  * @}
  */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx */

/**
  * @}
  */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* __STM32F4xx_LL_FSMC_H */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


RSpec.shared_context 'packaged install' do
  let(:package_cachedir) { '/package/share/cache' }

  before(:each) do
    allow(PDK::Util).to receive(:package_install?).and_return(true)
    allow(PDK::Util::Filesystem).to receive(:file?).with(%r{PDK_VERSION}).and_return(true)
    allow(PDK::Util::Filesystem).to receive(:exist?).with(%r{bundle(\.bat)?$}).and_return(true)
    allow(PDK::Util).to receive(:package_cachedir).and_return(package_cachedir)
    allow(PDK::Util::RubyVersion).to receive(:versions).and_return('2.4.4' => '2.4.0')
    allow(PDK::Util::RubyVersion).to receive(:default_ruby_version).and_return('2.4.4')
  end
end

RSpec.shared_context 'not packaged install' do
  before(:each) do
    allow(PDK::Util).to receive(:package_install?).and_return(false)
  end
end


/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL

#include "SDL_cocoavideo.h"
#include "SDL_cocoaopengles.h"
#include "SDL_cocoaopengl.h"
#include "SDL_log.h"

/* EGL implementation of SDL OpenGL support */

int
Cocoa_GLES_LoadLibrary(_THIS, const char *path) {

    /* If the profile requested is not GL ES, switch over to WIN_GL functions  */
    if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
#if SDL_VIDEO_OPENGL_CGL
        Cocoa_GLES_UnloadLibrary(_this);
        _this->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
        _this->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
        _this->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
        _this->GL_CreateContext = Cocoa_GL_CreateContext;
        _this->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
        _this->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
        _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
        _this->GL_SwapWindow = Cocoa_GL_SwapWindow;
        _this->GL_DeleteContext = Cocoa_GL_DeleteContext;
        return Cocoa_GL_LoadLibrary(_this, path);
#else
        return SDL_SetError("SDL not configured with OpenGL/CGL support");
#endif
    }

    if (_this->egl_data == NULL) {
        return SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0);
    }

    return 0;
}

SDL_GLContext
Cocoa_GLES_CreateContext(_THIS, SDL_Window * window)
{
    SDL_GLContext context;
    SDL_WindowData *data = (SDL_WindowData *)window->driverdata;

#if SDL_VIDEO_OPENGL_CGL
    if (_this->gl_config.profile_mask != SDL_GL_CONTEXT_PROFILE_ES) {
        /* Switch to CGL based functions */
        Cocoa_GLES_UnloadLibrary(_this);
        _this->GL_LoadLibrary = Cocoa_GL_LoadLibrary;
        _this->GL_GetProcAddress = Cocoa_GL_GetProcAddress;
        _this->GL_UnloadLibrary = Cocoa_GL_UnloadLibrary;
        _this->GL_CreateContext = Cocoa_GL_CreateContext;
        _this->GL_MakeCurrent = Cocoa_GL_MakeCurrent;
        _this->GL_SetSwapInterval = Cocoa_GL_SetSwapInterval;
        _this->GL_GetSwapInterval = Cocoa_GL_GetSwapInterval;
        _this->GL_SwapWindow = Cocoa_GL_SwapWindow;
        _this->GL_DeleteContext = Cocoa_GL_DeleteContext;

        if (Cocoa_GL_LoadLibrary(_this, NULL) != 0) {
            return NULL;
        }

        return Cocoa_GL_CreateContext(_this, window);
    }
#endif

    context = SDL_EGL_CreateContext(_this, data->egl_surface);
    return context;
}

void
Cocoa_GLES_DeleteContext(_THIS, SDL_GLContext context)
{
    SDL_EGL_DeleteContext(_this, context);
    Cocoa_GLES_UnloadLibrary(_this);
}

SDL_EGL_SwapWindow_impl(Cocoa)
SDL_EGL_MakeCurrent_impl(Cocoa)

int
Cocoa_GLES_SetupWindow(_THIS, SDL_Window * window)
{
    /* The current context is lost in here; save it and reset it. */
    SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata;
    SDL_Window *current_win = SDL_GL_GetCurrentWindow();
    SDL_GLContext current_ctx = SDL_GL_GetCurrentContext();

    if (_this->egl_data == NULL) {
        if (SDL_EGL_LoadLibrary(_this, NULL, EGL_DEFAULT_DISPLAY, 0) < 0) {
            SDL_EGL_UnloadLibrary(_this);
            return -1;
        }
    }

    /* Create the GLES window surface */
    NSView* v = windowdata->nswindow.contentView;
    windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType)[v layer]);

    if (windowdata->egl_surface == EGL_NO_SURFACE) {
        return SDL_SetError("Could not create GLES window surface");
    }

    return Cocoa_GLES_MakeCurrent(_this, current_win, current_ctx);
}

#endif /* SDL_VIDEO_DRIVER_COCOA && SDL_VIDEO_OPENGL_EGL */

/* vi: set ts=4 sw=4 expandtab: */


/*******************************************************************************
*                                 AMetal
*                       ----------------------------
*                       innovating embedded platform
*
* Copyright (c) 2001-2018 Guangzhou ZHIYUAN Electronics Co., Ltd.
* All rights reserved.
*
* Contact information:
* web site:    http://www.zlg.cn/
*******************************************************************************/

/**
 * \file
 * \brief MiniPort-View + MiniPort-KEY 例程，通过标准接口实现
 *
 * - 操作步骤
 *   1. 先将 MiniPort-KEY 板子直接与 AM217BLE 的 MiniPort 相连接；
 *   2. 将 MiniPort-View 板子与 MiniPort-KEY 接口相连接。
 *
 * - 实验现象：
 *   1. 按下一个按键，两位数码管显示按键编号的二进制；
 *   2. 偶数编号时，数码管闪烁，奇数编号时，数码管不闪烁。
 *
 * \note
 *    测试本 Demo 必须在 am_prj_config.h 内将 AM_CFG_KEY_GPIO_ENABLE、
 *    AM_CFG_KEY_ENABLE 和 AM_CFG_SOFTIMER_ENABLE 定义为 1。但这些宏
 *    已经默认配置为 1， 用户不必再次配置。
 *
 * \par 源代码
 * \snippet demo_miniport_key_digitron.c src_miniport_key_digitron
 *
 * \internal
 * \par Modification history
 * - 1.00 17-07-03  nwt, first implementation
 * \endinternal
 */

/**
 * \addtogroup demo_if_miniport_key_digitron
 * \copydoc demo_miniport_key_digitron.c
 */

/** [src_miniport_key_digitron] */
#include "ametal.h"
#include "am_vdebug.h"
#include "am_zmf159_inst_init.h"
#include "demo_std_entries.h"
#include "demo_zmf159_core_entries.h"
#include "am_hwconf_miniport.h"

/**
 * \brief 例程入口
 */
void demo_zmf159_core_miniport_key_digitron_entry (void)
{
    AM_DBG_INFO("demo zmf159_core miniport key digitron!\r\n");

    am_miniport_view_key_inst_init();

    demo_std_key_digitron_entry(0);
}
/** [src_miniport_key_digitron] */

/* end of file */


<launch>

  <!-- This file makes it easy to include the settings for trajectory execution  -->

  <!-- Flag indicating whether MoveIt is allowed to load/unload  or switch controllers -->
  <arg name="moveit_manage_controllers" default="true"/>
  <param name="moveit_manage_controllers" value="$(arg moveit_manage_controllers)"/>

  <!-- When determining the expected duration of a trajectory, this multiplicative factor is applied to get the allowed duration of execution -->
  <param name="trajectory_execution/allowed_execution_duration_scaling" value="1.2"/> <!-- default 1.2 -->
  <!-- Allow more than the expected execution time before triggering a trajectory cancel (applied after scaling) -->
  <param name="trajectory_execution/allowed_goal_duration_margin" value="0.5"/> <!-- default 0.5 -->
  <!-- Allowed joint-value tolerance for validation that trajectory's first point matches current robot state -->
  <param name="trajectory_execution/allowed_start_tolerance" value="0.01"/> <!-- default 0.01 -->

  <!-- Load the robot specific controller manager; this sets the moveit_controller_manager ROS parameter -->
  <arg name="moveit_controller_manager" default="[ROBOT_NAME]" />
  <include file="$(find [GENERATED_PACKAGE_NAME])/launch/$(arg moveit_controller_manager)_moveit_controller_manager.launch.xml" />

</launch>


<?php

namespace SMW\MediaWiki\Hooks;

use Html;
use Page;
use SMW\DIProperty;
use SMW\DIWikiPage;
use SMW\MediaWiki\Jobs\ChangePropagationDispatchJob;
use SMW\MediaWiki\HookListener;
use SMW\OptionsAwareTrait;
use SMW\DependencyValidator;
use SMW\NamespaceExaminer;
use SMW\Message;
use SMW\Store;
use Title;

/**
 * @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleViewHeader
 *
 * Note: This hook is not called on non-article pages (including edit pages) and
 * it is also not called prior to outputting the edit preview.
 *
 * @license GNU GPL v2+
 * @since 3.0
 *
 * @author mwjames
 */
class ArticleViewHeader implements HookListener {

	use OptionsAwareTrait;

	/**
	 * @var Store
	 */
	private $store;

	/**
	 * @var NamespaceExaminer
	 */
	private $namespaceExaminer;

	/**
	 * @var DependencyValidator
	 */
	private $dependencyValidator;

	/**
	 * @since 3.0
	 *
	 * @param Store $store
	 * @param NamespaceExaminer $namespaceExaminer
	 * @param DependencyValidator $dependencyLinksValidator
	 */
	public function __construct( Store $store, NamespaceExaminer $namespaceExaminer, DependencyValidator $dependencyValidator ) {
		$this->store = $store;
		$this->namespaceExaminer = $namespaceExaminer;
		$this->dependencyValidator = $dependencyValidator;
	}

	/**
	 * @since 3.0
	 *
	 * @param Page $page
	 * @param boolean &$outputDone
	 * @param boolean &$useParserCache
	 *
	 * @return bool
	 */
	public function process( Page $page, &$outputDone, &$useParserCache ) {

		$title = $page->getTitle();

		if ( !$this->namespaceExaminer->isSemanticEnabled( $title->getNamespace() ) ) {
			return true;
		}

		$subject = DIWikiPage::newFromTitle( $title );

		// Preload data most likely to be used during a request hereby providing
		// a possibility to bundle relevant data objects early given that this
		// hook runs before any other GET request
		$this->store->getObjectIds()->preload( [ $subject ] );

		$changePropagationWatchlist = array_flip(
			$this->getOption( 'smwgChangePropagationWatchlist', [] )
		);

		// Only act when `_SUBC` is maintained as watchable property
		if ( isset( $changePropagationWatchlist['_SUBC'] ) && $title->getNamespace() === NS_CATEGORY ) {
			$useParserCache = $this->updateCategoryTop( $title, $page->getContext()->getOutput() );
		}

		if ( $this->dependencyValidator->hasArchaicDependencies( $subject ) ) {
			$this->dependencyValidator->markTitle( $title );
			// Disable the parser cache even before `RejectParserCacheValue` comes into play
			$useParserCache = false;
		}

		return true;
	}

	private function updateCategoryTop( $title, $output ) {

		$message = '';

		$subject = DIWikiPage::newFromTitle(
			$title
		);

		$semanticData = $this->store->getSemanticData(
			$subject
		);

		if ( $semanticData->hasProperty( new DIProperty( DIProperty::TYPE_CHANGE_PROP ) ) ) {
			$severity = $this->getOption( 'smwgChangePropagationProtection', true ) ? 'error' : 'warning';

			$message .= $this->message(
				$severity,
				[
					'smw-category-change-propagation-locked-' . $severity,
					str_replace( '_', ' ', $subject->getDBKey() )
				]
			);
		}

		if ( $message === '' && ChangePropagationDispatchJob::hasPendingJobs( $subject ) ) {
			$message .= $this->message(
				'warning',
				[
					'smw-category-change-propagation-pending',
					ChangePropagationDispatchJob::getPendingJobsCount( $subject )
				]
			);
		}

		$output->addHTML( $message );

		// No Message means `useParserCache`otherwise refresh the output to
		// display the latest update
		return $message === '';
	}

	private function message( $type, array $message ) {
		return Html::rawElement(
			'div',
			[
				'id' => $message[0],
				'class' => 'plainlinks ' . ( $type !== '' ? 'smw-callout smw-callout-' . $type : '' )
			],
			Message::get( $message, Message::PARSE, Message::USER_LANGUAGE )
		);
	}

}


# SPDX-License-Identifier: GPL-2.0-only
config COMMON_CLK_HI3516CV300
	tristate "HI3516CV300 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	select RESET_HISI
	default ARCH_HISI
	help
	  Build the clock driver for hi3516cv300.

config COMMON_CLK_HI3519
	tristate "Hi3519 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	select RESET_HISI
	default ARCH_HISI
	help
	  Build the clock driver for hi3519.

config COMMON_CLK_HI3660
	bool "Hi3660 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	default ARCH_HISI
	help
	  Build the clock driver for hi3660.

config COMMON_CLK_HI3670
	bool "Hi3670 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	default ARCH_HISI
	help
	  Build the clock driver for hi3670.

config COMMON_CLK_HI3798CV200
	tristate "Hi3798CV200 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	select RESET_HISI
	default ARCH_HISI
	help
	  Build the clock driver for hi3798cv200.

config COMMON_CLK_HI6220
	bool "Hi6220 Clock Driver"
	depends on ARCH_HISI || COMPILE_TEST
	default ARCH_HISI
	help
	  Build the Hisilicon Hi6220 clock driver based on the common clock framework.

config RESET_HISI
	bool "HiSilicon Reset Controller Driver"
	depends on ARCH_HISI || COMPILE_TEST
	select RESET_CONTROLLER
	help
	  Build reset controller driver for HiSilicon device chipsets.

config STUB_CLK_HI6220
	bool "Hi6220 Stub Clock Driver" if EXPERT
	depends on (COMMON_CLK_HI6220 || COMPILE_TEST)
	depends on MAILBOX
	default COMMON_CLK_HI6220
	help
	  Build the Hisilicon Hi6220 stub clock driver.

config STUB_CLK_HI3660
	bool "Hi3660 Stub Clock Driver" if EXPERT
	depends on (COMMON_CLK_HI3660 || COMPILE_TEST)
	depends on MAILBOX
	default COMMON_CLK_HI3660
	help
	  Build the Hisilicon Hi3660 stub clock driver.


/// <reference path='fourslash.ts' />

////class C<T = number> {
////    x?: T;
////    constructor(x: T) { this.x = x; }
////}
////let a = C(1, 2, 3);
////let b = C<string>("hello");
////let c = C<boolean>();

verify.codeFixAll({
    fixId: "addMissingNewOperator",
    fixAllDescription: "Add missing 'new' operator to all calls",
    newFileContent:
`class C<T = number> {
    x?: T;
    constructor(x: T) { this.x = x; }
}
let a = new C(1, 2, 3);
let b = new C<string>("hello");
let c = new C<boolean>();`
});


"""
Interactive legend plugin
=========================
This is a demonstration of how to add an interactive legend to data plots.
The Plugin is defined within mpld3. The user provides how select/unselect
and legend overlay
will affect the alpha parameter of associated objects.
You can also control how to initialize the graph: all selected or unselected.
"""
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import mpld3
from mpld3 import plugins
np.random.seed(9615)

# generate df
N = 100
df = pd.DataFrame((.1 * (np.random.random((N, 5)) - .5)).cumsum(0),
                  columns=['a', 'b', 'c', 'd', 'e'],)

# plot line + confidence interval
fig, ax = plt.subplots()
ax.grid(True, alpha=0.3)

for key, val in df.iteritems():
    l, = ax.plot(val.index, val.values, label=key)
    ax.fill_between(val.index,
                    val.values * .5, val.values * 1.5,
                    color=l.get_color(), alpha=.4)

# define interactive legend

handles, labels = ax.get_legend_handles_labels() # return lines and labels
interactive_legend = plugins.InteractiveLegendPlugin(zip(handles,
                                                         ax.collections),
                                                     labels,
                                                     alpha_unsel=0.5,
                                                     alpha_over=1.5,
                                                     start_visible=True)
plugins.connect(fig, interactive_legend)

ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title('Interactive legend', size=20)

mpld3.show()


"use strict";

require("../../style/index.less");

require("./index.less");


// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'countertop.dart';

void main() {
  SystemChrome.setEnabledSystemUIOverlays([]);
  return runApp(FortnightlyCountertop());
}


angular.module('chatApp.chat', ['chatApp.utils'])
.controller('ChatCtrl', function($rootScope, $scope, $state, $_) {

    $scope.chatState = "Start Chatting";
    $rootScope.chatuser = {
        name: "",
        phone: "",
        email: ""
    };

    var data = {
        UserPoolId : USER_POOL_ID,
        ClientId : CLIENT_ID
    };
    var userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(data);
    var cognitoUser = userPool.getCurrentUser();

    if (cognitoUser != null) {
        cognitoUser.getSession(function(err, session) {
            if (err) {
                $scope.signout();
                return;
            }
            console.log('session validity: ' + session.isValid());
            cognitoUser.getUserAttributes(function(err, result) {
                if (err) {
                    console.log(err);
                    return;
                }
                var nm = $_.where(result, { Name: "name" });
                if (nm.length > 0) {
                    $rootScope.chatuser.name = nm[0].Value;
                }

                var ph = $_.where(result, { Name: "phone_number" });
                if (ph.length > 0) {
                    $rootScope.chatuser.phone = ph[0].Value;
                }

                var em = $_.where(result, { Name: "email" });
                if (em.length > 0) {
                    $rootScope.chatuser.email = em[0].Value;
                }
                $scope.$apply();

            });
        });
    }

    var login = function() {
        $rootScope.chatting = true;
        $rootScope.$emit('chatting');
        $scope.chatState = "Stop Chatting";

    };

    var logoff = function() {
        $scope.chatState = "Start Chatting";
        $rootScope.chatting = false;
        $rootScope.$emit('not chatting');
    };

    $scope.toggleChatting = function() {
        if($rootScope.chatting) {
            logoff();
        } else {
            login();
        }
    };

    $scope.signout = function() {
        if (cognitoUser != null) {
            console.log("logging user out");
            $scope.chatState = "Start Chatting";
            $rootScope.chatting = false;
            $rootScope.$emit('not chatting');
            cognitoUser.signOut();
            AWS.config.credentials.clearCachedId();
            $state.go('signin', { });
        }
    };

});


'use strict';

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

var flexSpec = require('./flex-spec');
var Declaration = require('../declaration');

var AlignSelf = function (_Declaration) {
    _inherits(AlignSelf, _Declaration);

    function AlignSelf() {
        _classCallCheck(this, AlignSelf);

        return _possibleConstructorReturn(this, _Declaration.apply(this, arguments));
    }

    /**
     * Change property name for 2012 specs
     */
    AlignSelf.prototype.prefixed = function prefixed(prop, prefix) {
        var spec = void 0;

        var _flexSpec = flexSpec(prefix);

        spec = _flexSpec[0];
        prefix = _flexSpec[1];

        if (spec === 2012) {
            return prefix + 'flex-item-align';
        } else {
            return _Declaration.prototype.prefixed.call(this, prop, prefix);
        }
    };

    /**
     * Return property name by final spec
     */

    AlignSelf.prototype.normalize = function normalize() {
        return 'align-self';
    };

    /**
     * Change value for 2012 spec and ignore prefix for 2009
     */

    AlignSelf.prototype.set = function set(decl, prefix) {
        var spec = flexSpec(prefix)[0];
        if (spec === 2012) {
            decl.value = AlignSelf.oldValues[decl.value] || decl.value;
            return _Declaration.prototype.set.call(this, decl, prefix);
        } else if (spec === 'final') {
            return _Declaration.prototype.set.call(this, decl, prefix);
        }
        return undefined;
    };

    return AlignSelf;
}(Declaration);

Object.defineProperty(AlignSelf, 'names', {
    enumerable: true,
    writable: true,
    value: ['align-self', 'flex-item-align']
});
Object.defineProperty(AlignSelf, 'oldValues', {
    enumerable: true,
    writable: true,
    value: {
        'flex-end': 'end',
        'flex-start': 'start'
    }
});

module.exports = AlignSelf;


using NUnit.Framework;
using OpenWrap.Commands.Messages;
using OpenWrap.Testing;

namespace Tests.Commands.remote.set
{
    [TestFixture("secundus -username sauron")]
    [TestFixture("secundus -password sarumansucks")]
    public class changing_credentials_missing : contexts.set_remote
    {
        public changing_credentials_missing(string input)
        {
            given_remote_config("secundus");
            when_executing_command(input);
        }

        [Test]
        public void error_is_returned()
        {
            Results.ShouldHaveOne<IncompleteCredentials>();
        }
    }
}


// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package messageset encodes and decodes the obsolete MessageSet wire format.
package messageset

import (
	"math"

	"google.golang.org/protobuf/encoding/protowire"
	"google.golang.org/protobuf/internal/errors"
	pref "google.golang.org/protobuf/reflect/protoreflect"
	preg "google.golang.org/protobuf/reflect/protoregistry"
)

// The MessageSet wire format is equivalent to a message defiend as follows,
// where each Item defines an extension field with a field number of 'type_id'
// and content of 'message'. MessageSet extensions must be non-repeated message
// fields.
//
//	message MessageSet {
//		repeated group Item = 1 {
//			required int32 type_id = 2;
//			required string message = 3;
//		}
//	}
const (
	FieldItem    = protowire.Number(1)
	FieldTypeID  = protowire.Number(2)
	FieldMessage = protowire.Number(3)
)

// ExtensionName is the field name for extensions of MessageSet.
//
// A valid MessageSet extension must be of the form:
//	message MyMessage {
//		extend proto2.bridge.MessageSet {
//			optional MyMessage message_set_extension = 1234;
//		}
//		...
//	}
const ExtensionName = "message_set_extension"

// IsMessageSet returns whether the message uses the MessageSet wire format.
func IsMessageSet(md pref.MessageDescriptor) bool {
	xmd, ok := md.(interface{ IsMessageSet() bool })
	return ok && xmd.IsMessageSet()
}

// IsMessageSetExtension reports this field extends a MessageSet.
func IsMessageSetExtension(fd pref.FieldDescriptor) bool {
	if fd.Name() != ExtensionName {
		return false
	}
	if fd.FullName().Parent() != fd.Message().FullName() {
		return false
	}
	return IsMessageSet(fd.ContainingMessage())
}

// FindMessageSetExtension locates a MessageSet extension field by name.
// In text and JSON formats, the extension name used is the message itself.
// The extension field name is derived by appending ExtensionName.
func FindMessageSetExtension(r preg.ExtensionTypeResolver, s pref.FullName) (pref.ExtensionType, error) {
	name := s.Append(ExtensionName)
	xt, err := r.FindExtensionByName(name)
	if err != nil {
		if err == preg.NotFound {
			return nil, err
		}
		return nil, errors.Wrap(err, "%q", name)
	}
	if !IsMessageSetExtension(xt.TypeDescriptor()) {
		return nil, preg.NotFound
	}
	return xt, nil
}

// SizeField returns the size of a MessageSet item field containing an extension
// with the given field number, not counting the contents of the message subfield.
func SizeField(num protowire.Number) int {
	return 2*protowire.SizeTag(FieldItem) + protowire.SizeTag(FieldTypeID) + protowire.SizeVarint(uint64(num))
}

// Unmarshal parses a MessageSet.
//
// It calls fn with the type ID and value of each item in the MessageSet.
// Unknown fields are discarded.
//
// If wantLen is true, the item values include the varint length prefix.
// This is ugly, but simplifies the fast-path decoder in internal/impl.
func Unmarshal(b []byte, wantLen bool, fn func(typeID protowire.Number, value []byte) error) error {
	for len(b) > 0 {
		num, wtyp, n := protowire.ConsumeTag(b)
		if n < 0 {
			return protowire.ParseError(n)
		}
		b = b[n:]
		if num != FieldItem || wtyp != protowire.StartGroupType {
			n := protowire.ConsumeFieldValue(num, wtyp, b)
			if n < 0 {
				return protowire.ParseError(n)
			}
			b = b[n:]
			continue
		}
		typeID, value, n, err := ConsumeFieldValue(b, wantLen)
		if err != nil {
			return err
		}
		b = b[n:]
		if typeID == 0 {
			continue
		}
		if err := fn(typeID, value); err != nil {
			return err
		}
	}
	return nil
}

// ConsumeFieldValue parses b as a MessageSet item field value until and including
// the trailing end group marker. It assumes the start group tag has already been parsed.
// It returns the contents of the type_id and message subfields and the total
// item length.
//
// If wantLen is true, the returned message value includes the length prefix.
func ConsumeFieldValue(b []byte, wantLen bool) (typeid protowire.Number, message []byte, n int, err error) {
	ilen := len(b)
	for {
		num, wtyp, n := protowire.ConsumeTag(b)
		if n < 0 {
			return 0, nil, 0, protowire.ParseError(n)
		}
		b = b[n:]
		switch {
		case num == FieldItem && wtyp == protowire.EndGroupType:
			if wantLen && len(message) == 0 {
				// The message field was missing, which should never happen.
				// Be prepared for this case anyway.
				message = protowire.AppendVarint(message, 0)
			}
			return typeid, message, ilen - len(b), nil
		case num == FieldTypeID && wtyp == protowire.VarintType:
			v, n := protowire.ConsumeVarint(b)
			if n < 0 {
				return 0, nil, 0, protowire.ParseError(n)
			}
			b = b[n:]
			if v < 1 || v > math.MaxInt32 {
				return 0, nil, 0, errors.New("invalid type_id in message set")
			}
			typeid = protowire.Number(v)
		case num == FieldMessage && wtyp == protowire.BytesType:
			m, n := protowire.ConsumeBytes(b)
			if n < 0 {
				return 0, nil, 0, protowire.ParseError(n)
			}
			if message == nil {
				if wantLen {
					message = b[:n:n]
				} else {
					message = m[:len(m):len(m)]
				}
			} else {
				// This case should never happen in practice, but handle it for
				// correctness: The MessageSet item contains multiple message
				// fields, which need to be merged.
				//
				// In the case where we're returning the length, this becomes
				// quite inefficient since we need to strip the length off
				// the existing data and reconstruct it with the combined length.
				if wantLen {
					_, nn := protowire.ConsumeVarint(message)
					m0 := message[nn:]
					message = nil
					message = protowire.AppendVarint(message, uint64(len(m0)+len(m)))
					message = append(message, m0...)
					message = append(message, m...)
				} else {
					message = append(message, m...)
				}
			}
			b = b[n:]
		default:
			// We have no place to put it, so we just ignore unknown fields.
			n := protowire.ConsumeFieldValue(num, wtyp, b)
			if n < 0 {
				return 0, nil, 0, protowire.ParseError(n)
			}
			b = b[n:]
		}
	}
}

// AppendFieldStart appends the start of a MessageSet item field containing
// an extension with the given number. The caller must add the message
// subfield (including the tag).
func AppendFieldStart(b []byte, num protowire.Number) []byte {
	b = protowire.AppendTag(b, FieldItem, protowire.StartGroupType)
	b = protowire.AppendTag(b, FieldTypeID, protowire.VarintType)
	b = protowire.AppendVarint(b, uint64(num))
	return b
}

// AppendFieldEnd appends the trailing end group marker for a MessageSet item field.
func AppendFieldEnd(b []byte) []byte {
	return protowire.AppendTag(b, FieldItem, protowire.EndGroupType)
}

// SizeUnknown returns the size of an unknown fields section in MessageSet format.
//
// See AppendUnknown.
func SizeUnknown(unknown []byte) (size int) {
	for len(unknown) > 0 {
		num, typ, n := protowire.ConsumeTag(unknown)
		if n < 0 || typ != protowire.BytesType {
			return 0
		}
		unknown = unknown[n:]
		_, n = protowire.ConsumeBytes(unknown)
		if n < 0 {
			return 0
		}
		unknown = unknown[n:]
		size += SizeField(num) + protowire.SizeTag(FieldMessage) + n
	}
	return size
}

// AppendUnknown appends unknown fields to b in MessageSet format.
//
// For historic reasons, unresolved items in a MessageSet are stored in a
// message's unknown fields section in non-MessageSet format. That is, an
// unknown item with typeID T and value V appears in the unknown fields as
// a field with number T and value V.
//
// This function converts the unknown fields back into MessageSet form.
func AppendUnknown(b, unknown []byte) ([]byte, error) {
	for len(unknown) > 0 {
		num, typ, n := protowire.ConsumeTag(unknown)
		if n < 0 || typ != protowire.BytesType {
			return nil, errors.New("invalid data in message set unknown fields")
		}
		unknown = unknown[n:]
		_, n = protowire.ConsumeBytes(unknown)
		if n < 0 {
			return nil, errors.New("invalid data in message set unknown fields")
		}
		b = AppendFieldStart(b, num)
		b = protowire.AppendTag(b, FieldMessage, protowire.BytesType)
		b = append(b, unknown[:n]...)
		b = AppendFieldEnd(b)
		unknown = unknown[n:]
	}
	return b, nil
}


# https://raw.githubusercontent.com/rook/rook/v1.0.4/cluster/examples/kubernetes/ceph/cluster.yaml

#################################################################################################################
# Define the settings for the rook-ceph cluster with common settings for a production cluster.
# All nodes with available raw devices will be used for the Ceph cluster. At least three nodes are required
# in this example. See the documentation for more details on storage settings available.

# For example, to create the cluster:
#   kubectl create -f common.yaml
#   kubectl create -f operator.yaml
#   kubectl create -f cluster.yaml
#################################################################################################################

apiVersion: ceph.rook.io/v1
kind: CephCluster
metadata:
  name: rook-ceph
  namespace: rook-ceph
spec:
  cephVersion:
    # The container image used to launch the Ceph daemon pods (mon, mgr, osd, mds, rgw).
    # v12 is luminous, v13 is mimic, and v14 is nautilus.
    # RECOMMENDATION: In production, use a specific version tag instead of the general v14 flag, which pulls the latest release and could result in different
    # versions running within the cluster. See tags available at https://hub.docker.com/r/ceph/ceph/tags/.
    image: ceph/ceph:v14.2.1-20190430
    # Whether to allow unsupported versions of Ceph. Currently luminous, mimic and nautilus are supported, with the recommendation to upgrade to nautilus.
    # Do not set to true in production.
    allowUnsupported: false
  # The path on the host where configuration files will be persisted. Must be specified.
  # Important: if you reinstall the cluster, make sure you delete this directory from each host or else the mons will fail to start on the new cluster.
  # In Minikube, the '/data' directory is configured to persist across reboots. Use "/data/rook" in Minikube environment.
  dataDirHostPath: /var/lib/rook
  # set the amount of mons to be started
  mon:
    count: 3
    allowMultiplePerNode: false
  # enable the ceph dashboard for viewing cluster status
  dashboard:
    enabled: true
    # serve the dashboard under a subpath (useful when you are accessing the dashboard via a reverse proxy)
    # urlPrefix: /ceph-dashboard
    # serve the dashboard at the given port.
    # port: 8443
    # serve the dashboard using SSL
    # ssl: true
  network:
    # toggle to use hostNetwork
    hostNetwork: false
  rbdMirroring:
    # The number of daemons that will perform the rbd mirroring.
    # rbd mirroring must be configured with "rbd mirror" from the rook toolbox.
    workers: 0
  # To control where various services will be scheduled by kubernetes, use the placement configuration sections below.
  # The example under 'all' would have all services scheduled on kubernetes nodes labeled with 'role=storage-node' and
  # tolerate taints with a key of 'storage-node'.
#  placement:
#    all:
#      nodeAffinity:
#        requiredDuringSchedulingIgnoredDuringExecution:
#          nodeSelectorTerms:
#          - matchExpressions:
#            - key: role
#              operator: In
#              values:
#              - storage-node
#      podAffinity:
#      podAntiAffinity:
#      tolerations:
#      - key: storage-node
#        operator: Exists
# The above placement information can also be specified for mon, osd, and mgr components
#    mon:
#    osd:
#    mgr:
  annotations:
#    all:
#    mon:
#    osd:
# If no mgr annotations are set, prometheus scrape annotations will be set by default.
#   mgr:
  resources:
# The requests and limits set here, allow the mgr pod to use half of one CPU core and 1 gigabyte of memory
#    mgr:
#      limits:
#        cpu: "500m"
#        memory: "1024Mi"
#      requests:
#        cpu: "500m"
#        memory: "1024Mi"
# The above example requests/limits can also be added to the mon and osd components
#    mon:
#    osd:
  storage: # cluster level storage configuration and selection
    useAllNodes: true
    useAllDevices: true
    deviceFilter:
    location:
    config:
      # The default and recommended storeType is dynamically set to bluestore for devices and filestore for directories.
      # Set the storeType explicitly only if it is required not to use the default.
      # storeType: bluestore
      # metadataDevice: "md0" # specify a non-rotational storage so ceph-volume will use it as block db device of bluestore.
      # databaseSizeMB: "1024" # uncomment if the disks are smaller than 100 GB
      # journalSizeMB: "1024"  # uncomment if the disks are 20 GB or smaller
      # osdsPerDevice: "1" # this value can be overridden at the node or device level
      # encryptedDevice: "true" # the default value for this option is "false"
# Cluster level list of directories to use for filestore-based OSD storage. If uncommented, this example would create an OSD under the dataDirHostPath.
    #directories:
    #- path: /var/lib/rook
# Individual nodes and their config can be specified as well, but 'useAllNodes' above must be set to false. Then, only the named
# nodes below will be used as storage resources.  Each node's 'name' field should match their 'kubernetes.io/hostname' label.
#    nodes:
#    - name: "172.17.4.101"
#      directories: # specific directories to use for storage can be specified for each node
#      - path: "/rook/storage-dir"
#      resources:
#        limits:
#          cpu: "500m"
#          memory: "1024Mi"
#        requests:
#          cpu: "500m"
#          memory: "1024Mi"
#    - name: "172.17.4.201"
#      devices: # specific devices to use for storage can be specified for each node
#      - name: "sdb"
#      - name: "nvme01" # multiple osds can be created on high performance devices
#        config:
#          osdsPerDevice: "5"
#      config: # configuration can be specified at the node level which overrides the cluster level config
#        storeType: filestore
#    - name: "172.17.4.301"
#      deviceFilter: "^sd."


/* Credit to https://gist.github.com/wataru420/2048287 */
.highlight {
  /* Comment */
  /* Error */
  /* Keyword */
  /* Operator */
  /* Comment.Multiline */
  /* Comment.Preproc */
  /* Comment.Single */
  /* Comment.Special */
  /* Generic.Deleted */
  /* Generic.Deleted.Specific */
  /* Generic.Emph */
  /* Generic.Error */
  /* Generic.Heading */
  /* Generic.Inserted */
  /* Generic.Inserted.Specific */
  /* Generic.Output */
  /* Generic.Prompt */
  /* Generic.Strong */
  /* Generic.Subheading */
  /* Generic.Traceback */
  /* Keyword.Constant */
  /* Keyword.Declaration */
  /* Keyword.Pseudo */
  /* Keyword.Reserved */
  /* Keyword.Type */
  /* Literal.Number */
  /* Literal.String */
  /* Name.Attribute */
  /* Name.Builtin */
  /* Name.Class */
  /* Name.Constant */
  /* Name.Entity */
  /* Name.Exception */
  /* Name.Function */
  /* Name.Namespace */
  /* Name.Tag */
  /* Name.Variable */
  /* Operator.Word */
  /* Text.Whitespace */
  /* Literal.Number.Float */
  /* Literal.Number.Hex */
  /* Literal.Number.Integer */
  /* Literal.Number.Oct */
  /* Literal.String.Backtick */
  /* Literal.String.Char */
  /* Literal.String.Doc */
  /* Literal.String.Double */
  /* Literal.String.Escape */
  /* Literal.String.Heredoc */
  /* Literal.String.Interpol */
  /* Literal.String.Other */
  /* Literal.String.Regex */
  /* Literal.String.Single */
  /* Literal.String.Symbol */
  /* Name.Builtin.Pseudo */
  /* Name.Variable.Class */
  /* Name.Variable.Global */
  /* Name.Variable.Instance */
  /* Literal.Number.Integer.Long */ }
  .highlight .c {
    color: #999988;
    font-style: italic; }
  .highlight .err {
    color: #a61717;
    background-color: #e3d2d2; }
  .highlight .k {
    color: #000000;
    font-weight: bold; }
  .highlight .o {
    color: #000000;
    font-weight: bold; }
  .highlight .cm {
    color: #999988;
    font-style: italic; }
  .highlight .cp {
    color: #999999;
    font-weight: bold; }
  .highlight .c1 {
    color: #999988;
    font-style: italic; }
  .highlight .cs {
    color: #999999;
    font-weight: bold;
    font-style: italic; }
  .highlight .gd {
    color: #000000;
    background-color: #ffdddd; }
  .highlight .gd .x {
    color: #000000;
    background-color: #ffaaaa; }
  .highlight .ge {
    color: #000000;
    font-style: italic; }
  .highlight .gr {
    color: #aa0000; }
  .highlight .gh {
    color: #999999; }
  .highlight .gi {
    color: #000000;
    background-color: #ddffdd; }
  .highlight .gi .x {
    color: #000000;
    background-color: #aaffaa; }
  .highlight .go {
    color: #888888; }
  .highlight .gp {
    color: #555555; }
  .highlight .gs {
    font-weight: bold; }
  .highlight .gu {
    color: #aaaaaa; }
  .highlight .gt {
    color: #aa0000; }
  .highlight .kc {
    color: #000000;
    font-weight: bold; }
  .highlight .kd {
    color: #000000;
    font-weight: bold; }
  .highlight .kp {
    color: #000000;
    font-weight: bold; }
  .highlight .kr {
    color: #000000;
    font-weight: bold; }
  .highlight .kt {
    color: #445588; }
  .highlight .m {
    color: #009999; }
  .highlight .s {
    color: #d14; }
  .highlight .na {
    color: #008080; }
  .highlight .nb {
    color: #0086B3; }
  .highlight .nc {
    color: #445588;
    font-weight: bold; }
  .highlight .no {
    color: #008080; }
  .highlight .ni {
    color: #800080; }
  .highlight .ne {
    color: #990000;
    font-weight: bold; }
  .highlight .nf {
    color: #990000; }
  .highlight .nn {
    color: #555555; }
  .highlight .nt {
    color: #000080; }
  .highlight .nv {
    color: #008080; }
  .highlight .ow {
    color: #000000;
    font-weight: bold; }
  .highlight .w {
    color: #bbbbbb; }
  .highlight .mf {
    color: #009999; }
  .highlight .mh {
    color: #009999; }
  .highlight .mi {
    color: #009999; }
  .highlight .mo {
    color: #009999; }
  .highlight .sb {
    color: #d14; }
  .highlight .sc {
    color: #d14; }
  .highlight .sd {
    color: #d14; }
  .highlight .s2 {
    color: #d14; }
  .highlight .se {
    color: #d14; }
  .highlight .sh {
    color: #d14; }
  .highlight .si {
    color: #d14; }
  .highlight .sx {
    color: #d14; }
  .highlight .sr {
    color: #009926; }
  .highlight .s1 {
    color: #d14; }
  .highlight .ss {
    color: #990073; }
  .highlight .bp {
    color: #999999; }
  .highlight .vc {
    color: #008080; }
  .highlight .vg {
    color: #008080; }
  .highlight .vi {
    color: #008080; }
  .highlight .il {
    color: #009999; }


#include "spherePlot.h"

/***********************************************************
* Constructor                                              *
***********************************************************/

SpherePlot::SpherePlot(int _numberLevelsBig, int _numberLevelsSmall, float _radiusBig, float _radiusSmall, SourceManager *_sourceManager, int _width, int _height, QMutex *_mutex)
{

    // Create the spheres
    this->bigSphere = new Sphere(_numberLevelsBig, _radiusBig);
    this->smallSphere = new Sphere(_numberLevelsSmall, _radiusSmall);

    // Save pointer to the source manager
    this->currentSourceManager = _sourceManager;

    // Connect
    this->colorsToDraw = &this->currentSourceManager->connectColors;
    this->xPosition = &this->currentSourceManager->connectXPosition;
    this->yPosition = &this->currentSourceManager->connectYPosition;
    this->zPosition = &this->currentSourceManager->connectZPosition;

    this->rotationX = -60.0;
    this->rotationY = 0.0;
    this->rotationZ = -45.0;

    // Initialize
    this->setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));

    // Zoom
    this->zoom = -6.0;

    // Mouse cursor
    this->setCursor(Qt::OpenHandCursor);

    // Resize
    this->resizeGL(_width, _height);

    // Save the mutex
    this->blockRendering = _mutex;

}

/***********************************************************
* Destructor                                               *
***********************************************************/

SpherePlot::~SpherePlot()
{

    delete this->bigSphere;
    delete this->smallSphere;

}

/***********************************************************
* Mutator                                                  *
***********************************************************/

// +-------------------------------------------------------+
// | Set the background color                              |
// +-------------------------------------------------------+

void SpherePlot::setBackgroundColor(QColor _color)
{
    this->backgroundColor = _color;
}

// +-------------------------------------------------------+
// | Set the axes color                                    |
// +-------------------------------------------------------+

void SpherePlot::setAxesColor(QColor _color)
{
    this->axesColor = _color;
}

// +-------------------------------------------------------+
// | Set the top grid color                                |
// +-------------------------------------------------------+

void SpherePlot::setTopGridColor(QColor _color)
{
    this->topGridColor = _color;
}

// +-------------------------------------------------------+
// | Set the bottom grid color                             |
// +-------------------------------------------------------+

void SpherePlot::setBottomGridColor(QColor _color)
{
    this->bottomGridColor = _color;
}

/***********************************************************
* Refresh                                                  *
***********************************************************/

void SpherePlot::updateGraph()
{
    this->update();
}

/***********************************************************
* OpenGL                                                   *
***********************************************************/

// +-------------------------------------------------------+
// | Draw the spheres                                      |
// +-------------------------------------------------------+

void SpherePlot::paintGL()
{

    // This is a critical section
    // Protect with a mutex
    this->blockRendering->lock();

    GLfloat p1x, p1y, p1z;
    GLfloat p2x, p2y, p2z;
    GLfloat p3x, p3y, p3z;

    GLfloat red, green, blue;
    QColor sphereColor;

    GLfloat centerX, centerY, centerZ;

    // Enable depth test, counter-clockwise face
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    // Clear the previous buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Resize if required
    if (this->resizeDone == true)
    {
        glViewport(0,0,this->width,this->height);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        GLfloat x = GLfloat(this->width) / GLfloat(this->height);
        glFrustum(-1.0*x, x, -1.0, 1.0, 4.0, 50.0);
        glMatrixMode(GL_MODELVIEW);

        // Remove flag
        this->resizeDone = false;
    }

    // Set up view
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.0,0.0,this->zoom);
    glRotatef(this->rotationX,1.0,0.0,0.0);
    glRotatef(this->rotationY,0.0,1.0,0.0);
    glRotatef(this->rotationZ,0.0,0.0,1.0);
    glLightModelf(GL_LIGHT_MODEL_AMBIENT, 1.5);

    // Create background
    glClearColor(this->backgroundColor.red()/255.0, this->backgroundColor.green()/255.0, this->backgroundColor.blue()/255.0, 1.0);

    // Draw the big sphere
    for (int indexTriangle = 0; indexTriangle < this->bigSphere->getNumberTriangles(); indexTriangle++)
    {

        glBegin(GL_LINE_LOOP);

        // Load vertices
        this->bigSphere->getTriangleVertices(indexTriangle, &p1x, &p1y, &p1z, &p2x, &p2y, &p2z, &p3x, &p3y, &p3z);

        // Setup appearance
        if (((p1z + p2z + p3z) / 3) > 0)
        {
            glColor4f(this->topGridColor.red()/255.0,this->topGridColor.green()/255.0,this->topGridColor.blue()/255.0,1.0);
        }
        else
        {
            glColor4f(this->bottomGridColor.red()/255.0,this->bottomGridColor.green()/255.0,this->bottomGridColor.blue()/255.0,1.0);
        }

        // Draw
        glVertex3f(p1x,p1y,p1z);
        glVertex3f(p2x,p2y,p2z);
        glVertex3f(p3x,p3y,p3z);

        glEnd();

    }

    // Draw the axis
    glLoadIdentity();
    glTranslatef(0.0,0.0,this->zoom);
    glRotatef(this->rotationX,1.0,0.0,0.0);
    glRotatef(this->rotationY,0.0,1.0,0.0);
    glRotatef(this->rotationZ,0.0,0.0,1.0);
    glTranslatef(-1 * this->bigSphere->getRadius(), -1 * this->bigSphere->getRadius(), -1 * this->bigSphere->getRadius());
    glColor4f(this->axesColor.red()/255.0,this->axesColor.green()/255.0,this->axesColor.blue()/255.0,1.0);

    glBegin(GL_LINES);

    // X-axis
    glVertex3f( 0.0 , 0.0 , 0.0 );
    glVertex3f( 1.0 , 0.0 , 0.0 );
    glVertex3f( 1.0 , 0.0 , 0.0 );
    glVertex3f( 0.9 , 0.05 , 0.0 );
    glVertex3f( 1.0 , 0.0 , 0.0 );
    glVertex3f( 0.9 , -0.05 , 0.0 );

    // Y-axis
    glVertex3f( 0.0 , 0.0 , 0.0 );
    glVertex3f( 0.0 , 1.0 , 0.0 );
    glVertex3f( 0.0 , 1.0 , 0.0 );
    glVertex3f( 0.05 , 0.9 , 0.0 );
    glVertex3f( 0.0 , 1.0 , 0.0 );
    glVertex3f( -0.05 , 0.9 , 0.0 );

    // Z-axis
    glVertex3f( 0.0 , 0.0 , 0.0 );
    glVertex3f( 0.0 , 0.0 , 1.0 );
    glVertex3f( 0.0 , 0.0 , 1.0 );
    glVertex3f( 0.05 , -0.05 , 0.9 );
    glVertex3f( 0.0 , 0.0 , 1.0 );
    glVertex3f( -0.05 , 0.05 , 0.9 );

    glEnd();

    // Draw the small spheres
    for (int indexSphere = 0; indexSphere < this->currentSourceManager->numberSources; indexSphere++)
    {

        // Get position of the source
        centerX = this->xPosition->at(indexSphere);
        centerY = this->yPosition->at(indexSphere);
        centerZ = this->zPosition->at(indexSphere);

        // Move to position
        glLoadIdentity();
        glTranslatef(0.0,0.0,this->zoom);
        glRotatef(this->rotationX,1.0,0.0,0.0);
        glRotatef(this->rotationY,0.0,1.0,0.0);
        glRotatef(this->rotationZ,0.0,0.0,1.0);
        glTranslatef(centerX, centerY, centerZ);

        // Draw each sphere
        for (int indexTriangle = 0; indexTriangle < this->smallSphere->getNumberTriangles(); indexTriangle++)
        {

            glBegin(GL_TRIANGLES);

            // Load vertices
            this->smallSphere->getTriangleVertices(indexTriangle, &p1x, &p1y, &p1z, &p2x, &p2y, &p2z, &p3x, &p3y, &p3z);

            // Get color of the source

            sphereColor = this->colorsToDraw->at(indexSphere);
            red = ((GLfloat) sphereColor.red()) / ((GLfloat) 255.0);
            green = ((GLfloat) sphereColor.green()) / ((GLfloat) 255.0);
            blue = ((GLfloat) sphereColor.blue()) / ((GLfloat) 255.0);

            // Setup appearance
            glColor4f(red,green,blue,0.1);

            // Draw
            glVertex3f(p1x,p1y,p1z);
            glVertex3f(p2x,p2y,p2z);
            glVertex3f(p3x,p3y,p3z);

            glEnd();

        }

    }

    // Free
    this->blockRendering->unlock();

}

// +-------------------------------------------------------+
// | Resize the widget                                     |
// +-------------------------------------------------------+

void SpherePlot::resizeGL(int _width, int _height)
{
    this->width = _width;
    this->height = _height;
    this->resizeDone = true;
}

/***********************************************************
* User interaction                                         *
***********************************************************/

// +-------------------------------------------------------+
// | Mouse is pressed                                      |
// +-------------------------------------------------------+

void SpherePlot::mousePressEvent(QMouseEvent *event)
{
    this->cursorLastPosition = event->pos();
    this->setCursor(Qt::ClosedHandCursor);
}

// +-------------------------------------------------------+
// | Mouse is released                                     |
// +-------------------------------------------------------+

void SpherePlot::mouseReleaseEvent(QMouseEvent *event)
{
    this->setCursor(Qt::OpenHandCursor);
}

// +-------------------------------------------------------+
// | Mouse is moved                                        |
// +-------------------------------------------------------+

void SpherePlot::mouseMoveEvent(QMouseEvent *event)
{
    float dx;
    float dy;

    if (event->buttons() & Qt::LeftButton)
    {

        // Compute the difference since last move
        dx = this->cursorLastPosition.x() - event->pos().x();
        dy = this->cursorLastPosition.y() - event->pos().y();

        // Increment the angle wrt the y-axis
        this->rotationZ -= dx;
        if (this->rotationZ > 360)
        {
            this->rotationZ -= 360;
        }

        // Increment the angle wrt the x-axis
        this->rotationX -= dy;
        if (this->rotationX > 360)
        {
            this->rotationX -= 360;
        }

        // Refresh the position
        this->cursorLastPosition = event->pos();

    }

}

// +-------------------------------------------------------+
// | Wheel is turned                                       |
// +-------------------------------------------------------+

void SpherePlot::wheelEvent(QWheelEvent *event)
{

    this->zoom += (event->delta() / 1000.0);

}