
    i<                    X   d dl mZ d dlmZ d dlZd dlZd dlmZmZm	Z	m
Z
mZmZmZmZmZmZmZmZmZmZmZmZmZ d dlmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlm Z  d dlm!Z! d dlm"Z" d dlm#Z# d dlm$Z$ d dlm%Z% d dlm&Z& d dlm'Z' d dl(m)Z) d dl*m+Z+  G d dee          Z,dS )    )Exchange)ImplicitAPIN)Balances
CurrenciesCurrencyIntMarketNumOrder	OrderBook	OrderSide	OrderTypeStrStringsTickerTickersTradeTradingFeesTransaction)List)ExchangeError)AuthenticationError)PermissionDenied)ArgumentsRequired)
BadRequest)InsufficientFunds)InvalidOrder)OrderNotFound)NotSupported)RateLimitExceeded)ExchangeNotAvailable)OnMaintenance)InvalidNonce)	TICK_SIZE)Precisec                       e Zd Z fdZi fdefdZi fdZi fdee         fdZ	i fdZ
d Zi fdZi fd	Zdefd
Zdi fdededefdZi fdefdZi fdefdZi fdefdZi fdedefdZd9dedefdZdi fdedefdZd9dedefdZddi fdedededee         fdZdefdZ i fde!fdZ"i fdefdZ#d9dede$fdZ%di fdede&fdZ'dddi fde&dededee$         fd Z(di fded!e)d"e*d#e+d$e,f
d%Z-di fdede&fd&Z.dddi fde&dedefd'Z/di fd(ed#e+fd)Z0d* Z1dddi fd(e&dededee2         fd+Z3d9d,e4de2fd-Z5d. Z6d9d,e4fd/Z7i fd(efd0Z8i fd(efd1Z9d2d3i ddfd4Z:d5 Z;i fd(efd6Z<d7ddi fdedededee=         fd8Z> xZ?S ):geminic           %         |                      t          t          |                                           dddgdddi dd ddd	d
dddd
dd
dd
dddd
dd
dddd
dddd
dddd
dd
i dd
dd
dd
dd
ddddddd dd!d
d"d
d#d
d$d
d%d
d&d
d'd
d(d
d)d
i d*d
d+dd,d
d-dd.dd/d
d0dd1dd2dd3d
d4d
d5d
d6d
d7d
d8d
d9dd:ddd
dd;dd
d
d
d
dd<
d=d>d>d?d@dAdBdCdDgdEdEd?d@dAg dFdGdHdIgidHdJgidHdKdKdKdKdKdKdKdKdKdKdKdKdLidMi dNdOdPdOdQdOdRdOdSdOdTdOdUdOdVdOdWdOdXdOdYdOdZdOd[dOd\dOd]dOd^dOd_dOi d`dOdadOdbdOdcdOdddOdedOdfdOdgdOdhdOdidOdjdOdkdOdldOdmdOdndOdodOdpdOdOdOdOdOdOdOdqidrt          dsdtdudvit
          t          t          t          t          t          t          t          dwdxdydzd{d|d}d~di dt
          dt
          dt
          dt
          dt
          dt
          dt
          dt          dt
          dt          dt          dt          dt          dt          dt          dt          dt
          t
          t          t          t          t          t          t          t          t          t
          t          t          t          t
          dt          t          t          ddddd
g dddddddgddKdddddddddddddddddddddid
d          S )Nr'   GeminiUSd   v1TCORSspotmarginFswapfutureoption	addMargincancelOrdercloseAllPositionsclosePositioncreateDepositAddresscreateMarketOrdercreateOrdercreateReduceOnlyOrderfetchBalancefetchBidsAsksfetchBorrowRateHistoriesfetchBorrowRateHistoryfetchClosedOrdersfetchCrossBorrowRatefetchCrossBorrowRatesfetchCurrenciesfetchDepositAddressfetchDepositAddressesByNetworkfetchDepositsWithdrawalsfetchFundingHistoryfetchFundingRatefetchFundingRateHistoryfetchFundingRatesfetchIndexOHLCVfetchIsolatedBorrowRatefetchIsolatedBorrowRatesfetchLeveragefetchLeverageTiersfetchMarginModefetchMarketsfetchMarkOHLCVfetchMyTrades
fetchOHLCVfetchOpenInterestHistoryfetchOpenOrders
fetchOrderfetchOrderBookfetchOrdersfetchPositionfetchPositionModefetchPositionsfetchPositionsRiskfetchPremiumIndexOHLCVfetchTickerfetchTickersemulated)
fetchTradesfetchTradingFeefetchTradingFeesfetchTransactionspostOnlyreduceMarginsetLeveragesetMarginModesetPositionModewithdrawzchttps://user-images.githubusercontent.com/1294454/27816857-ce7be644-6096-11e7-82d6-3c257263229c.jpgzhttps://api.gemini.comzhttps://docs.gemini.comzhttps://exchange.gemini.com)publicprivatewebwebExchangezhttps://gemini.com/z https://docs.gemini.com/rest-apizhttps://docs.sandbox.gemini.comzhttps://api.sandbox.gemini.com)z#https://gemini.com/api-fee-schedulezhttps://gemini.com/trading-feesz https://gemini.com/transfer-fees)logoapiwwwdoctestfeesget zrest-api   )z
v1/symbolszv1/symbols/details/{symbol}zv1/staking/rateszv1/pubticker/{symbol}zv2/ticker/{symbol}zv2/candles/{symbol}/{timeframe}zv1/trades/{symbol}zv1/auction/{symbol}zv1/auction/{symbol}/historyzv1/pricefeedzv1/book/{symbol}zv1/earn/ratespostzv1/staking/unstake   zv1/staking/stakezv1/staking/rewardszv1/staking/historyzv1/order/newzv1/order/cancelzv1/wrap/{symbol}zv1/order/cancel/sessionzv1/order/cancel/allzv1/order/statusz	v1/orderszv1/mytradeszv1/notionalvolumezv1/tradevolumezv1/clearing/newzv1/clearing/statuszv1/clearing/cancelzv1/clearing/confirmzv1/balanceszv1/balances/stakingzv1/notionalbalances/{currency}zv1/transferszv1/addresses/{network}zv1/deposit/{network}/newAddressz v1/deposit/{currency}/newAddresszv1/withdraw/{currency}zv1/account/transfer/{currency}zv1/payments/addbankzv1/payments/methodszv1/payments/sen/withdrawzv1/balances/earnzv1/earn/interestzv1/earn/historyz&v1/approvedAddresses/{network}/request)z&v1/approvedAddresses/account/{network}z%v1/approvedAddresses/{network}/removez
v1/accountzv1/account/createzv1/account/listzv1/heartbeat)rn   rm   rk   rl   tradinggMbp?gMb`?)takermaker)4004034044064295005025031m5m15m30m1hr6hr1day)r   r   r   r   1h6h1dAuctionNotOpenClientOrderIdTooLongClientOrderIdMustBeStringConflictingOptionsEndpointMismatchEndpointNotFoundIneligibleTimingr   InvalidJsonr#   InvalidApiKeyInvalidOrderTypeInvalidPriceInvalidQuantityInvalidSideInvalidSignatureInvalidSymbol)InvalidTimestampInPayloadMaintenanceMarketNotOpenMissingApikeyHeaderMissingOrderFieldMissingRoleMissingPayloadHeaderMissingSignatureHeaderNoSSLOptionsMustBeArrayr   	RateLimitSystemUnsupportedOption)z8The Gemini Exchange is currently undergoing maintenance.z?We are investigating technical issues with the Gemini Exchange.zInternal Server Error)exactbroadfetch_markets_from_api
   )USDTGUSDUSDDAIEURGBPSGDBTCETHLTCBCH)fetchDetailsForAllSymbolsquoteCurrencies)webApiEnablewebApiRetriesbtcusdtethusdt)r   r   webApiMuteFailurefetchTickerV1bitcoinethereumbitcoincashlitecoinzcashfilecoindogecointezos	avalanchesolanacosmospolkadot)r   ERC20r   r   ZECFILDOGEXTZAVAXXSOLATOMDOTmillisecondspaxgusdPAXGr   )basequote)
fetchMarketsMethodfetchMarketFromWebRetriesfetchMarketsFromAPIrP   fetchUsdtMarketsrB   fetchTickerMethodnetworksnonceconflictingMarkets)idname	countries	rateLimitversionprohasurlsrp   precisionModert   httpExceptions
timeframes
exceptionsoptions)deep_extendsuperr'   describer$   r   r   r   r   r    r   r!   r"   r#   r   r   )self	__class__s    _/var/www/html/crypto-bot/backend/venv/lib/python3.11/site-packages/ccxt/async_support/gemini.pyr   zgemini.describe   s
   fd 3 3 < < > > >>> %> 	>
 %> %> U> t> $U>  > '> $U> t> (> >   !>" +E#> >$ )%%>& $U'>( ')>* (+>, "4->. &t/>0 1$1>2 +D3>4 &u5>6 #E7>8 *59>: $U;>< "5=>> *5?>@ +EA>B  C>D %eE> > >F "5G>H I>J !%K>L  M>N dO>P +EQ>R "4S>T dU>V !$W>X uY>Z  [>\ $U]>^ !%_>` %ea>b )%c>d te>f g> >h  $#($(%/  %$!&#( {> > >@ ~674#@	  -65
 ??
 5#@	 	  / >   " &'78,-12./;<.//078(),-)* "  ),a)*A) -a) -a	)
 ') *1) +A) 21) .q) *1) $Q) &q) ,Q) )!) *1)  -a!)" -a#) )$ .q%)& &q')( .q))* 9!+), '-). 1!/)0 :11)2 ;A3)4 1!5)6 9!7)8 .q9): .q;)< 3A=)> +A?)@ +AA)B *1C)D A!E) )F CDAB&'-.+,()Q) ) )+7G GP '""  "'$(($+$	 	   $j *J  0  )*	 
 '
  '
  '
  ():  ":  #L  $%8  '  #L  &|  "<   '(;! " $Z# $ 2<#0%1+>)5#6,?.A0*4%2!2+)3?     D Q^Wk-A E' 'R '?-/16'v'v'v( (
 %)%'! ! &/	$:$(%&)-$ $
 &5$'(%"%&"(#$%  ( &!&   'C' '_WA
 WA
 W W W	    returnc                 <   K   |                      |           d{V S )z
        fetches all available currencies on an exchange
        :param dict [params]: extra parameters specific to the endpoint
        :returns dict: an associative dictionary of currencies
        N)fetch_currencies_from_web)r   paramss     r   fetch_currencieszgemini.fetch_currencies9  s.       33F;;;;;;;;;r   c                   K   |                      ddddd           d{V }|dS i }|                     |d          | j        d<   |                     |dg           }t	          d	t          |                    D ]}||         }|                     |d	          }|                     |          }|                     |d
          rdnd}	|                     | 	                    |                     |d                              }
i }|                     |d          }d}|| 
                    |          }||||dddd|
dddddddd	||<   ||||                     |d          dddd|	|
ddddddd|d||<   |S )z
         * @ignore
        fetches all available currencies on an exchange
        :param dict [params]: extra parameters specific to the endpoint
        :returns dict: an associative dictionary of currencies
        rB   webExchangeGetTz="currencyData">z	</script>NtradingPairs
currenciesr      fiatcryptorw   	   minmax)depositrj   )	infor   networkactiver  rj   fee	precisionlimitsry   )r	  r   coder   r  r  rj   r  typer  r  r   )fetch_web_endpoint	safe_listr   
safe_valuerangelensafe_stringsafe_currency_codeparse_numberparse_precisionnetwork_id_to_code)r   r   dataresultcurrenciesArrayicurrencyr   r  r  r  r   	networkIdnetworkCodes                 r   r   z gemini.fetch_currencies_from_webA  s/      ,,->@PRVXjlwxxxxxxxx<4* '+~~dN'K'K^$//$bAAq#o..// 6	 6	A&q)H!!(A..B**2..D!--h::H66D))$*>*>t?O?OPXZ[?\?\*]*]^^IH((155IK$"55i@@&$#*"# $!* $(#'$ $
 $(#'% %	 	) )%* !((155 &  $#   
  $#! !	 	 %+ F4LL. r   c                   K   |                      | j        dd          }|dk    rg }|                    |                     |                     |                    |                     |                     t          j        |  d{V }|                     |d         |d                   S |                     |           d{V S )a  
        retrieves data on all markets for gemini
        :see: https://docs.gemini.com/rest-api/#symbols
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict[]: an array of objects representing market data
        r   r   fetch_markets_from_webNr   ry   )	r  r   appendr#  fetch_usdt_marketsasynciogatherarray_concatr   )r   r   methodpromisespromisesResults        r   fetch_marketszgemini.fetch_markets  s       /CE]^^---HOOD77??@@@OOD33F;;<<<#*>8#<<<<<<<N$$^A%6q8IJJJ00888888888r   c                   K   |                      dddd           d {V }| j        dz   }|                    d          }t          |          }|dk     rt	          |          |d                             d	          }t          |          }|dk     rt	          |          g }t          d|          D ]A}	||	         }
|
                    d
          }t          |          }|dk     rt	          |          |d                             dd          }|                    dd          }|d                             dd          }|                    d          }|                     |d          }|d                             dd          }|                    d          }t          |          dz
  }|dz
  }|d                             dd          }|                    d          }|                     |d|||                   }|                     |d|                    |d                    }| 	                    |          }| 	                    |          }|
                    i d|d|dz   |z   d|d|dd d|d|dd ddddddddd dd!dd"d d#dd$d d d d d d d |                     |d          |                     |d          d%d d d&|d d&d d d&d d d&d'd |
d(
           C|S ))NrP   webGetRestApiFz7<h1 id="symbols-and-minimums">Symbols and minimums</h1>z fetchMarketsFromWeb() the API doc HTML markup has changed, breaking the parser of order limits and precision info for markets.ztbody>   ry   z
<tr>
z</td>
rw   r   z<td>rv   *    r   symbol/r   r   settlebaseIdquoteIdsettleIdr  r.   Tr/   r0   r1   r2   r  contractlinear)amountpricer  leverager;  r<  cost
inversecontractSizeexpiryexpiryDatetimestrike
optionTyper  r  createdr	  )r  r   splitr  r   r  replacesafe_numbersafe_string_lowerr  r$  )r   r   r  errortables	numTablesrowsnumRowsr  r  rowcellsnumCellsmarketIdminAmountStringminAmountParts	minAmountamountPrecisionStringamountPrecisionPartsidLengthstartingIndexpricePrecisionStringpricePrecisionPartsr7  r6  r   r   s                              r   r#  zgemini.fetch_markets_from_web  s)     ,,^_e  VO  P  P  P  P  P  P  P  P  \  \H%%KK	q==u%%%ayz**d))Q;;u%%%q'"" M	 M	Aq'CIIi((E5zzH!||"5))) Qx''33H''R00H#Ah..vr::O,22377N((;;I$)!H$4$4VR$@$@!#8#>#>s#C#C 8}}q(H$qLM#(8#3#3FB#?#? "6"<"<S"A"A,,-@!Xm\dNdEeffG++,@!XEUEUV]_aEbEbccF**622D++G44EMM 0h0$*u,0 0 	0
 $0 &0 70 D0 0 0 %0 0 %0 %0 $0  E!0" $#0$   $"&""../CQGG!--.A1EE   $#! !
  )# 
  $# 
  $#  $  _0 0 0 0 0 0 0b r   c                 H    dddddd}|dS |                      ||d          S )NTF)openclosedcancel_only	post_only
limit_only)	safe_boolr   statusstatusess      r   parse_market_activezgemini.parse_market_active  s?    
 
 >4~~h555r   c                 b  K   d| j         v rg S |                     | j        dg           }g }t          dt	          |                    D ]e}||         }d|i}|                     |                     ||                     d {V }|                    |                     |                     f|S )Nrs   r   r   r3  )	r   r  r   r  r  publicGetV1SymbolsDetailsSymbolextendr$  parse_market)r   r   r   r  r  rT  requestrawResponses           r   r%  zgemini.fetch_usdt_markets  s       TYI??4<9KRPPq#.//00 	: 	:A'*H(G !% D DT[[QXZ`EaEa b bbbbbbbKMM$++K889999r   c           	        K   |                      |           d {V }g }|                     | j        di           }d}g }t          dt	          |                    D ])}||         |k    r|                    ||                    *|                     |dd          rg }t          dt	          |                    D ]J}||         }	d|	i}
|                    |                     |                     |
|                               Kt          j
        |  d {V }t          dt	          |                    D ]0}|                    |                     ||                              1n|                     | j        d          }||                     |d          }t          dt	          |                    D ]\}||         }	|                     ||	                                          }|(|                    |                     |                     ]nNt          dt	          |                    D ]0}|                    |                     ||                              1|S )Nr   efilfilr   r   Fr3  r   )publicGetV1Symbols	safe_dictr   r  r  r$  rd  rj  rk  r&  r'  rl  r  index_byupper)r   r   marketIdsRawr  r   	bugSymbol	marketIdsr  r*  rT  rm  	responsesr   indexedTradingPairstradingPairs                  r   r   zgemini.fetch_markets_from_api%  s     !44V<<<<<<<< ../DbII		q#l++,, 	2 	2AA)++  a111>>'#>FF #	CH1c)nn-- d d$Q<h  D DT[[QXZ`EaEa b bcccc &nh7777777I1c)nn-- ? ?d//	!==>>>>?  >>$,GGL'&*mmL!&D&D#q#i..11 F FA(|H"&..1DhnnFVFV"W"WK".d&7&7&D&DEEE	F q#i..11 C CAMM$"3"3IaL"A"ABBBBr   c                     d }d }d }d }d }d }d }d }	d}
d }d }d }t          |t                    }t          |t                    }|s|s|                     |d          }|                     |d          }|                     |d          }|                     |d          }|                     |                     |d                    }	|                     |d          }|                     |d          }|                     |d	          }n|r|}n|                     |d
          }|                     |                     |                     |d                              }|                     |                     |                     |d                              }|                     |d          }|	                                }|
                    d          d
k    }|                    dd          }|                     | j        di           }|                                }||v r#||         }|d         }|d         }|r|d         }n|                     ddg           }t!          d
t#          |                    D ]V}||         }|                    |          r7|                     dt#          |          z            }|d
|         }|}|r|} nW|                     |          }|                     |          }|                     |          }|dz   |z   }||dz   |z   }d}
|}d}d}|
rdnd}i d|d|d|d|d|d|d|d|d |d|
 d!dd|
d"dd#dd$|	d%|
d&|||d d d d ||d'd d d(|d d(d d d(d d d(d)d |d*
S )+NFr3  	tick_sizequote_incrementmin_order_sizerf  base_currencyquote_currencycontract_price_currencyr   ry   r/  r2  PERPrv   r   r   r   r   r   r4  :Tr0   r.   r   r5  r6  r7  r8  r  r/   r1   r2   r  r9  r:  )r<  r;  r  r=  r@  )
isinstancestrlistrK  rJ  rh  r  r  r  rt  findrI  rr  r   lowerhandle_optionr  r  endswithparse_to_intr  )r   responserT  r6  r7  r8  tickSizeamountPrecisionminSizerf  r0   rB  r:  rA  isStringisArraymarketIdUpperisPerpmarketIdWithoutPerpr   lowerCaseIdconflictingMarketr   r  quoteCurrencyquoteLengthr   r   r5  r3  r  s                                  r   rl  zgemini.parse_market[  s   B x--h-- '	 '	--hAAH"..xEEO''2CDDH&&x1ABBG--d.>.>x.R.RSSF%%h@@F&&x1ABBG''2KLLHH  8#11(A>>,,T-A-A$BRBRS[]^B_B_-`-`aa"&"3"3D4H4HIYIYZbdeIfIf4g4g"h"h**8Q77$NN,,M#((00A5F"/"7"7"C"C!%>RTV!W!W-3355K000$6{$C!*62+G4 :09H"&"4"45JL]_a"b"bq#o"6"677  A$3A$6M*33MBB &*&7&7S=O=O8O&P&P!4Q{]!C"/! 5'4H &&v..''00((22e#c\F*FD#LFG)vv60
(0
f0
 D0
 U	0

 f0
 f0
 w0
 0
 D0
 H0
 e0
 D0
 e0
 e0
 f0
  !0
" f#0
$ ("!)    
 # 
   
    $ _0
 0
 0
 0	
r   Nr3  limitc           	      0  K   |                                   d{V  |                     |          }d|d         i}|
||d<   ||d<   |                     |                     ||                     d{V }|                     ||d         ddddd	          S )
a6  
        fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
        :see: https://docs.gemini.com/rest-api/#current-order-book
        :param str symbol: unified symbol of the market to fetch the order book for
        :param int [limit]: the maximum amount of order book entries to return
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
        Nr3  r   
limit_bids
limit_asksbidsasksr<  r;  )load_marketsmarketpublicGetV1BookSymbolrk  parse_order_book)r   r3  r  r   r  rm  r  s          r   fetch_order_bookzgemini.fetch_order_book  s       !!!!!!!!!V$$fTl
 $)GL!$)GL!33DKK4P4PQQQQQQQQ$$Xvh/?vvW^`hiiir   c                   K   |                                   d {V  |                     |          }d|d         i}|                     |                     ||                     d {V }|                     ||          S Nr3  r   )r  r  publicGetV1PubtickerSymbolrk  parse_tickerr   r3  r   r  rm  r  s         r   fetch_ticker_v1zgemini.fetch_ticker_v1  s      !!!!!!!!!V$$fTl
 88Wf9U9UVVVVVVVV   6222r   c                   K   |                                   d {V  |                     |          }d|d         i}|                     |                     ||                     d {V }|                     ||          S r  )r  r  publicGetV2TickerSymbolrk  r  r  s         r   fetch_ticker_v2zgemini.fetch_ticker_v2  s      !!!!!!!!!V$$fTl
 55dkk'66R6RSSSSSSSS   6222r   c                   K   |                      ||           d {V }|                     ||           d {V }|                     ||d         |d         |d         |d         |d         |d         |d         d          S )	Nr_  highlowchange
percentageaverager	  )r_  r  r  r  r  r  r	  )r  r  r   )r   r3  r   tickerAtickerBs        r   fetch_ticker_v1_and_v2zgemini.fetch_ticker_v1_and_v2.  s      ,,VV<<<<<<<<,,VV<<<<<<<<FOFO5>h'!,/y)FO*
 *
   	r   c                    K   |                      | j        dd          }|dk    r|                     ||           d{V S |dk    r|                     ||           d{V S |                     ||           d{V S )a  
        fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
        :see: https://docs.gemini.com/rest-api/#ticker
        :see: https://docs.gemini.com/rest-api/#ticker-v2
        :param str symbol: unified symbol of the market to fetch the ticker for
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :param dict [params.fetchTickerMethod]: 'fetchTickerV2', 'fetchTickerV1' or 'fetchTickerV1AndV2' - 'fetchTickerV1' for original ccxt.gemini.fetch_ticker- 'fetchTickerV1AndV2' for 2 api calls to get the result of both fetchTicker methods - default = 'fetchTickerV1'
        :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
        r   r   NfetchTickerV2)r  r   r  r  r  )r   r3  r   r)  s       r   fetch_tickerzgemini.fetch_ticker;  s       /BOTT_$$--ff=========_$$--ff=========00@@@@@@@@@r   r  c                    |                      |di           }|                     |d          }d }|                     |d          }|                     ||          }d }d }d }	d }
|u|st	          |          dz
  }|dk    r|dd         }|dd         }n|dd         }|dd         }|                     |          }	|                     |          }
|	d	z   |
z   }|6|4|d
         }|                     |d          }|                     |d          }|                     |d          }|                     |dd|          }|                     |d          }|                     |d          }|                     ||          }|                     ||          }| 	                    i d
|d|d| 
                    |          d|                     |d          d|                     |d          d|                     |d          dd d|                     |d          dd dd d|d|d|dd dd d|dd |||d|          S )Nvolume	timestamppairr   r     r2     r4  r3  r6  r7  r<  lastclosepercentChange24hr_  datetimer  r  bid	bidVolumeask	askVolumevwappreviousCloser  r  r  )
baseVolumequoteVolumer	  )r  safe_integerrK  safe_marketr  r  safe_string_upperr  safe_string_2safe_tickeriso8601)r   tickerr  r  r  r3  rT  r6  r7  r   r   rZ  r<  r  r  r_  r  r  s                     r   r  zgemini.parse_tickerL  s   J 266%%fk::	))&&99!!(F33 v~8}}q(H1}}!!A#"1Q3-!!A#"1Q3-**622D++G44ECZ%'FN!3H%F++FH==F,,VY??G  11!!&&'5AA%%f.@AA
//%%ff55
&&vw77 !
f!
!
 Y//!
 D$$VV44	!

 4##FE22!
 4##FE22!
 !
 4##FE22!
 !
 D!
 D!
 T!
 D!
 T!
 d!
  *!!
" t#!
$ %&)!
 !
 !
* +  	r   symbolsc                    K   |                                   d{V  |                     |           d{V }|                     ||          S )a  
        fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
        :see: https://docs.gemini.com/rest-api/#price-feed
        :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
        N)r  publicGetV1Pricefeedparse_tickers)r   r  r   r  s       r   fetch_tickerszgemini.fetch_tickers  si       !!!!!!!!!226:::::::: !!(G444r   c                 ,   |                      |d          }|                     |d          }|                     |d          }|                     |d          }|                     |          }|                     |d          |d}|                     |d          }	|                     |d          }
|                     |d	          }|                     d |          }|                     |||||                     |          |d |d |	d |
|d
|          S )Ntimestampmstidorder_idfee_currency
fee_amountr?  r  r<  r;  r  )r   orderr	  r  r  r3  r  sidetakerOrMakerr<  r?  r;  r  )r  r  r  rK  safe_symbol
safe_trader  )r   trader  r  r   orderIdfeeCurrencyIdfeeCurrencyCoder  priceStringamountStringr  r3  s                r   parse_tradezgemini.parse_trade  s<   D %%e];;	eU++""5*55((??11-@@$$UL99'
 
 &&ug66''x88%%eV44!!$//"Y//  " 
  
   	r   sincec                 >  K   |                                   d{V  |                     |          }d|d         i}|t          |d          |d<   |||d<   |                     |                     ||                     d{V }|                     ||||          S )a  
        get the list of most recent trades for a particular symbol
        :see: https://docs.gemini.com/rest-api/#trade-history
        :param str symbol: unified symbol of the market to fetch trades for
        :param int [since]: timestamp in ms of the earliest trade to fetch
        :param int [limit]: the maximum amount of trades to fetch
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
        Nr3  r   i  limit_tradesr  )r  r  r  publicGetV1TradesSymbolrk  parse_tradesr   r3  r  r  r   r  rm  r  s           r   fetch_tradeszgemini.fetch_trades  s       !!!!!!!!!V$$fTl
 &)%ooGN##(GK 55dkk'66R6RSSSSSSSS   65%@@@r   c                 p   d|i}t          dt          |                    D ]}||         }|                     |d          }|                     |          }|                                 }|                     |d          |d<   |                     |d          |d<   |||<   |                     |          S )Nr	  r   r  	availablefreer;  total)r  r  r  r  accountsafe_balance)r   r  r  r  balance
currencyIdr  r  s           r   parse_balancezgemini.parse_balance"  s    (#q#h--(( 	# 	#AqkG))':>>J**:66DllnnG"..wDDGFO#//BBGG"F4LL  (((r   c                   K   |                                   d{V  |                     |           d{V }|                     |d          }|                     |d          }t          j        |d          }t          j        |d          }|                     |          }|                     |          }i }	t          dt          | j                            D ]}
| j        |
         }||||ddd|	|<   |	S )aT  
        fetch the trading fees for multiple markets
        :see: https://docs.gemini.com/rest-api/#get-notional-volume
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
        Napi_maker_fee_bpsapi_taker_fee_bps10000r   T)r	  r3  r|   r{   r  	tierBased)	r  privatePostV1Notionalvolumer  r%   
string_divr  r  r  r  )r   r   r  makerBpstakerBpsmakerStringtakerStringr|   r{   r  r  r3  s               r   fetch_trading_feeszgemini.fetch_trading_fees.  s'      !!!!!!!!!99&AAAAAAAA: ##H.ABB##H.ABB(7;;(7;;!!+..!!+..q#dl++,, 		 		A\!_F  "! F6NN r   c                    K   |                                   d{V  |                     |           d{V }|                     |          S )ah  
        query for balance and get the amount of funds available for trading or funds locked in orders
        :see: https://docs.gemini.com/rest-api/#get-available-balances
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
        N)r  privatePostV1Balancesr  )r   r   r  s      r   fetch_balancezgemini.fetch_balancef  se       !!!!!!!!!33F;;;;;;;;!!(+++r   c           	         |                      |d          }|                     |d          }|                     |d          }|                     |d          }d}|d         rd}|d         rd	}|                     |d
          }|                     |d          }	|                     |d          }
|
dk    rd}
n|
dk    s|
dk    rd}
n|d         }
d }|                     |d          }|                     ||          }|                     |d          }|                     |d          }|                     |d          }|                     |dg           }|                     |d          }d}d}||dk    rd}n|dk    rd}n
|dk    rd}d }|                     i d!|d"|d#|d$|d%|                     |          d&d d'|d|d|
d(|d)|d|d
|d*d d+d d,|	d-d ||||d d.|          S )/Nr  original_amountremaining_amountexecuted_amountr`  is_liver_  is_cancelledcanceledr<  avg_execution_pricer  exchange limitr  z
market buyzmarket sellr  r3  r  r  client_order_idr   r   GTCFimmediate-or-cancelIOCfill-or-killFOKmaker-or-cancelPOTr   clientOrderIdr	  r  r  lastTradeTimestamprf  timeInForcere   	stopPricetriggerPricer  r?  )r;  filled	remainingr  trades)r  r  r  rK  r  
safe_orderr  )r   r  r  r  r;  r!  r   rf  r<  r  r  r  rT  r3  r   r  r  optionsArrayr2   r  re   s                        r   parse_orderzgemini.parse_orderq  s   F %%e];;	!!%):;;$$U,>??	!!%):;; 	F  	 F  00""5*?@@v..###DD\!!T]%:%:DD=D##E844!!(F33eZ00%%eV44((0ABBui<<!!,22...#>))#,,,"  
" 
] 
 E 
 	 

 Y// 
 !$ 
 f 
 f 
 D 
 ; 
  
 D 
 U 
  
 D 
  w! 
" D# 
$ "- 
  
  
. /  	r   r   c                    K   |                                   d{V  d|i}|                     |                     ||                     d{V }|                     |          S )a|  
        fetches information on an order made by the user
        :see: https://docs.gemini.com/rest-api/#order-status
        :param str symbol: unified symbol of the market the order was made in
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
        Nr  )r  privatePostV1OrderStatusrk  r%  r   r   r3  r   rm  r  s         r   fetch_orderzgemini.fetch_order  s       !!!!!!!!!
 66t{{7F7S7STTTTTTTT0 )))r   c                    K   |                                   d{V  |                     |           d{V }d}||                     |          }|                     ||||          S )a
  
        fetch all unfilled currently open orders
        :see: https://docs.gemini.com/rest-api/#get-active-orders
        :param str symbol: unified market symbol
        :param int [since]: the earliest time in ms to fetch open orders for
        :param int [limit]: the maximum number of  open orders structures to retrieve
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
        N)r  privatePostV1Ordersr  parse_orders)r   r3  r  r  r   r  r  s          r   fetch_open_orderszgemini.fetch_open_orders7  s       !!!!!!!!!11&999999994 [[((F  65%@@@r   r  r  r;  r<  c                   K   |                                   d{V  |dk    rt          | j        dz             |                     |dd          }|                     |ddg          }|!t          |                                           }|                     |          }|                     ||          }	| 	                    ||          }
||d         |	|
|dd}| 
                    |d	|          }|                     |d	          }|                     |d
d          }|                     |g d          }|dk    rt          | j        dz   |z   dz             || 	                    ||          |d
<   d|d	<   n| 
                    |d          }|                     |d          }|2|dk    s|dk    rdg|d<   n|dk    s|dk    rdg|d<   n|dk    rdg|d<   |                     |dd          }|                     |d          }|rdg|d<   | 
                    |d          }||g|d<   |                     |                     ||                     d{V }|                     |          S )a  
        create a trade order
        :see: https://docs.gemini.com/rest-api/#new-order
        :param str symbol: unified symbol of the market to create an order in
        :param str type: must be 'limit'
        :param str side: 'buy' or 'sell'
        :param float amount: how much of currency you want to trade in units of base currency
        :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
        Nr  z' createOrder() allows limit orders onlyr  r  r   r  )r  r3  r;  r<  r  r  r  
stop_pricer  )r/  r  r  	stopLimitzL createOrder() requires a stopPrice parameter or a stop_price parameter for z orderszexchange stop limitr  r  r  r   r  r  r  r  re   F)r  r   r   r  omitr  r   r  amount_to_precisionprice_to_precisionr  r   rd  privatePostV1OrderNewrk  r%  )r   r3  r  r  r;  r<  r   r  r  r  r  rm  rawStopPricer  re   r   r  s                    r   create_orderzgemini.create_ordera  s      !!!!!!!!!7??*S STTT**6?DUVV6O5F#GHH  1 1 3 344MV$$//??--fe<<,Tl" $
 
 5566**))&,LL6#F#F#FGG;#DG.|$|  @D  %D  GP  %P  Q  Q  Q#$($;$;FL$Q$QGL!3GFOO **6=AAKYYv}55F&5((k=R.R.R*?)@GI&&!U**~0M0M*8)9GI&& D((*;)<GI&~~fj%@@HYYvz22F 9&7%8	"&&vy99G"&-Y	"33DKK4P4PQQQQQQQQ0 )))r   c                    K   |                                   d{V  d|i}|                     |                     ||                     d{V }|                     |          S )a  
        cancels an open order
        :see: https://docs.gemini.com/rest-api/#cancel-order
        :param str id: order id
        :param str symbol: unified symbol of the market the order was made in
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
        Nr  )r  privatePostV1OrderCancelrk  r%  r(  s         r   cancel_orderzgemini.cancel_order  s       !!!!!!!!!
 66t{{7F7S7STTTTTTTT2 )))r   c                   K   |t          | j        dz             |                                  d{V  |                     |          }d|d         i}|||d<   ||                     |dz            |d<   |                     |                     ||                     d{V }|                     ||||          S )a  
        fetch all trades made by the user
        :see: https://docs.gemini.com/rest-api/#get-past-trades
        :param str symbol: unified market symbol
        :param int [since]: the earliest time in ms to fetch trades for
        :param int [limit]: the maximum number of trades structures to retrieve
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
        Nz+ fetchMyTrades() requires a symbol argumentr3  r   r  i  r  )r   r   r  r  r  privatePostV1Mytradesrk  r  r  s           r   fetch_my_tradeszgemini.fetch_my_trades  s       >#DG.[$[\\\!!!!!!!!!V$$fTl
 &+GN##'#4#4UT\#B#BGK 33DKK4P4PQQQQQQQQ  65%@@@r   r  c                   K   |                      ||          \  }}|                     |           |                                  d{V  |                     |          }|d         ||d}|                     |                     ||                     d{V }|                     |d          }	|	dk    r-t          | j        dz   | 	                    |          z             | 
                    ||          S )a  
        make a withdrawal
        :see: https://docs.gemini.com/rest-api/#withdraw-crypto-funds
        :param str code: unified currency code
        :param float amount: the amount to withdraw
        :param str address: the address to withdraw to
        :param str tag:
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
        Nr   )r  r;  addressr  rL  z withdraw() failed: )handle_withdraw_tag_and_paramscheck_addressr  r  privatePostV1WithdrawCurrencyrk  r  r   r   jsonparse_transaction)
r   r  r;  r>  tagr   r  rm  r  r  s
             r   rj   zgemini.withdraw  s      99#vFFV7###!!!!!!!!!==&& 
 

 ;;DKKQW<X<XYYYYYYYY0 !!(H55W*@ @499XCVCV VWWW%%h999r   c                     |                      | j        dd          }|dk    r|                                 S |                                 S )Nr   r   )r  r   r   seconds)r   nonceMethods     r   r   zgemini.nonce'  sF    &&t|WnMM.(($$&&&||~~r   c                    K   |                                   d{V  i }|||d<   |||d<   |                     |                     ||                     d{V }|                     |          S )a^  
        fetch history of deposits and withdrawals
        :see: https://docs.gemini.com/rest-api/#transfers
        :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
        :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
        :param int [limit]: max number of deposit/withdrawals to return, default is None
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
        Nlimit_transfersr  )r  privatePostV1Transfersrk  parse_transactions)r   r  r  r  r   rm  r  s          r   fetch_deposits_withdrawalsz!gemini.fetch_deposits_withdrawals-  s       !!!!!!!!!).G%&#(GK 44T[[&5Q5QRRRRRRRR&&x000r   r  c                    |                      |d          }|                     |d          }|                     ||          }|                     |d          }|                     |d          }|                     |d          }d }	|                     |d          }
|
|
|d}	i d|d	|                     |d
d          d|                     |d          d|d|                     |          dd d|dd dd dd dd dd d|d|                     |d          d|d|                     |          dd d |                     |d          |	dS )Nr  r  destinationr  rf  	feeAmountr  r	  r   eidwithdrawalIdtxidtxHashr  r  r
  r>  	addressToaddressFromrD  tagTotagFromr;  updatedmessage)internalcommentr  )r  r  r  rK  rJ  r  r  parse_transaction_status)r   transactionr  r  r  r  r>  r  	statusRawr  rO  s              r   rC  zgemini.parse_transaction@  s   & %%k=AA	%%k:>>
&&z8<<"";>>%%k6::$$[(;;	$$[+>>	 !  C
K
$$$[%HH
 D$$[(;;
 	

 Y//
 t
 w
 
 4
 4
 T
 t
 D
 d&&{H==
 
  d33I>>!
" t#
$ ''Y??)
 
 
 	
r   c                 :    ddd}|                      |||          S )Nok)AdvancedComplete)r  re  s      r   r\  zgemini.parse_transaction_statusx  s.    
 
 &&999r   c                 j    |                      |d          }|                     d |          }|d |d |dS )Nr>  )r  r
  r>  rD  r	  )r  r  )r   depositAddressr  r>  r  s        r   parse_deposit_addresszgemini.parse_deposit_address  sL     "">9==&&tX66"
 
 	
r   c                 &  K   |                                   d{V  |                     ||           d{V }d}|                     |          \  }}|                     |                     ||          d          }|                     ||          S )a  
        :see: https://docs.gemini.com/rest-api/#get-deposit-addresses
        fetch the deposit address for a currency associated with self account
        :param str code: unified currency code
        :param dict [params]: extra parameters specific to the endpoint
        :param str [params.network]:  *required* The chain of currency
        :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
        Nr  )r  "fetch_deposit_addresses_by_networkhandle_network_code_and_paramsrs  r  )r   r  r   groupedByNetworkr!  networkGroups         r   fetch_deposit_addresszgemini.fetch_deposit_address  s       !!!!!!!!!!%!H!Hv!V!VVVVVVV"AA&IIV}}T__5E{%S%SU_``|T222r   c                   K   |                                   d{V  |                     |          }|d         }d}|                     |          \  }}|t          | j        dz             |                     |          }d|i}|                     |                     ||                     d{V }|                     ||gd||d          }| 	                    |d          S )a  
        fetch a dictionary of addresses for a currency, indexed by network
        :see: https://docs.gemini.com/rest-api/#get-deposit-addresses
        :param str code: unified currency code of the currency for the deposit address
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :param str [params.network]:  *required* The chain of currency
        :returns dict: a dictionary of `address structures <https://docs.ccxt.com/#/?id=address-structure>` indexed by the network
        Nr  z5 fetchDepositAddresses() requires a network parameterr
  F)r
  r  )
r  r  rh  r   r   network_code_to_idprivatePostV1AddressesNetworkrk  parse_deposit_addressesgroup_by)	r   r  r   r  r!  r   rm  r  resultss	            r   rg  z)gemini.fetch_deposit_addresses_by_network  s      !!!!!!!!!==&&"AA&IIV#DG.e$efff++K88	y
 ;;DKKQW<X<XYYYYYYYY..x$T_mqHrHrss}}Wi000r   rk   GETc                 Z   d|                      ||          z   }|                     ||                     |                    }|dk    r|                                  | j        }	|	                    d          dk     rt          | j        dz             t          | 	                                          }
| 
                    ||
d|          }|                     |          }|                     |          }|                     |                     |          |                     | j                  t           j                  }d| j        ||d}n|r|d	|                     |          z   z  }| j        d
         |         |z   }|dk    s|dk    r|                     |          }||||dS )Nr4  rl   r  r   z> sign() requires an account-key, master-keys are not-supported)rm  r   z
text/plain)zContent-TypezX-GEMINI-APIKEYzX-GEMINI-PAYLOADzX-GEMINI-SIGNATURE?rp   POSTDELETE)urlr)  bodyheaders)implode_paramsr1  extract_paramscheck_required_credentialsapiKeyr  r   r   r  r   rk  rB  string_to_base64hmacencodesecrethashlibsha384	urlencoder   )r   pathrp   r)  r   ry  rx  rw  queryr}  r   rm  payload	signatures                 r   signzgemini.sign  s   D''f555		&$"5"5d";";<<)++---[F{{9%%)))$'4t*tuuu

%%Ekk# #  G ii((G++G44G		$++g"6"6DK8P8PRYR`aaI ,#';$+&/	 GG  3sT^^E2222is#c)f&H"4"499U##DfdwOOOr   c
                 *   |Ft          |t                    r/| j        dz   |z   }
|                     | j        d         ||
           d S |                     |d          }|dk    r|                     |d          }|                     |d          }| j        dz   |z   }
|                     | j        d         ||
           |                     | j        d         ||
           |                     | j        d         ||
           t          |
          d S )Nr1  r   r  rL  reasonrY  r   )r  r  r   throw_broadly_matched_exceptionr   r  throw_exactly_matched_exceptionr   )r   httpCoder  rw  r)  ry  rx  r  requestHeadersrequestBodyfeedbackr  reasonInnerrY  s                 r   handle_errorszgemini.handle_errors  s   $$$ _7S=4/44T_W5MtU]^^^4 !!(H55W**8X>>K&&x;;Gw}w.H001I;X`aaa001I7T\]]]001I7T\]]])))tr   c                 :  K   |                                   d{V  |                     |          }d|d         i}|                     |                     ||                     d{V }|                     |d          }|                     |           ||d|dS )a  
        create a currency deposit address
        :see: https://docs.gemini.com/rest-api/#new-deposit-address
        :param str code: unified currency code of the currency for the deposit address
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
        Nr  r   r>  )r  r>  rD  r	  )r  r  &privatePostV1DepositCurrencyNewAddressrk  r  r@  )r   r  r   r  rm  r  r>  s          r   create_deposit_addresszgemini.create_deposit_address  s       !!!!!!!!!==&&
 DDT[[QXZ`EaEabbbbbbbb""8Y777###	
 
 	
r   r   c                 B  K   |                                   d{V  |                     |          }|                     | j        ||          }||d         d}|                     |                     ||                     d{V }	|                     |	||||          S )a  
        fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
        :see: https://docs.gemini.com/rest-api/#candles
        :param str symbol: unified symbol of the market to fetch OHLCV data for
        :param str timeframe: the length of time each candle represents
        :param int [since]: timestamp in ms of the earliest candle to fetch
        :param int [limit]: the maximum amount of candles to fetch
        :param dict [params]: extra parameters specific to the exchange API endpoint
        :returns int[][]: A list of candles ordered, open, high, low, close, volume
        Nr   )	timeframer3  )r  r  r  r   !publicGetV2CandlesSymbolTimeframerk  parse_ohlcvs)
r   r3  r  r  r  r   r  timeframeIdrm  r  s
             r   fetch_ohlcvzgemini.fetch_ohlcv  s       !!!!!!!!!V$$&&t	9MM$Tl
 
 ??GU[@\@\]]]]]]]]   69eUKKKr   )N)@__name__
__module____qualname__r   r   r   r   r   r	   r,  r#  rh  r%  r   rl  r  r   r   r  r  r  r  r   r  r  r   r   r  r   r  r  r   r  r   r  r	  r   r%  r   r)  r-  r   r   floatr
   r6  r9  r<  rj   r   r   rL  r   rC  r\  re  rk  rg  r  r  r  r  r  __classcell__)r   s   @r   r'   r'      s       X X X X Xt -/ < <: < < < < 68 X X X Xt *, 9 9V 9 9 9 9  35 [ [ [ [z
6 
6 
6 /1    " 35 4 4 4 4lR
 R
 R
 R
 R
h @DB j jS j jS\ j j j j( 9; 3 3C 3 3 3 3* 9; 3 3C 3 3 3 3, @B  3     68 A A AF A A A A"X X6 XV X X X Xt 6:" 5 57 5 5 5 5 54= = =5 = = = =~ <@d[] !A !A !AS !A !Abfglbm !A !A !A !AF
) 
) 
) 
) 
) /1 6 6[ 6 6 6 6p *, 	, 	, 	, 	, 	, 	,^ ^ ^5 ^ ^ ^ ^@ 8<B $* $*C $* $* $* $* $*L 59tZ^gi (A (Ac (A (ATW (Anrsxny (A (A (A (AT mqy{ S* S* S*I S*Y S*X] S*fi S* S* S* S*j 9=R &* &*S &*# &* &* &* &*P 37TX\eg A AC As ARU A A A A0 EIQS /: /:3 /: /: /: /: /:b   <@daenp 1 1S 1 1[^ 1uy  {F  vG 1 1 1 1&6
 6
x 6
; 6
 6
 6
 6
p: : :
 
h 
 
 
 
$ =? 3 3 3 3 3 3  JL 1 1S 1 1 1 10 &eBSW P P P P<  0 >@ 
 
 
 
 
 
. 8<$]ajl L L LC LWZ Lquvzq{ L L L L L L L Lr   r'   )- ccxt.async_support.base.exchanger   ccxt.abstract.geminir   r&  r  ccxt.base.typesr   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   r   typingr   ccxt.base.errorsr   r   r   r   r   r   r   r   r   r    r!   r"   r#   ccxt.base.decimal_to_precisionr$   ccxt.base.preciser%   r'    r   r   <module>r     s   6 5 5 5 5 5 , , , , , ,   u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u  u       * * * * * * 0 0 0 0 0 0 - - - - - - . . . . . . ' ' ' ' ' ' . . . . . . ) ) ) ) ) ) * * * * * * ) ) ) ) ) ) . . . . . . 1 1 1 1 1 1 * * * * * * ) ) ) ) ) ) 4 4 4 4 4 4 % % % % % %CL CL CL CL CLX{ CL CL CL CL CLr   