From 0d166565f2d7ac589bf0c93bd1969684cbfb2d0f Mon Sep 17 00:00:00 2001 From: Ichinga Samuel Date: Sun, 10 Aug 2025 18:36:08 +0100 Subject: [PATCH] 4.0.15b --- pyproject.toml | 6 +- requirements.txt | 160 -- src/aiomql/contrib/trackers/open_position.py | 4 +- src/aiomql/lib/order.py | 5 +- src/aiomql/ta_libs/pandas_ta/__init__.py | 60 - src/aiomql/ta_libs/pandas_ta/__main__.py | 7 - src/aiomql/ta_libs/pandas_ta/_typing.py | 70 - .../ta_libs/pandas_ta/candle/__init__.py | 16 - .../ta_libs/pandas_ta/candle/cdl_doji.py | 90 - .../ta_libs/pandas_ta/candle/cdl_inside.py | 77 - .../ta_libs/pandas_ta/candle/cdl_pattern.py | 125 -- src/aiomql/ta_libs/pandas_ta/candle/cdl_z.py | 92 - src/aiomql/ta_libs/pandas_ta/candle/ha.py | 86 - src/aiomql/ta_libs/pandas_ta/core.py | 1792 --------------- src/aiomql/ta_libs/pandas_ta/custom.py | 177 -- .../ta_libs/pandas_ta/cycle/__init__.py | 8 - src/aiomql/ta_libs/pandas_ta/cycle/ebsw.py | 141 -- src/aiomql/ta_libs/pandas_ta/cycle/reflex.py | 114 - src/aiomql/ta_libs/pandas_ta/ma.py | 72 - src/aiomql/ta_libs/pandas_ta/maps.py | 90 - .../ta_libs/pandas_ta/momentum/__init__.py | 93 - src/aiomql/ta_libs/pandas_ta/momentum/ao.py | 65 - src/aiomql/ta_libs/pandas_ta/momentum/apo.py | 74 - src/aiomql/ta_libs/pandas_ta/momentum/bias.py | 58 - src/aiomql/ta_libs/pandas_ta/momentum/bop.py | 70 - src/aiomql/ta_libs/pandas_ta/momentum/brar.py | 91 - src/aiomql/ta_libs/pandas_ta/momentum/cci.py | 75 - src/aiomql/ta_libs/pandas_ta/momentum/cfo.py | 69 - src/aiomql/ta_libs/pandas_ta/momentum/cg.py | 57 - src/aiomql/ta_libs/pandas_ta/momentum/cmo.py | 90 - .../ta_libs/pandas_ta/momentum/coppock.py | 70 - src/aiomql/ta_libs/pandas_ta/momentum/crsi.py | 105 - src/aiomql/ta_libs/pandas_ta/momentum/cti.py | 56 - src/aiomql/ta_libs/pandas_ta/momentum/dm.py | 94 - src/aiomql/ta_libs/pandas_ta/momentum/er.py | 93 - src/aiomql/ta_libs/pandas_ta/momentum/eri.py | 75 - src/aiomql/ta_libs/pandas_ta/momentum/exhc.py | 123 - .../ta_libs/pandas_ta/momentum/fisher.py | 95 - .../ta_libs/pandas_ta/momentum/inertia.py | 118 - src/aiomql/ta_libs/pandas_ta/momentum/kdj.py | 94 - src/aiomql/ta_libs/pandas_ta/momentum/kst.py | 97 - src/aiomql/ta_libs/pandas_ta/momentum/macd.py | 141 -- src/aiomql/ta_libs/pandas_ta/momentum/mom.py | 76 - src/aiomql/ta_libs/pandas_ta/momentum/pgo.py | 68 - src/aiomql/ta_libs/pandas_ta/momentum/ppo.py | 107 - src/aiomql/ta_libs/pandas_ta/momentum/psl.py | 80 - src/aiomql/ta_libs/pandas_ta/momentum/qqe.py | 174 -- src/aiomql/ta_libs/pandas_ta/momentum/roc.py | 84 - src/aiomql/ta_libs/pandas_ta/momentum/rsi.py | 115 - src/aiomql/ta_libs/pandas_ta/momentum/rsx.py | 149 -- src/aiomql/ta_libs/pandas_ta/momentum/rvgi.py | 87 - .../ta_libs/pandas_ta/momentum/slope.py | 71 - src/aiomql/ta_libs/pandas_ta/momentum/smc.py | 118 - src/aiomql/ta_libs/pandas_ta/momentum/smi.py | 92 - .../ta_libs/pandas_ta/momentum/squeeze.py | 205 -- .../ta_libs/pandas_ta/momentum/squeeze_pro.py | 222 -- src/aiomql/ta_libs/pandas_ta/momentum/stc.py | 175 -- .../ta_libs/pandas_ta/momentum/stoch.py | 121 - .../ta_libs/pandas_ta/momentum/stochf.py | 100 - .../ta_libs/pandas_ta/momentum/stochrsi.py | 104 - src/aiomql/ta_libs/pandas_ta/momentum/tmo.py | 130 -- src/aiomql/ta_libs/pandas_ta/momentum/trix.py | 93 - src/aiomql/ta_libs/pandas_ta/momentum/tsi.py | 106 - src/aiomql/ta_libs/pandas_ta/momentum/uo.py | 105 - .../ta_libs/pandas_ta/momentum/willr.py | 75 - .../ta_libs/pandas_ta/overlap/__init__.py | 77 - .../ta_libs/pandas_ta/overlap/alligator.py | 87 - src/aiomql/ta_libs/pandas_ta/overlap/alma.py | 81 - src/aiomql/ta_libs/pandas_ta/overlap/dema.py | 75 - src/aiomql/ta_libs/pandas_ta/overlap/ema.py | 81 - src/aiomql/ta_libs/pandas_ta/overlap/fwma.py | 66 - src/aiomql/ta_libs/pandas_ta/overlap/hilo.py | 100 - src/aiomql/ta_libs/pandas_ta/overlap/hl2.py | 52 - src/aiomql/ta_libs/pandas_ta/overlap/hlc3.py | 60 - src/aiomql/ta_libs/pandas_ta/overlap/hma.py | 71 - src/aiomql/ta_libs/pandas_ta/overlap/hwma.py | 74 - .../ta_libs/pandas_ta/overlap/ichimoku.py | 131 -- src/aiomql/ta_libs/pandas_ta/overlap/jma.py | 118 - src/aiomql/ta_libs/pandas_ta/overlap/kama.py | 94 - .../ta_libs/pandas_ta/overlap/linreg.py | 164 -- src/aiomql/ta_libs/pandas_ta/overlap/mama.py | 167 -- src/aiomql/ta_libs/pandas_ta/overlap/mcgd.py | 72 - .../ta_libs/pandas_ta/overlap/midpoint.py | 64 - .../ta_libs/pandas_ta/overlap/midprice.py | 67 - src/aiomql/ta_libs/pandas_ta/overlap/ohlc4.py | 53 - .../ta_libs/pandas_ta/overlap/pivots.py | 264 --- src/aiomql/ta_libs/pandas_ta/overlap/pwma.py | 67 - src/aiomql/ta_libs/pandas_ta/overlap/rma.py | 56 - .../ta_libs/pandas_ta/overlap/sinwma.py | 63 - src/aiomql/ta_libs/pandas_ta/overlap/sma.py | 85 - src/aiomql/ta_libs/pandas_ta/overlap/smma.py | 82 - src/aiomql/ta_libs/pandas_ta/overlap/ssf.py | 115 - src/aiomql/ta_libs/pandas_ta/overlap/ssf3.py | 94 - .../ta_libs/pandas_ta/overlap/supertrend.py | 108 - src/aiomql/ta_libs/pandas_ta/overlap/swma.py | 68 - src/aiomql/ta_libs/pandas_ta/overlap/t3.py | 85 - src/aiomql/ta_libs/pandas_ta/overlap/tema.py | 73 - src/aiomql/ta_libs/pandas_ta/overlap/trima.py | 77 - src/aiomql/ta_libs/pandas_ta/overlap/vidya.py | 113 - src/aiomql/ta_libs/pandas_ta/overlap/wcp.py | 65 - src/aiomql/ta_libs/pandas_ta/overlap/wma.py | 94 - src/aiomql/ta_libs/pandas_ta/overlap/zlma.py | 98 - .../ta_libs/pandas_ta/performance/__init__.py | 10 - .../ta_libs/pandas_ta/performance/drawdown.py | 68 - .../pandas_ta/performance/log_return.py | 64 - .../pandas_ta/performance/percent_return.py | 64 - src/aiomql/ta_libs/pandas_ta/py.typed | 0 .../ta_libs/pandas_ta/statistics/__init__.py | 24 - .../ta_libs/pandas_ta/statistics/entropy.py | 60 - .../ta_libs/pandas_ta/statistics/kurtosis.py | 58 - .../ta_libs/pandas_ta/statistics/mad.py | 61 - .../ta_libs/pandas_ta/statistics/median.py | 58 - .../ta_libs/pandas_ta/statistics/quantile.py | 57 - .../ta_libs/pandas_ta/statistics/skew.py | 58 - .../ta_libs/pandas_ta/statistics/stdev.py | 70 - .../pandas_ta/statistics/tos_stdevall.py | 96 - .../ta_libs/pandas_ta/statistics/variance.py | 70 - .../ta_libs/pandas_ta/statistics/zscore.py | 57 - .../ta_libs/pandas_ta/trend/__init__.py | 46 - src/aiomql/ta_libs/pandas_ta/trend/adx.py | 168 -- .../ta_libs/pandas_ta/trend/alphatrend.py | 161 -- src/aiomql/ta_libs/pandas_ta/trend/amat.py | 87 - src/aiomql/ta_libs/pandas_ta/trend/aroon.py | 100 - src/aiomql/ta_libs/pandas_ta/trend/chop.py | 92 - src/aiomql/ta_libs/pandas_ta/trend/cksp.py | 101 - src/aiomql/ta_libs/pandas_ta/trend/decay.py | 95 - .../ta_libs/pandas_ta/trend/decreasing.py | 85 - src/aiomql/ta_libs/pandas_ta/trend/dpo.py | 69 - .../ta_libs/pandas_ta/trend/ht_trendline.py | 154 -- .../ta_libs/pandas_ta/trend/increasing.py | 85 - .../ta_libs/pandas_ta/trend/long_run.py | 66 - src/aiomql/ta_libs/pandas_ta/trend/psar.py | 154 -- src/aiomql/ta_libs/pandas_ta/trend/qstick.py | 67 - src/aiomql/ta_libs/pandas_ta/trend/rwi.py | 94 - .../ta_libs/pandas_ta/trend/short_run.py | 66 - .../ta_libs/pandas_ta/trend/trendflex.py | 111 - .../ta_libs/pandas_ta/trend/ttm_trend.py | 76 - src/aiomql/ta_libs/pandas_ta/trend/vhf.py | 68 - src/aiomql/ta_libs/pandas_ta/trend/vortex.py | 83 - src/aiomql/ta_libs/pandas_ta/trend/zigzag.py | 335 --- .../ta_libs/pandas_ta/utils/__init__.py | 28 - .../ta_libs/pandas_ta/utils/_candles.py | 54 - src/aiomql/ta_libs/pandas_ta/utils/_core.py | 400 ---- src/aiomql/ta_libs/pandas_ta/utils/_math.py | 792 ------- src/aiomql/ta_libs/pandas_ta/utils/_numba.py | 145 -- .../ta_libs/pandas_ta/utils/_signals.py | 623 ------ src/aiomql/ta_libs/pandas_ta/utils/_study.py | 145 -- src/aiomql/ta_libs/pandas_ta/utils/_time.py | 152 -- .../ta_libs/pandas_ta/utils/_validate.py | 190 -- .../ta_libs/pandas_ta/volatility/__init__.py | 36 - .../pandas_ta/volatility/aberration.py | 85 - .../ta_libs/pandas_ta/volatility/accbands.py | 93 - .../ta_libs/pandas_ta/volatility/atr.py | 107 - .../ta_libs/pandas_ta/volatility/atrts.py | 140 -- .../ta_libs/pandas_ta/volatility/bbands.py | 124 - .../pandas_ta/volatility/chandelier_exit.py | 127 -- .../ta_libs/pandas_ta/volatility/donchian.py | 77 - .../ta_libs/pandas_ta/volatility/hwc.py | 142 -- src/aiomql/ta_libs/pandas_ta/volatility/kc.py | 95 - .../ta_libs/pandas_ta/volatility/massi.py | 77 - .../ta_libs/pandas_ta/volatility/natr.py | 97 - .../ta_libs/pandas_ta/volatility/pdist.py | 67 - .../ta_libs/pandas_ta/volatility/rvi.py | 117 - .../ta_libs/pandas_ta/volatility/thermo.py | 111 - .../pandas_ta/volatility/true_range.py | 94 - src/aiomql/ta_libs/pandas_ta/volatility/ui.py | 73 - .../ta_libs/pandas_ta/volume/__init__.py | 44 - src/aiomql/ta_libs/pandas_ta/volume/ad.py | 72 - src/aiomql/ta_libs/pandas_ta/volume/adosc.py | 95 - src/aiomql/ta_libs/pandas_ta/volume/aobv.py | 113 - src/aiomql/ta_libs/pandas_ta/volume/cmf.py | 79 - src/aiomql/ta_libs/pandas_ta/volume/efi.py | 71 - src/aiomql/ta_libs/pandas_ta/volume/eom.py | 82 - src/aiomql/ta_libs/pandas_ta/volume/kvo.py | 100 - src/aiomql/ta_libs/pandas_ta/volume/mfi.py | 99 - src/aiomql/ta_libs/pandas_ta/volume/nvi.py | 68 - src/aiomql/ta_libs/pandas_ta/volume/obv.py | 65 - src/aiomql/ta_libs/pandas_ta/volume/pvi.py | 111 - src/aiomql/ta_libs/pandas_ta/volume/pvo.py | 81 - src/aiomql/ta_libs/pandas_ta/volume/pvol.py | 51 - src/aiomql/ta_libs/pandas_ta/volume/pvr.py | 58 - src/aiomql/ta_libs/pandas_ta/volume/pvt.py | 59 - src/aiomql/ta_libs/pandas_ta/volume/tsv.py | 104 - src/aiomql/ta_libs/pandas_ta/volume/vhm.py | 76 - src/aiomql/ta_libs/pandas_ta/volume/vp.py | 129 -- src/aiomql/ta_libs/pandas_ta/volume/vwap.py | 120 - src/aiomql/ta_libs/pandas_ta/volume/vwma.py | 58 - uv.lock | 1985 ++++++++--------- 188 files changed, 999 insertions(+), 21263 deletions(-) delete mode 100644 requirements.txt delete mode 100644 src/aiomql/ta_libs/pandas_ta/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/__main__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/_typing.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/cdl_doji.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/cdl_inside.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/cdl_pattern.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/cdl_z.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/candle/ha.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/core.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/custom.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/cycle/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/cycle/ebsw.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/cycle/reflex.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/ma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/maps.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/ao.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/apo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/bias.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/bop.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/brar.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/cci.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/cfo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/cg.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/cmo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/coppock.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/crsi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/cti.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/dm.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/er.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/eri.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/exhc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/fisher.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/inertia.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/kdj.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/kst.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/macd.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/mom.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/pgo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/ppo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/psl.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/qqe.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/roc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/rsi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/rsx.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/rvgi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/slope.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/smc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/smi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/squeeze.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/squeeze_pro.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/stc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/stoch.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/stochf.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/stochrsi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/tmo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/trix.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/tsi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/uo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/momentum/willr.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/alligator.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/alma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/dema.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/ema.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/fwma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/hilo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/hl2.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/hlc3.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/hma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/hwma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/ichimoku.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/jma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/kama.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/linreg.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/mama.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/mcgd.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/midpoint.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/midprice.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/ohlc4.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/pivots.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/pwma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/rma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/sinwma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/sma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/smma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/ssf.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/ssf3.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/supertrend.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/swma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/t3.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/tema.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/trima.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/vidya.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/wcp.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/wma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/overlap/zlma.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/performance/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/performance/drawdown.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/performance/log_return.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/performance/percent_return.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/py.typed delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/entropy.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/kurtosis.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/mad.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/median.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/quantile.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/skew.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/stdev.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/tos_stdevall.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/variance.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/statistics/zscore.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/adx.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/alphatrend.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/amat.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/aroon.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/chop.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/cksp.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/decay.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/decreasing.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/dpo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/ht_trendline.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/increasing.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/long_run.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/psar.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/qstick.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/rwi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/short_run.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/trendflex.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/ttm_trend.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/vhf.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/vortex.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/trend/zigzag.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_candles.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_core.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_math.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_numba.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_signals.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_study.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_time.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/utils/_validate.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/aberration.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/accbands.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/atr.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/atrts.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/bbands.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/chandelier_exit.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/donchian.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/hwc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/kc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/massi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/natr.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/pdist.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/rvi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/thermo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/true_range.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volatility/ui.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/__init__.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/ad.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/adosc.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/aobv.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/cmf.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/efi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/eom.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/kvo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/mfi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/nvi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/obv.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/pvi.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/pvo.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/pvol.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/pvr.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/pvt.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/tsv.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/vhm.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/vp.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/vwap.py delete mode 100644 src/aiomql/ta_libs/pandas_ta/volume/vwma.py diff --git a/pyproject.toml b/pyproject.toml index edc9e0f..4a8f15a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,9 +18,9 @@ keywords = ["MetaTrader5", "Asynchronous", "Algorithmic Trading", "Trading Bot", dependencies = [ "MetaTrader5>=5.0.5200", - "pandas>=1.5.0", - "mplfinance>=0.10.1", - "pandas-stubs==2.3.0.250703", + "pandas>=2.0.0", + "mplfinance>=0.12.10b0", + "numba>=0.61.2", "tqdm>=4.67.1", ] diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index b430bc3..0000000 --- a/requirements.txt +++ /dev/null @@ -1,160 +0,0 @@ --e git+ssh://git@github.com/Chimezirim-Bassey/aiomql.git@bae2983bded5b3912f7234fd0acaa89ab84fa1c4#egg=aiomql -anyio==4.3.0 -argon2-cffi==23.1.0 -argon2-cffi-bindings==21.2.0 -arrow==1.3.0 -asttokens==2.4.1 -async-lru==2.0.4 -attrs==23.2.0 -Babel==2.14.0 -beautifulsoup4==4.12.3 -black==23.9.1 -bleach==6.1.0 -build==1.2.2.post1 -certifi==2023.7.22 -cffi==1.16.0 -charset-normalizer==3.3.0 -click==8.1.7 -colorama==0.4.6 -comm==0.2.2 -contourpy==1.2.1 -cycler==0.12.1 -databind.core==4.4.1 -databind.json==4.4.1 -debugpy==1.8.1 -decorator==5.1.1 -defusedxml==0.7.1 -Deprecated==1.2.14 -docspec==2.2.1 -docspec-python==2.2.1 -docstring-parser==0.11 -docutils==0.20.1 -docutils-stubs==0.0.22 -executing==2.0.1 -fastjsonschema==2.19.1 -fonttools==4.51.0 -fqdn==1.5.1 -h11==0.14.0 -httpcore==1.0.5 -httpx==0.27.0 -id==1.5.0 -idna==3.4 -importlib-metadata==6.8.0 -iniconfig==2.0.0 -ipykernel==6.29.4 -ipython==8.23.0 -ipywidgets==8.1.2 -isoduration==20.11.0 -jaraco.classes==3.3.0 -jedi==0.19.1 -Jinja2==3.1.2 -json5==0.9.24 -jsonpointer==2.4 -jsonschema==4.21.1 -jsonschema-specifications==2023.12.1 -jupyter==1.0.0 -jupyter-console==6.6.3 -jupyter-events==0.10.0 -jupyter-lsp==2.2.5 -jupyter_client==8.6.1 -jupyter_core==5.7.2 -jupyter_server==2.13.0 -jupyter_server_terminals==0.5.3 -jupyterlab==4.1.6 -jupyterlab_pygments==0.3.0 -jupyterlab_server==2.26.0 -jupyterlab_widgets==3.0.10 -keyring==24.2.0 -kiwisolver==1.4.5 -markdown-it-py==3.0.0 -MarkupSafe==2.1.3 -matplotlib==3.8.4 -matplotlib-inline==0.1.6 -mdurl==0.1.2 -MetaTrader5==5.0.5200 -mistune==3.0.2 -more-itertools==10.1.0 -mplfinance==0.12.10b0 -mypy-extensions==1.0.0 -nbclient==0.10.0 -nbconvert==7.16.3 -nbformat==5.10.4 -nest-asyncio==1.6.0 -nh3==0.2.14 -notebook==7.1.2 -notebook_shim==0.2.4 -nr-date==2.1.0 -nr-stream==1.1.5 -nr.util==0.8.12 -numpy==1.26.0 -overrides==7.7.0 -packaging==25.0 -pandas==2.1.1 -pandas-ta==0.3.14b0 -pandocfilters==1.5.1 -parso==0.8.4 -pathspec==0.11.2 -pillow==10.3.0 -pkginfo==1.9.6 -platformdirs==3.11.0 -pluggy==1.5.0 -prometheus_client==0.20.0 -prompt-toolkit==3.0.43 -psutil==5.9.8 -pure-eval==0.2.2 -pycparser==2.22 -pydoc-markdown==4.8.2 -Pygments==2.16.1 -pyparsing==3.1.2 -pyproject_hooks==1.0.0 -pytest==8.3.3 -pytest-asyncio==0.24.0 -pytest-order==1.3.0 -python-dateutil==2.8.2 -python-json-logger==2.0.7 -python-telegram-bot==21.0.1 -pytz==2023.3.post1 -pywin32==306 -pywin32-ctypes==0.2.2 -pywinpty==2.0.13 -PyYAML==6.0.1 -pyzmq==25.1.2 -qtconsole==5.5.1 -QtPy==2.4.1 -readme-renderer==42.0 -referencing==0.34.0 -requests==2.31.0 -requests-toolbelt==1.0.0 -rfc3339-validator==0.1.4 -rfc3986==2.0.0 -rfc3986-validator==0.1.1 -rich==13.6.0 -rpds-py==0.18.0 -ruff==0.7.3 -Send2Trash==1.8.3 -six==1.16.0 -sniffio==1.3.1 -soupsieve==2.5 -stack-data==0.6.3 -terminado==0.18.1 -tinycss2==1.2.1 -tomli==2.0.1 -tomli_w==1.0.0 -tornado==6.4 -traitlets==5.14.2 -twine==6.1.0 -typeapi==2.1.1 -types-python-dateutil==2.9.0.20240316 -typing_extensions==4.6.3 -tzdata==2023.3 -uri-template==1.3.0 -urllib3==2.0.6 -watchdog==3.0.0 -wcwidth==0.2.13 -webcolors==1.13 -webencodings==0.5.1 -websocket-client==1.7.0 -widgetsnbextension==4.0.10 -wrapt==1.15.0 -yapf==0.40.2 -zipp==3.17.0 diff --git a/src/aiomql/contrib/trackers/open_position.py b/src/aiomql/contrib/trackers/open_position.py index 3224b99..31e003b 100644 --- a/src/aiomql/contrib/trackers/open_position.py +++ b/src/aiomql/contrib/trackers/open_position.py @@ -58,6 +58,7 @@ class OpenPosition: logger.error("%s: Unable to remove closed position from state", exe) async def update_position(self) -> bool: + # ToDo: remove pending order pos = await self.positions.get_position_by_ticket(ticket=self.ticket) if pos is not None: self.position = pos @@ -69,6 +70,7 @@ class OpenPosition: async def modify_stops(self, *, sl: float = None, tp: float = None, use_stop_levels=False) -> tuple[bool, OrderSendResult | None]: try: + # todo: add stops tick = await self.symbol.info_tick() # modify stop_loss @@ -147,7 +149,7 @@ class OpenPosition: logger.error("%s: Error occurred in track method of Open Position for %d:%s", exe, self.symbol.name, self.ticket) - async def get_price_from_profit(self, profit): + async def profit_to_price(self, profit): action = OrderType.BUY if self.position.type == 0 else OrderType.SELL volume = self.position.volume price_open = self.position.price_open diff --git a/src/aiomql/lib/order.py b/src/aiomql/lib/order.py index 4e7d77f..cb94bc5 100644 --- a/src/aiomql/lib/order.py +++ b/src/aiomql/lib/order.py @@ -80,9 +80,10 @@ class Order(_Base, TradeRequest): return tuple() @classmethod - async def cancel_order(cls, *, ticket: int, symbol: str) -> TradeOrder | None: + async def cancel_order(cls, *, order: int, symbol: str) -> OrderSendResult: """Cancel an active pending order by ticket number.""" - order = cls.mt5.order_send({"symbol": symbol, "ticket": ticket, "action": TradeAction.REMOVE}) + res = await cls.mt5.order_send({"symbol": symbol, "order": order, "action": TradeAction.REMOVE}) + return res async def check(self, **kwargs) -> OrderCheckResult: """Check funds sufficiency for performing a required trading operation and the possibility of executing it. diff --git a/src/aiomql/ta_libs/pandas_ta/__init__.py b/src/aiomql/ta_libs/pandas_ta/__init__.py deleted file mode 100644 index 9975446..0000000 --- a/src/aiomql/ta_libs/pandas_ta/__init__.py +++ /dev/null @@ -1,60 +0,0 @@ -from .maps import EXCHANGE_TZ, RATE, Category, Imports -from .utils import * -from .utils import __all__ as utils_all - -# Flat Structure. Supports ta.ema() or ta.overlap.ema() -from .candle import * -from .cycle import * -from .momentum import * -from .overlap import * -from .performance import * -from .statistics import * -from .trend import * -from .volatility import * -from .volume import * -from .candle import __all__ as candle_all -from .cycle import __all__ as cycle_all -from .momentum import __all__ as momentum_all -from .overlap import __all__ as overlap_all -from .performance import __all__ as performance_all -from .statistics import __all__ as statistics_all -from .trend import __all__ as trend_all -from .volatility import __all__ as volatility_all -from .volume import __all__ as volume_all - -# Common Averages useful for Indicators -# with a mamode argument, like ta.adx() -from .ma import ma - -# Custom External Directory Commands. See help(import_dir) -from .custom import create_dir, import_dir - -# Enable "ta" DataFrame Extension -from .core import AnalysisIndicators - -__all__ = [ - # "name", - "EXCHANGE_TZ", - "RATE", - "Category", - "Imports", - "ma", - "create_dir", - "import_dir", - "AnalysisIndicators", - "AllStudy", - "CommonStudy", -] - -__all__ += [ - utils_all - + candle_all - + cycle_all - + momentum_all - + overlap_all - + performance_all - + statistics_all - + trend_all - + volatility_all - + volume_all -] diff --git a/src/aiomql/ta_libs/pandas_ta/__main__.py b/src/aiomql/ta_libs/pandas_ta/__main__.py deleted file mode 100644 index c842f73..0000000 --- a/src/aiomql/ta_libs/pandas_ta/__main__.py +++ /dev/null @@ -1,7 +0,0 @@ -#-*- coding: utf-8 -*- -from pandas_ta import version - -SUPPORT="http://www.pandas-ta.dev/support" - -if __name__ == "__main__": - print(f"Pandas TA: {version}\nSupport: {SUPPORT}") diff --git a/src/aiomql/ta_libs/pandas_ta/_typing.py b/src/aiomql/ta_libs/pandas_ta/_typing.py deleted file mode 100644 index bc7566c..0000000 --- a/src/aiomql/ta_libs/pandas_ta/_typing.py +++ /dev/null @@ -1,70 +0,0 @@ -from pathlib import Path -from typing import ( - Any, - Dict, - Iterable, - List, - Optional, - Sequence, - TextIO, - Tuple, - TypeVar, - Union -) - -from numpy import ndarray, recarray, void -from numpy import bool_ as np_bool_ -from numpy import floating as np_floating -from numpy import generic as np_generic -from numpy import integer as np_integer -from numpy import number as np_number -from pandas import DataFrame, Series - - - -# Generic types -T = TypeVar("T") - -# Scalars -Scalar = Union[str, float, int, complex, bool, object, np_generic] -Number = Union[int, float, complex, np_number, np_bool_] -Int = int | np_integer -Float = Union[float, np_floating] -IntFloat = Union[Int, Float] - -# Basic sequences -MaybeTuple = Union[T, Tuple[T, ...]] -MaybeList = Union[T, List[T]] -TupleList = Union[List[T], Tuple[T, ...]] -MaybeTupleList = Union[T, List[T], Tuple[T, ...]] -MaybeIterable = Union[T, Iterable[T]] -MaybeSequence = Union[T, Sequence[T]] -ListStr = List[str] - -DictLike = Union[None, dict] -DictLikeSequence = MaybeSequence[DictLike] -Args = Tuple[Any, ...] -ArgsLike = Union[None, Args] -Kwargs = Dict[str, Any] -KwargsLike = Union[None, Kwargs] -KwargsLikeSequence = MaybeSequence[KwargsLike] -FileName = Union[str, Path] - -DTypeLike = Any -PandasDTypeLike = Any -Shape = Tuple[int, ...] -RelaxedShape = Union[int, Shape] -Array = ndarray -Array1d = ndarray -Array2d = ndarray -Array3d = ndarray -Record = void -RecordArray = ndarray -RecArray = recarray -MaybeArray = Union[T, Array] -SeriesFrame = Union[Series, DataFrame] -MaybeSeries = Union[T, Series] -MaybeSeriesFrame = Union[T, Series, DataFrame] -AnyArray = Union[Array, Series, DataFrame] -AnyArray1d = Union[Array1d, Series] -AnyArray2d = Union[Array2d, DataFrame] diff --git a/src/aiomql/ta_libs/pandas_ta/candle/__init__.py b/src/aiomql/ta_libs/pandas_ta/candle/__init__.py deleted file mode 100644 index 9da8e2a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -from .cdl_doji import cdl_doji -from .cdl_inside import cdl_inside -from .cdl_pattern import cdl_pattern, cdl, ALL_PATTERNS as CDL_PATTERN_NAMES -from .cdl_z import cdl_z -from .ha import ha - -__all__ = [ - "cdl_doji", - "cdl_inside", - "cdl_pattern", - "cdl", - "CDL_PATTERN_NAMES", - "cdl_z", - "ha", -] diff --git a/src/aiomql/ta_libs/pandas_ta/candle/cdl_doji.py b/src/aiomql/ta_libs/pandas_ta/candle/cdl_doji.py deleted file mode 100644 index 9e457f3..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/cdl_doji.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from ..overlap import sma -from .._typing import Int, IntFloat -from ..utils import high_low_range, v_percent -from ..utils import real_body, v_offset, v_pos_default -from ..utils import v_bool, v_scalar, v_series - - - -def cdl_doji( - open_: Series, high: Series, low: Series, close: Series, - length: Int = None, factor: IntFloat = None, - scalar: IntFloat = None, asint: bool = None, - offset: Int = None, **kwargs: dict | None -) -> Series: - """Doji - - Attempts to identify a "Doji" candle which is shorter than 10% of - the average of the 10 previous bars High-Low range. - - Sources: - * [TA Lib](https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_CDLDOJI.c) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - factor (float): Doji value. Default: ```100``` - scalar (float): Scalar. Default: ```100``` - asint (bool): Returns as ```Int```. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - naive (bool): Prefills potential Doji; bodies that are less - than a percentage, ```factor```, of it's High-Low range. - Default: ```False``` - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9434563530497265)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 10) - open_ = v_series(open_, length) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if open_ is None or high is None or low is None or close is None: - return - - factor = v_scalar(factor, 10) if v_percent(factor) else 10 - scalar = v_scalar(scalar, 100) - asint = v_bool(asint, True) - offset = v_offset(offset) - naive = kwargs.pop("naive", False) - - # Calculate - body = real_body(open_, close).abs() - hl_range = high_low_range(high, low).abs() - hl_range_avg = sma(hl_range, length) - doji = body < 0.01 * factor * hl_range_avg - - if naive: - doji.iat[:length] = body < 0.01 * factor * hl_range - if asint: - doji = scalar * doji.astype(int) - - # Offset - if offset != 0: - doji = doji.shift(offset) - - # Fill - if "fillna" in kwargs: - doji.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - doji.name = f"CDL_DOJI_{length}_{0.01 * factor}" - doji.category = "candle" - - return doji diff --git a/src/aiomql/ta_libs/pandas_ta/candle/cdl_inside.py b/src/aiomql/ta_libs/pandas_ta/candle/cdl_inside.py deleted file mode 100644 index cde21fe..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/cdl_inside.py +++ /dev/null @@ -1,77 +0,0 @@ -from numpy import roll, where -from numba import njit -from pandas import Series -from .._typing import Int, IntFloat -from ..utils import v_bool, v_offset, v_offset, v_scalar, v_series - - - -@njit(cache=True) -def np_cdl_inside(high, low): - hdiff = where(high - roll(high, 1) < 0, 1, 0) - ldiff = where(low - roll(low, 1) > 0, 1, 0) - return hdiff & ldiff - - -def cdl_inside( - open_: Series, high: Series, low: Series, close: Series, - asbool: bool = None, scalar: IntFloat = None, - offset: Int = None, **kwargs: dict | None -) -> Series: - """Inside Bar - - Attempts to identify an "Inside" candle which is smaller than it's - previous candle. - - Sources: - * [TA Lib](https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_CDL3INSIDE.c) - * [tradingview](https://www.tradingview.com/script/IyIGN1WO-Inside-Bar/) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - asbool (bool): Return booleans. Default: ```False``` - scalar (float): Scalar. Default: ```100``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.Series): 1 column - """ - # Validate - open_ = v_series(open_) - high = v_series(high) - low = v_series(low) - close = v_series(close) - - if open_ is None or high is None or low is None or close is None: - return - - asbool = v_bool(asbool, False) - scalar = v_scalar(scalar, 100) - offset = v_offset(offset) - - # Calculate - np_high, np_low = high.to_numpy(), low.to_numpy() - np_inside = np_cdl_inside(np_high, np_low) - inside = Series(np_inside, index=close.index, dtype=bool) - - if not asbool: - inside = scalar * inside.astype(int) - - # Offset - if offset != 0: - inside = inside.shift(offset) - - # Fill - if "fillna" in kwargs: - inside.fillna(kwargs["fillna"], inplace=True) - # Name and Category - inside.name = f"CDL_INSIDE" - inside.category = "candle" - - return inside diff --git a/src/aiomql/ta_libs/pandas_ta/candle/cdl_pattern.py b/src/aiomql/ta_libs/pandas_ta/candle/cdl_pattern.py deleted file mode 100644 index 82c7cc3..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/cdl_pattern.py +++ /dev/null @@ -1,125 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series, DataFrame -from numpy import integer -from ..maps import Imports -from ..utils import v_offset, v_scalar, v_series -from ..candle import cdl_doji, cdl_inside - - - -ALL_PATTERNS = [ - "2crows", "3blackcrows", "3inside", "3linestrike", "3outside", - "3starsinsouth", "3whitesoldiers", "abandonedbaby", "advanceblock", - "belthold", "breakaway", "closingmarubozu", "concealbabyswall", - "counterattack", "darkcloudcover", "doji", "dojistar", "dragonflydoji", - "engulfing", "eveningdojistar", "eveningstar", "gapsidesidewhite", - "gravestonedoji", "hammer", "hangingman", "harami", "haramicross", - "highwave", "hikkake", "hikkakemod", "homingpigeon", "identical3crows", - "inneck", "inside", "invertedhammer", "kicking", "kickingbylength", - "ladderbottom", "longleggeddoji", "longline", "marubozu", "matchinglow", - "mathold", "morningdojistar", "morningstar", "onneck", "piercing", - "rickshawman", "risefall3methods", "separatinglines", "shootingstar", - "shortline", "spinningtop", "stalledpattern", "sticksandwich", "takuri", - "tasukigap", "thrusting", "tristar", "unique3river", "upsidegap2crows", - "xsidegap3methods" -] - - -def cdl_pattern( - open_: Series, high: Series, low: Series, close: Series, - name: str | list[str] = "all", scalar: int | float = None, - offset: int | integer = None, **kwargs: dict | None -) -> DataFrame: - """Candle Pattern - - This function wraps TA Lib candle patterns. - - Sources: - * [TA Lib](https://ta-lib.org) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - name (str | list[str]): Pattern name or a list of pattern names. - Default: ```"all"``` - scalar (float): Scalar. Default: ```100``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.DataFrame): Pattern Column(s) - - Warning: TA Lib - TA Lib must be installed - """ - # Validate Arguments - open_ = v_series(open_, 1) - high = v_series(high, 1) - low = v_series(low, 1) - close = v_series(close, 1) - - if open_ is None or high is None or low is None or close is None: - return - - offset = v_offset(offset) - scalar = v_scalar(scalar, 100) - - pta_patterns = {"doji": cdl_doji, "inside": cdl_inside} - - if name == "all": - name = ALL_PATTERNS - - if isinstance(name, str): - name = [name] - - if Imports["talib"]: - import talib.abstract as tala - - result = {} - for n in name: - if n not in ALL_PATTERNS: - print(f"[X] There is no candle pattern named {n} available!") - continue - - if n in pta_patterns: - pattern_result = pta_patterns[n]( - open_, high, low, close, offset=offset, scalar=scalar, **kwargs - ) - if not isinstance(pattern_result, Series): - continue - result[pattern_result.name] = pattern_result - - else: - if not Imports["talib"]: - print(f"[i] Requires TA-Lib to use {n}. (pip install TA-Lib)") - continue - - pf = tala.Function(f"CDL{n.upper()}") - pattern_result = Series( - 0.01 * scalar * pf(open_, high, low, close, **kwargs) - ) - pattern_result.index = close.index - - # Offset - if offset != 0: - pattern_result = pattern_result.shift(offset) - - # Fill - if "fillna" in kwargs: - pattern_result.fillna(kwargs["fillna"], inplace=True) - result[f"CDL_{n.upper()}"] = pattern_result - - if len(result) == 0: - return - - # Name and Category - df = DataFrame(result) - df.name = "CDL_PATTERN" - df.category = "candle" - return df - -cdl = cdl_pattern # Alias diff --git a/src/aiomql/ta_libs/pandas_ta/candle/cdl_z.py b/src/aiomql/ta_libs/pandas_ta/candle/cdl_z.py deleted file mode 100644 index 0c43cee..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/cdl_z.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from .._typing import Int -from ..statistics import zscore -from ..utils import v_bool, v_offset, v_pos_default, v_series - - -def cdl_z( - open_: Series, high: Series, low: Series, close: Series, - length: Int = None, full: bool = None, ddof: Int = None, - offset: Int = None, **kwargs: dict | None -) -> DataFrame: - """Z Candles - - Creates candlesticks using a rolling Z Score. - - Sources: - * Kevin Johnson - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - full (bool): Apply ```length``` to whole DataFrame. - Default: ```False``` - ddof (int): By default, uses Pandas ```ddof=1```. - For Numpy calculation, use ```0```. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - naive (bool): If ```True```, prefills potential Doji less - than the length if it less than a percentage of it's - High-Low range. Default: ```False``` - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.DataFrame): 4 columns - - Note: - * Numpy ```std()``` [ddof](https://numpy.org/doc/stable/reference/generated/numpy.std.html) explanation. - """ - # Validate - length = v_pos_default(length, 30) - open_ = v_series(open_, length) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if open_ is None or high is None or low is None or close is None: - return - - full = v_bool(full, False) - ddof = int(ddof) if isinstance(ddof, int) and 0 <= ddof < length else 1 - offset = v_offset(offset) - - # Calculate - if full: - length = close.size - - z_open = zscore(open_, length=length, ddof=ddof) - z_high = zscore(high, length=length, ddof=ddof) - z_low = zscore(low, length=length, ddof=ddof) - z_close = zscore(close, length=length, ddof=ddof) - - _full = "a" if full else "" - _props = _full if full else f"_{length}_{ddof}" - data = { - f"open_Z{_props}": z_open, - f"high_Z{_props}": z_high, - f"low_Z{_props}": z_low, - f"close_Z{_props}": z_close, - } - df = DataFrame(data, index=close.index) - - if full: - df.fillna(method="backfill", axis=0, inplace=True) - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - df.name = f"CDL_Z{_props}" - df.category = "candle" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/candle/ha.py b/src/aiomql/ta_libs/pandas_ta/candle/ha.py deleted file mode 100644 index 60cd713..0000000 --- a/src/aiomql/ta_libs/pandas_ta/candle/ha.py +++ /dev/null @@ -1,86 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import empty_like, maximum, minimum -from numba import njit -from pandas import DataFrame, Series -from .._typing import Int -from ..utils import v_offset, v_series - - - -@njit(cache=True) -def np_ha(np_open, np_high, np_low, np_close): - ha_close = 0.25 * (np_open + np_high + np_low + np_close) - ha_open = empty_like(ha_close) - ha_open[0] = 0.5 * (np_open[0] + np_close[0]) - - m = np_close.size - for i in range(1, m): - ha_open[i] = 0.5 * (ha_open[i - 1] + ha_close[i - 1]) - - ha_high = maximum(maximum(ha_open, ha_close), np_high) - ha_low = minimum(minimum(ha_open, ha_close), np_low) - - return ha_open, ha_high, ha_low, ha_close - - -def ha( - open_: Series, high: Series, low: Series, close: Series, - offset: Int = None, **kwargs: dict | None -) -> DataFrame: - """Heikin Ashi Candles - - Creates Japanese _ohlc_ candlesticks that attempts to filter out market - noise. Developed by Munehisa Homma in the 1700s, Heikin Ashi Candles share - some characteristics with standard candlestick charts but creates a - smoother candlestick appearance. - - Sources: - * [Investopedia](https://www.investopedia.com/terms/h/heikinashi.asp) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.DataFrame): 4 columns - """ - # Validate - open_ = v_series(open_, 1) - high = v_series(high, 1) - low = v_series(low, 1) - close = v_series(close, 1) - offset = v_offset(offset) - - if open_ is None or high is None or low is None or close is None: - return - - # Calculate - np_open, np_high = open_.to_numpy(), high.to_numpy() - np_low, np_close = low.to_numpy(), close.to_numpy() - ha_open, ha_high, ha_low, ha_close = np_ha(np_open, np_high, np_low, np_close) - df = DataFrame({ - "HA_open": ha_open, - "HA_high": ha_high, - "HA_low": ha_low, - "HA_close": ha_close, - }, index=close.index) - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - df.name = "Heikin-Ashi" - df.category = "candle" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/core.py b/src/aiomql/ta_libs/pandas_ta/core.py deleted file mode 100644 index 0952679..0000000 --- a/src/aiomql/ta_libs/pandas_ta/core.py +++ /dev/null @@ -1,1792 +0,0 @@ -# -*- coding: utf-8 -from dataclasses import dataclass -from multiprocessing import cpu_count, Pool -from pathlib import Path -from time import perf_counter -from warnings import simplefilter - -from numpy import log, log10, ndarray -from pandas.api.extensions import register_dataframe_accessor -from pandas.errors import PerformanceWarning -from pandas import DataFrame, Series, concat -from pandas import options as pd_options -from tqdm import tqdm - -from pandas_ta._typing import * -from pandas_ta import * - -# Recommended moving forward to Pandas 3 -pd_options.mode.copy_on_write = True - - - -@register_dataframe_accessor("ta") -class AnalysisIndicators(object): - """Pandas DataFrame Extension: "ta" - - The "ta" extension simplifies the processing of concatenating - Technical Analysis indicators onto the existing Pandas DataFrame. - To do so, this extension assumes that the DataFrame includes a DateTime - oriented index and columns named: "open", "high", "low", "close", "volume". - - Features: - * Properties and methods to work with ta data. - * Wrappers for each indicator. Simplifies - ```sma = ta.sma(df["Close"]); df["sma"] = sma``` to - ```df.ta.sma(append=True)``` - * A special ```study``` method, to simplify processing indicators with - or without multiprocessing. See: ```help(ta.study)``` - - Returns: - Any (pd.Series, pd.DataFrame, None): See Notes - - See Also: - * Pandas TA [DataFrame Extension](http://127.0.0.1:8000/docs/api/dataframe/) Documention - * [Pandas DataFrame Accessor](https://pandas.pydata.org/docs/reference/api/pandas.api.extensions.register_dataframe_accessor.html#pandas.api.extensions.register_dataframe_accessor) - - Note: - Most Indicators will return a Pandas Series. Others like MACD, - BBANDS, KC, et al will return a Pandas DataFrame. Ichimoku on the - other hand will return two DataFrames, the Ichimoku DataFrame for - the known period and a Span DataFrame for the future of the Span values. - - Documentation is formatted for [mkdocs](https://www.mkdocs.org/) and [mkdocs-docstrings](https://mkdocstrings.github.io/). - - Tip: - Remember to adjust the ```cores``` for maximum speed! - """ - # DataFrame Extension Properties/Attributes - _adjusted = None - _cores = cpu_count() - _custom = None - _df = DataFrame() - _ds = "yf" if Imports["yfinance"] else None - _exchange = "NYSE" - _last_run = get_time(_exchange, to_string=True) - _time_range = "years" - - - def __init__(self, obj: SeriesFrame): - v_dataframe(obj) - self._df = obj - self._last_run = get_time(self._exchange, to_string=True) - - - # DataFrame Behavioral Methods - def __call__( - self, kind: str = None, timed: bool = False, - version: bool = False, **kwargs: DictLike - ): - if version: - print(f"Pandas TA - Technical Analysis Indicators - v{version}") - try: - if isinstance(kind, str): - # Get the indicator named "kind" as fn - kind = kind.lower() - - # if kind == "ta": - # self.help() - - fn = getattr(self, kind) - - if timed: - stime = perf_counter() - - # Run the indicator - # Equivalent: fn(**kwargs) = getattr(self, kind)(**kwargs) - result = fn(**kwargs) - - if timed: - result.timed = final_time(stime) - print(f"[+] {kind}: {result.timed}") - - self._last_run = get_time(self.exchange, to_string=True) - return result - else: - self.help() - - except BaseException: - pass - - - @property - def adjusted(self) -> str: - return self._adjusted - - - @adjusted.setter - def adjusted(self, name: str) -> None: - if name is not None and isinstance(name, str): - self._adjusted = name - else: - self._adjusted = None - - - @property - def cores(self) -> Int: - return self._cores - - @cores.setter - def cores(self, cpus: Int) -> None: - _cpus = cpu_count() - if cpus is not None and isinstance(cpus, int): - self._cores = int(cpus) if 0 <= cpus <= _cpus else _cpus - else: - self._cores = _cpus - - - @property - def exchange(self) -> str: - return self._exchange - - @exchange.setter - def exchange(self, value: str) -> None: - if value is not None and isinstance(value, str) and value in EXCHANGE_TZ.keys(): - self._exchange = value - - - @property - def time_range(self) -> IntFloat: - return total_time(self._df, self._time_range) - - - @time_range.setter - def time_range(self, value: str) -> None: - if value is not None and isinstance(value, str): - self._time_range = value - else: - self._time_range = "years" - - - # Private DataFrame Methods - def _add_prefix_suffix(self, - result: MaybeSeriesFrame = None, **kwargs: DictLike - ) -> MaybeSeriesFrame: - """Add prefix and/or suffix to the result columns""" - if result is None: - return - else: - prefix = suffix = "" - delimiter = kwargs.setdefault("delimiter", "_") - - if "prefix" in kwargs: - prefix = f"{kwargs['prefix']}{delimiter}" - if "suffix" in kwargs: - suffix = f"{delimiter}{kwargs['suffix']}" - - if isinstance(result, Series): - result.name = prefix + result.name + suffix - else: - result.columns = [prefix + column + suffix for column in result.columns] - - - def _append(self, - result: MaybeSeriesFrame = None, **kwargs: DictLike - ) -> MaybeSeriesFrame: - """Appends a Pandas Series or DataFrame columns to self._df.""" - if result is None: return - - if "col_names" in kwargs and not isinstance(kwargs["col_names"], tuple): - # Note: tuple(kwargs["col_names"]) doesn't work - kwargs["col_names"] = (kwargs["col_names"],) - - df = self._df - if isinstance(result, DataFrame): - simplefilter(action="ignore", category=PerformanceWarning) - pd_options.mode.chained_assignment = None - - # Rename the columns if kwargs["col_names"] - if "col_names" in kwargs and isinstance(kwargs["col_names"], tuple): - if len(kwargs["col_names"]) >= len(result.columns): - for col, ind_name in zip(result.columns, kwargs["col_names"]): - df[ind_name] = result.loc[:, col] - else: - print(f"[!] Not enough col_names were specified : got {len(kwargs['col_names'])}, expected {len(result.columns)}.") - return - else: - for i, column in enumerate(result.columns): - df.loc[:, (column)] = result.iloc[:, i] - else: - ind_name = ( - kwargs["col_names"][0] - if "col_names" in kwargs and isinstance(kwargs["col_names"], tuple) - else result.name - ) - df.loc[:, (ind_name)] = result - - - def _check_na_columns(self): - """Returns the columns in which all it's values are na.""" - return [x for x in self._df.columns if all(self._df[x].isna())] - - - def _get_column(self, series: Union[Series, str, None]): - """Attempts to get the correct series or 'column' and return it.""" - df = self._df - if df is None: return - - # Explicitly passing a pd.Series to override default. - if isinstance(series, Series): - return series - # Apply default if no series nor a default. - elif series is None: - return df[self.adjusted] if self.adjusted is not None else None - # Ok. So it's a str. - elif isinstance(series, str): - # Return the df column since it's in there. - if series in df.columns: - return df[series] - else: - # Attempt to match the 'series' because it was likely - # misspelled. - matches = df.columns.str.match(series, case=False) - match = [i for i, x in enumerate(matches) if x] - # If found, awesome. Return it or return the 'series'. - NOT_FOUND = f"[X] The '{series}' column was not found in" - cols = ", ".join(list(df.columns)) - - if len(df.columns): NOT_FOUND += f": {cols}" - else: NOT_FOUND += " the DataFrame" - - if len(match): - return df.iloc[:, match[0]] - else: - print(NOT_FOUND) - - - def _indicators_by_category(self, name: str) -> List: - """Returns indicators by Categorical name.""" - return Category[name] if name in self.categories() else None - - - def _mp_worker(self, arguments: Tuple): - """Multiprocessing Worker to handle different Methods.""" - method, args, kwargs = arguments - - if method != "ichimoku": - return getattr(self, method)(*args, **kwargs) - else: - return getattr(self, method)(*args, **kwargs)[0] - - - def _post_process(self, - result: Union[Series, DataFrame], **kwargs: DictLike - ) -> Union[Series, DataFrame]: - """Applies any additional modifications to the DataFrame - - * Applies prefixes and/or suffixes - * Appends the result to main DataFrame - """ - verbose = kwargs.pop("verbose", False) - if not isinstance(result, (Series, DataFrame)): - if verbose: - print(f"[X] The result is not a Series or DataFrame.") - return self._df - else: - # Append only specific columns to the dataframe (via - # 'col_numbers':(0,1,3) for example) - result = ( - result.iloc[:, [int(n) for n in kwargs["col_numbers"]]] - if isinstance(result, DataFrame) and - "col_numbers" in kwargs and - kwargs["col_numbers"] is not None else result - ) - # Add prefix/suffix and append to the dataframe - self._add_prefix_suffix(result=result, **kwargs) - - if "append" in kwargs and isinstance(kwargs["append"], bool): - if not kwargs["append"]: - # Issue 388 - No appending, just print to stdout - # No DatetimeIndex could break execution. - print(result) - else: - # Default: Appends result to DataFrame - self._append(result=result, **kwargs) - return result - - - def _study_mode(self, *args: Args) -> Tuple: - """Returns tuple: (name:str, mode:dict)""" - name = "All" - mode = {"all": False, "category": False, "custom": False} - - if len(args) == 0: - mode["all"] = True - else: - _categories = self.categories() - if isinstance(args[0], str): - if args[0].lower() == "all": - name, mode["all"] = name, True - if args[0].lower() in _categories: - name, mode["category"] = args[0], True - - if isinstance(args[0], Study): - study_ = args[0] - if study_.ta is None or study_.name.lower() == "all": - name, mode["all"] = name, True - elif study_.name.lower() in _categories: - name, mode["category"] = study_.name, True - else: - name, mode["custom"] = study_.name, True - - return name, mode - - - # Public DataFrame Methods - def baseline(self, - zero: bool = False, index: int = 0, - k: IntFloat = 1, to_log: bool = False, save: bool = False - ) -> DataFrame: - """baseline - - This method updates the DataFrame _ohlc_ values with a baseline - of ```k=1```. Useful for comparisons. - - Parameters: - zero (bool): Zero the _ohlc_ data. - index (bool): Index to baseline at. - k (IntFloat): Scaler. - to_log (bool): Pre apply ```np.log```. - save (bool): Preserve _ohlc_ when using ```to_log```. - """ - open_ = self._get_column("open") - high = self._get_column("high") - low = self._get_column("low") - close = self._get_column("close") - - zero = v_bool(zero, False) - index = v_pos_default(index, 0) - k = v_scalar(k, 1) - to_log = v_bool(to_log, False) - save = v_bool(save, False) - - if index >= self._df.shape[0]: - index = self._df.shape[0] - 1 - - if to_log: - if save: - self._df["_open"] = open_ - self._df["_high"] = high - self._df["_low"] = low - self._df["_close"] = close - - open_ = log(open_) - high = log(high) - low = log(low) - close = log(close) - - self._df.loc[:, (open_.name)] = k * open_ / open_.iloc[index] - self._df.loc[:, (high.name)] = k * high / high.iloc[index] - self._df.loc[:, (low.name)] = k * low / low.iloc[index] - self._df.loc[:, (close.name)] = k * close / close.iloc[index] - - if zero: - self._df.loc[:, (open_.name)] -= k - self._df.loc[:, (high.name)] -= k - self._df.loc[:, (low.name)] -= k - self._df.loc[:, (close.name)] -= k - - - def categories(self) -> ListStr: - """categories - - List of categories. - - Returns: - (ListStr): List of the indicator categories. - """ - return list(Category.keys()) - - - def constants(self, append: bool, values: Array | List) -> PandasDTypeLike | None: - """constants - - Concatenate / Drop constant(s) to the DataFrame. - - Parameters: - append (bool): Concatenate if ```True```. Drop if ```False```. - Default: ```None``` - values (Array): List/Numpy array of ```values``` to append/drop from - the DataFrame. - - Returns: - (pd.Series, pd.DataFrame, None): Depends upon parameters. - - See Also: - * [TA DataFrame Constants](../../support/how-to.md) - """ - if isinstance(values, ndarray) or isinstance(values, list): - if append: - for x in values: - self._df[f"{x}"] = x - return self._df[self._df.columns[-len(values):]] - else: - for x in values: - del self._df[f"{x}"] - - - def datetime_ordered(self) -> bool: - """datetime_ordered - - DataFrame DateTime ordered? - - Returns: - (bool): ```True``` if the DataFrame is DateTime ordered, - otherwise ```False```. - """ - return v_datetime_ordered(self._df) - - - def help(self, s: str ="") -> None | TextIO: - """help - - Help! - - Parameters: - s (str): String to search for. Default: ```""``` - - Returns: - (None | TextIO): Opens web browser to relevant Pandas TA website - page or prints all search keywords. - """ - return help(s) - - - def indicators(self, as_list: bool = None, exclude: ListStr = None) -> TextIO | ListStr: - """indicators - - List indicators. - - Parameters: - as_list (bool): Return as a list. Default: ```False``` - exclude (ListStr): The passed in list will be excluded - from the indicators list. Default: ```None``` - - Returns: - (TextIO | ListStr): Prints list or returns a ```ListStr```. - """ - as_list = bool(as_list) if isinstance(as_list, bool) else False - user_excluded = [] - if isinstance(exclude, list) and len(exclude): - user_excluded = exclude - - # Public DataFrame Extension methods - df_ext_methods = [ - "baseline", - "categories", - "constants", - "datetime_ordered", - "help", - "indicators", - "last_run", - "reverse", - "study", - "ticker", - "to_utc", - ] - # Public df.ta.properties - ta_properties = [ - "adjusted", - "cores", - # "custom", - # "ds", - "exchange", - "time_range" - ] - - # Public non-indicator methods - ta_indicators = list((x for x in dir(DataFrame().ta) if not x.startswith("_") and not x.endswith("_"))) - - # Add Pandas TA methods and properties to be removed - removed = df_ext_methods + ta_properties - - # Add user excluded methods to be removed - if isinstance(user_excluded, list) and len(user_excluded) > 0: - removed += user_excluded - - # Remove the unwanted indicators - [ta_indicators.remove(x) for x in removed] - - # If as a list, immediately return - if as_list: - return ta_indicators - - indicator_count = len(ta_indicators) - header = f"Pandas TA - Technical Analysis Indicators - v{version}" - - s, _count = f"{header}\n", 0 - if indicator_count > 0: - from pandas_ta.candle.cdl_pattern import ALL_PATTERNS - s += f"\nIndicators and Utilities [{indicator_count}]:\n {', '.join(ta_indicators)}\n" - _count += indicator_count - if Imports["talib"]: - s += f"\nCandle Patterns [{len(ALL_PATTERNS)}]:\n {', '.join(ALL_PATTERNS)}\n" - _count += len(ALL_PATTERNS) - s += f"\nTotal Candles, Indicators and Utilities: {_count}" - print(s) - - - def last_run(self) -> str: - """last_run - - Detailed string of last run time. - - Returns: - (str): Detailed date and time of the lastest run. - """ - return self._last_run - - - def reverse(self) -> None: - """reverse - - Reverse the DataFrame inplace. - - Returns: - (None): DataFrame reversed inplace. - """ - self._df.index = self._df.iloc[::-1].index - - - def study(self, *args: Args, **kwargs: DictLike) -> dataclass: - """study - - Applies the ```ta``` listed in a [```Study```](../studies.md). - - Other Parameters: - chunksize (int): Multiprocessing Pool chunksize. - Default: ```df.ta.cores``` - cores (int): Number of Multiprocessing cores. - Default: ```df.ta.cores``` - exclude (ListStr): List of indicator names. Default: ```[]``` - ordered (bool): Run ```ta``` in order. Default: ```True``` - returns (bool): Return the DataFrame. Default: ```False``` - timed (bool): Print the process time. Default: ```False``` - verbose (bool): More verbose output. Default: ```False``` - - Note: Multiprocessing - Multiprocessing is **not** viable or efficient for some cases. - Testing is required per case. See [Multiprocessing](https://docs.python.org/3.12/library/multiprocessing.html) - for more information. - """ - all_ordered = kwargs.pop("ordered", True) - # Append indicators to the DataFrame by default - kwargs.setdefault("append", True) - # If True, it returns the resultant DataFrame. Default: False - returns = kwargs.pop("returns", False) - - mp_chunksize = kwargs.pop("chunksize", self.cores) - cores = kwargs.pop("cores", self.cores) - self.cores = cores - - # Initialize - initial_column_count = self._df.shape[1] - excluded = ["long_run", "short_run", "tsignals", "xsignals"] - - # Get the Study Name and mode - name, mode = self._study_mode(*args) - - # If All or a Category, exclude user list if any - user_excluded = kwargs.pop("exclude", []) - if isinstance(user_excluded, str) and len(user_excluded) > 1: - user_excluded = [user_excluded] - if mode["all"] or mode["category"]: - excluded += user_excluded - - # Collect the indicators, remove excluded or include kwarg["append"] - if mode["category"]: - ta = self._indicators_by_category(name.lower()) - [ta.remove(x) for x in excluded if x in ta] - elif mode["custom"]: - if hasattr(args[0], "cores") and isinstance(args[0].cores, int): - self.cores = min(args[0].cores, self.cores) - ta = args[0].ta - for kwds in ta: - kwds["append"] = True - elif mode["all"]: - ta = self.indicators(as_list=True, exclude=excluded) - else: - print(f"[X] Study not available.") - return None - - verbose = kwargs.pop("verbose", False) - if verbose: - print(f"[+] Study: {name}\n[i] Indicator arguments: {kwargs}") - if mode["all"] or mode["category"]: - excluded_str = ", ".join(excluded) - print(f"[i] Excluded[{len(excluded)}]: {excluded_str}") - - timed = kwargs.pop("timed", False) - results = [] - use_multiprocessing = True if self.cores > 0 else False - has_col_names = False - - if timed: - stime = perf_counter() - - if use_multiprocessing and mode["custom"]: - # Determine if the Custom Study has "col_names" key - has_col_names = (True if len([ - True for x in ta - if "col_names" in x and isinstance(x["col_names"], tuple) - ]) else False) - - if has_col_names: - use_multiprocessing = False - print(f"[i] Multiprocessing is disabled (cores=0) when using custom \"col_names\".") - - if use_multiprocessing: - _total_ta = len(ta) - with Pool(self.cores) as pool: - # Some magic to optimize chunksize for speed - # based on total ta indicators - if mp_chunksize > _total_ta: - _chunksize = mp_chunksize - 1 - elif mp_chunksize > 0: - _chunksize = mp_chunksize - else: - _chunksize = int(log10(_total_ta)) + 1 - if verbose: - print(f"[i] Multiprocessing {_total_ta} indicators with chunksize {_chunksize} and {self.cores}/{cpu_count()} cpus.") - - results = None - if mode["custom"]: - # Create a list of all the custom indicators into a list - custom_ta = [( - ind["kind"], - ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else (), - {**ind, **kwargs}, - ) for ind in ta] - # Custom multiprocessing pool. Must be ordered for Chained Strategies - # May fix this to cpus if Chaining/Composition if it remains - if verbose: - results = tqdm(pool.map(self._mp_worker, custom_ta, _chunksize), total=len(custom_ta) // _chunksize) - else: - results = pool.map(self._mp_worker, custom_ta, _chunksize) - else: - default_ta = [(ind, tuple(), kwargs) for ind in ta] - tqdm_total = len(default_ta) // _chunksize - # All and Categorical multiprocessing pool. - if all_ordered: - if verbose: - results = tqdm(pool.imap(self._mp_worker, default_ta, _chunksize), total=tqdm_total) # Order over Speed - else: - results = pool.imap(self._mp_worker, default_ta, _chunksize) # Order over Speed - else: - if verbose: - results = tqdm(pool.imap_unordered(self._mp_worker, default_ta, _chunksize), total=tqdm_total) # Speed over Order - else: - results = pool.imap_unordered(self._mp_worker, default_ta, _chunksize) # Speed over Order - if results is None: - print(f"[X] ta.study('{name}') has no results.") - return - - pool.close() - pool.join() - self._last_run = get_time(self.exchange, to_string=True) - - else: - # Without multiprocessing: - if verbose: - _col_msg = f"[i] No multiprocessing. (cores = 0)" - if has_col_names: - _col_msg = f"[i] No multiprocessing support with the 'col_names' keyword." - print(_col_msg) - - if mode["custom"]: - if verbose: - pbar = tqdm(ta, f"[i] Progress") - for ind in pbar: - params = ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else tuple() - getattr(self, ind["kind"])(*params, **{**ind, **kwargs}) - else: - for ind in ta: - params = ind["params"] if "params" in ind and isinstance(ind["params"], tuple) else tuple() - getattr(self, ind["kind"])(*params, **{**ind, **kwargs}) - else: - if verbose: - pbar = tqdm(ta, f"[i] Progress") - for ind in pbar: - getattr(self, ind)(*tuple(), **kwargs) - else: - for ind in ta: - getattr(self, ind)(*tuple(), **kwargs) - self._last_run = get_time(self.exchange, to_string=True) - - # Apply prefixes/suffixes and appends indicator results to the DataFrame - [self._post_process(r, **kwargs) for r in results] - - final_column_count = self._df.shape[1] - _added_columns = final_column_count - initial_column_count - - if verbose: - print(f"[i] Total indicators: {len(ta)}") - print(f"[i] Columns added: {_added_columns}") - print(f"[i] Last Run: {self._last_run}") - if timed: - ft = final_time(stime) - if _added_columns > 0: - avgtd = (perf_counter() - stime) / _added_columns - else: - avgtd = perf_counter() - stime - print(f"[i] Pandas TA Time: {ft} for {_added_columns} columns (avg {avgtd * 1000:2.4f} ms / col)") - - if returns: - return self._df - - - def ticker(self, - ticker: str = None, period: str = None, interval: str = None, - study: Study = None, proxy: dict = None, - timed: bool = False, **kwargs: DictLike - ): - """ticker - - Download Historical _ohlcv_ data as a Pandas DataFrame if _yfinance_ - package is installed. It also can run a ```ta.Study``` afterwards. - - Parameters: - ticker (str): Any string for a ticker you would use - with ```yfinance```. Default: ```"SPY"``` - period (str): See the yfinance ```history()``` method for - more options. Default: ```"max"``` - interval (str): Default: ```"1d"``` - study (ta.Study | str): After downloading, apply ```Study``` - Default: ```None``` - proxy (dict): Proxy dictionary. Default: ```{}``` - timed (bool): Print download time to stdout. Default: ```False``` - - Returns: - (DataFrame | None): _ohlcv_ ```df``` or ```None``` - - Tip: YFinance ```history``` parameters - * [_yfinance_](https://ranaroussi.github.io/yfinance/index.html) - * _yfinance_ [```history()```](https://github.com/ranaroussi/yfinance/blob/main/yfinance/scrapers/history.py) - - Example: - ```py - import panadas as pd - import pandas_ta as ta - - # Simple - df = pd.DataFrame().ta.ticker("SPY", period="2y", timed=True) - - # Built In Study - df = pd.DataFrame().ta.ticker("SPY", period="2y", study=ta.AllStudy, timed=True) - ``` - """ - if self._ds is None: - print(f"[X] Please install yfinance to use this method. (pip install yfinance)") - return - - ticker = v_str(ticker, "SPY") - period = v_str(period, "max") - interval = v_str(interval, "1d") - proxy = proxy if isinstance(proxy, dict) else {} - timed = v_bool(timed, False) - - df, stime = None, None - if self._ds == "yf" and ticker is not None: - import yfinance as yf - yft = yf.Ticker(ticker) - - if timed: stime = perf_counter() - df = yft.history( - period=period, interval=interval, - proxy=proxy, **kwargs - ) - df.name = ticker - else: - return None - - if timed: - df.timed = final_time(stime) - print(f"[+] yf | {ticker}{df.shape}: {df.timed}") - - self._df = df - - if study is not None and isinstance(study, Study): - self.study(study, timed=timed, **kwargs) - - return self._df - - - def to_utc(self) -> None: - """to_utc - - Set the DataFrame index to UTC. - - Returns: - (None): Performs the operation. - """ - self._df = to_utc(self._df) - - - # def version(self) -> str: - # return version - - - # Public DataFrame Methods: Indicators and Utilities - # Candles - def cdl_pattern(self, name: str = "all", offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = cdl_pattern(open_=open_, high=high, low=low, close=close, name=name, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cdl_z(self, full=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = cdl_z(open_=open_, high=high, low=low, close=close, full=full, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ha(self, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = ha(open_=open_, high=high, low=low, close=close, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Cycles - def ebsw(self, close=None, length=None, bars=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ebsw(close=close, length=length, bars=bars, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def reflex(self, close=None, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = reflex(close=close, length=length, smooth=smooth, alpha=alpha, pi=pi, sqrt2=sqrt2, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Momentum - def ao(self, fast=None, slow=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = ao(high=high, low=low, fast=fast, slow=slow, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def apo(self, fast=None, slow=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = apo(close=close, fast=fast, slow=slow, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def bias(self, length=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = bias(close=close, length=length, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def bop(self, percentage=False, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = bop(open_=open_, high=high, low=low, close=close, percentage=percentage, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def brar(self, length=None, scalar=None, drift=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = brar(open_=open_, high=high, low=low, close=close, length=length, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cci(self, length=None, c=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = cci(high=high, low=low, close=close, length=length, c=c, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cfo(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = cfo(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cg(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = cg(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cmo(self, length=None, scalar=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = cmo(close=close, length=length, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def coppock(self, length=None, fast=None, slow=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = coppock(close=close, length=length, fast=fast, slow=slow, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def crsi(self, rsi_length=None, streak_length=None, rank_length=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = crsi(close=close, rsi_length=rsi_length, streak_length=streak_length, rank_length=rank_length, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cti(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = cti(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def dm(self, drift=None, offset=None, mamode=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = dm(high=high, low=low, drift=drift, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def er(self, length=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = er(close=close, length=length, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def eri(self, length=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = eri(high=high, low=low, close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def exhc(self, length=None, cap=None, asint=None, show_all=None, nozeros=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = exhc(close=close, length=length, cap=cap, asint=asint, show_all=show_all, nozeros=nozeros, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def fisher(self, length=None, signal=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = fisher(high=high, low=low, length=length, signal=signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def inertia(self, length=None, rvi_length=None, scalar=None, refined=None, thirds=None, mamode=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - if refined is not None or thirds is not None: - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = inertia(close=close, high=high, low=low, length=length, rvi_length=rvi_length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs) - else: - result = inertia(close=close, length=length, rvi_length=rvi_length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs) - - return self._post_process(result, **kwargs) - - def kdj(self, length=None, signal=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = kdj(high=high, low=low, close=close, length=length, signal=signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def kst(self, roc1=None, roc2=None, roc3=None, roc4=None, sma1=None, sma2=None, sma3=None, sma4=None, signal=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = kst(close=close, roc1=roc1, roc2=roc2, roc3=roc3, roc4=roc4, sma1=sma1, sma2=sma2, sma3=sma3, sma4=sma4, signal=signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def macd(self, fast=None, slow=None, signal=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = macd(close=close, fast=fast, slow=slow, signal=signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def mom(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = mom(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pgo(self, length=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = pgo(high=high, low=low, close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ppo(self, fast=None, slow=None, scalar=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ppo(close=close, fast=fast, slow=slow, scalar=scalar, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def psl(self, open_=None, length=None, scalar=None, drift=None, offset=None, **kwargs): - if open_ is not None: - open_ = self._get_column(kwargs.pop("open", "open")) - - close = self._get_column(kwargs.pop("close", "close")) - result = psl(close=close, open_=open_, length=length, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def qqe(self, length=None, smooth=None, factor=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = qqe(close=close, length=length, smooth=smooth, factor=factor, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def roc(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = roc(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rsi(self, length=None, scalar=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = rsi(close=close, length=length, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rsx(self, length=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = rsx(close=close, length=length, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rvgi(self, length=None, swma_length=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = rvgi(open_=open_, high=high, low=low, close=close, length=length, swma_length=swma_length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def slope(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = slope(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def smc(self, abr_length=None, close_length=None, vol_length=None, percent=None, vol_ratio=None, asint=None, mamode=None, talib=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = smc(open_=open_, high=high, low=low, close=close, abr_length=abr_length, close_length=close_length, vol_length=vol_length, percent=percent, vol_ratio=vol_ratio, asint=asint, mamode=mamode, talib=talib, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def smi(self, fast=None, slow=None, signal=None, scalar=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = smi(close=close, fast=fast, slow=slow, signal=signal, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def squeeze(self, bb_length=None, bb_std=None, kc_length=None, kc_scalar=None, mom_length=None, mom_smooth=None, use_tr=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = squeeze(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length, kc_scalar=kc_scalar, mom_length=mom_length, mom_smooth=mom_smooth, use_tr=use_tr, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def squeeze_pro(self, bb_length=None, bb_std=None, kc_length=None, kc_scalar_wide=None, kc_scalar_normal=None, kc_scalar_narrow=None, mom_length=None, mom_smooth=None, use_tr=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = squeeze_pro(high=high, low=low, close=close, bb_length=bb_length, bb_std=bb_std, kc_length=kc_length, kc_scalar_wide=kc_scalar_wide, kc_scalar_normal=kc_scalar_normal, kc_scalar_narrow=kc_scalar_narrow, mom_length=mom_length, mom_smooth=mom_smooth, use_tr=use_tr, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def stc(self, tclength=None, ma1=None, ma2=None, osc=None, fast=None, slow=None, factor=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = stc(close=close, tclength=tclength, ma1=ma1, ma2=ma2, osc=osc, fast=fast, slow=slow, factor=factor, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def stoch(self, k=None, d=None, smooth_k=None, mamode=None, talib=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = stoch(high=high, low=low, close=close, k=k, d=d, smooth_k=smooth_k, mamode=mamode, talib=talib, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def stochf(self, k=None, d=None, mamode=None, talib=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = stochf(high=high, low=low, close=close, k=k, d=d, mamode=mamode, talib=talib, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def stochrsi(self, length=None, rsi_length=None, k=None, d=None, mamode=None, talib=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = stochrsi(high=high, low=low, close=close, length=length, rsi_length=rsi_length, k=k, d=d, mamode=mamode, talib=talib, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tmo(self, tmo_length=None, calc_length=None, smooth_length=None, mamode=None, compute_momentum=False, normalize_signal=False, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - close = self._get_column(kwargs.pop("close", "close")) - result = tmo(open_=open_, close=close, tmo_length=tmo_length, calc_length=calc_length, smooth_length=smooth_length, mamode=mamode, compute_momentum=compute_momentum, normalize_signal=normalize_signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def trix(self, length=None, signal=None, scalar=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = trix(close=close, length=length, signal=signal, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tsi(self, fast=None, slow=None, drift=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = tsi(close=close, fast=fast, slow=slow, drift=drift, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def uo(self, fast=None, medium=None, slow=None, fast_w=None, medium_w=None, slow_w=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = uo(high=high, low=low, close=close, fast=fast, medium=medium, slow=slow, fast_w=fast_w, medium_w=medium_w, slow_w=slow_w, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def willr(self, length=None, percentage=True, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = willr(high=high, low=low, close=close, length=length, percentage=percentage, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Overlap - def alligator(self, jaw=None, teeth=None, lips=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = alligator(close=close, jaw=jaw, teeth=teeth, lips=lips, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def alma(self, length=None, sigma=None, distribution_offset=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = alma(close=close, length=length, sigma=sigma, distribution_offset=distribution_offset, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def dema(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = dema(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ema(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ema(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def fwma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = fwma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hilo(self, high_length=None, low_length=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = hilo(high=high, low=low, close=close, high_length=high_length, low_length=low_length, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hl2(self, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = hl2(high=high, low=low, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hlc3(self, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = hlc3(high=high, low=low, close=close, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hma(self, length=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = hma(close=close, length=length, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hwma(self, na=None, nb=None, nc=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = hwma(close=close, na=na, nb=nb, nc=nc, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def jma(self, length=None, phase=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = jma(close=close, length=length, phase=phase, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def kama(self, length=None, fast=None, slow=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = kama(close=close, length=length, fast=fast, slow=slow, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ichimoku(self, tenkan=None, kijun=None, senkou=None, include_chikou=True, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result, span = ichimoku(high=high, low=low, close=close, tenkan=tenkan, kijun=kijun, senkou=senkou, include_chikou=include_chikou, offset=offset, **kwargs) - self._add_prefix_suffix(result, **kwargs) - self._add_prefix_suffix(span, **kwargs) - self._append(result, **kwargs) - # return self._post_process(result, **kwargs), span - return result, span - - def linreg(self, length=None, offset=None, adjust=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = linreg(close=close, length=length, offset=offset, adjust=adjust, **kwargs) - return self._post_process(result, **kwargs) - - def mama(self, fastlimit=None, slowlimit=None, prenan=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = mama(close=close, fastlimit=fastlimit, slowlimit=slowlimit, prenan=prenan, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def mcgd(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = mcgd(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def midpoint(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = midpoint(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def midprice(self, length=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = midprice(high=high, low=low, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ohlc4(self, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = ohlc4(open_=open_, high=high, low=low, close=close, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pivots(self, method=None, anchor=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = pivots(open_=open_, high=high, low=low, close=close, method=method, anchor=anchor, **kwargs) - return self._post_process(result, **kwargs) - - def pwma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = pwma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = rma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rwi(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = rwi(high=high, low=low, close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def sinwma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = sinwma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def sma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = sma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def smma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = smma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ssf(self, length=None, everget=None, pi=None, sqrt2=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ssf(close=close, length=length, everget=everget, pi=pi, sqrt2=sqrt2, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ssf3(self, length=None, pi=None, sqrt3=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ssf3(close=close, length=length, pi=pi, sqrt3=sqrt3, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def supertrend(self, length=None, multiplier=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = supertrend(high=high, low=low, close=close, length=length, multiplier=multiplier, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def swma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = swma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def t3(self, length=None, a=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = t3(close=close, length=length, a=a, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tema(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = tema(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def trima(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = trima(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vidya(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = vidya(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def wcp(self, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = wcp(high=high, low=low, close=close, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def wma(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = wma(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def zlma(self, length=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = zlma(close=close, length=length, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Performance - def log_return(self, length=None, cumulative=False, percent=False, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = log_return(close=close, length=length, cumulative=cumulative, percent=percent, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def percent_return(self, length=None, cumulative=False, percent=False, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = percent_return(close=close, length=length, cumulative=cumulative, percent=percent, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Statistics - def entropy(self, length=None, base=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = entropy(close=close, length=length, base=base, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def kurtosis(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = kurtosis(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def mad(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = mad(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def median(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = median(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def quantile(self, length=None, q=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = quantile(close=close, length=length, q=q, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def skew(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = skew(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def stdev(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = stdev(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tos_stdevall(self, length=None, stds=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = tos_stdevall(close=close, length=length, stds=stds, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def variance(self, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = variance(close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def zscore(self, length=None, std=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = zscore(close=close, length=length, std=std, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Trend - def adx(self, length=None, lensig=None, mamode=None, scalar=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = adx(high=high, low=low, close=close, length=length, lensig=lensig, mamode=mamode, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def alphatrend(self, volume=None, src=None, length=None, multiplier=None, threshold=None, lag=None, mamode=None, talib=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - if volume is not None: - volume = self._get_column(kwargs.pop("volume", "volume")) - result = alphatrend(open_=open_, high=high, low=low, close=close, volume=volume, src=src, length=length, multiplier=multiplier, threshold=threshold, lag=lag, mamode=mamode, talib=talib, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def amat(self, fast=None, slow=None, mamode=None, lookback=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = amat(close=close, fast=fast, slow=slow, mamode=mamode, lookback=lookback, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def aroon(self, length=None, scalar=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = aroon(high=high, low=low, length=length, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def chop(self, length=None, atr_length=None, ln=None, scalar=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = chop(high=high, low=low, close=close, length=length, atr_length=atr_length, ln=ln, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cksp(self, p=None, x=None, q=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = cksp(high=high, low=low, close=close, p=p, x=x, q=q, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def decay(self, length=None, mode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = decay(close=close, length=length, mode=mode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def decreasing(self, length=None, strict=None, asint=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = decreasing(close=close, length=length, strict=strict, asint=asint, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def dpo(self, length=None, centered=True, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = dpo(close=close, length=length, centered=centered, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ht_trendline(self, talib=None, prenan=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ht_trendline(close=close, talib=talib, prenan=prenan, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def increasing(self, length=None, strict=None, asint=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = increasing(close=close, length=length, strict=strict, asint=asint, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def long_run(self, fast=None, slow=None, length=None, offset=None, **kwargs): - if fast is None and slow is None: - return self._df - else: - result = long_run(fast=fast, slow=slow, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def psar(self, af0=None, af=None, max_af=None, tv=False, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", None)) - result = psar(high=high, low=low, close=close, af0=af0, af=af, max_af=max_af, tv=tv, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def qstick(self, length=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - close = self._get_column(kwargs.pop("close", "close")) - result = qstick(open_=open_, close=close, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rwi(self, length=None, lensig=None, mamode=None, scalar=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = rwi(high=high, low=low, close=close, length=length, lensig=lensig, mamode=mamode, scalar=scalar, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def short_run(self, fast=None, slow=None, length=None, offset=None, **kwargs): - if fast is None and slow is None: - return self._df - else: - result = short_run(fast=fast, slow=slow, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def supertrend(self, period=None, multiplier=None, mamode=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = supertrend(high=high, low=low, close=close, period=period, multiplier=multiplier, mamode=mamode, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def trendflex(self, close=None, length=None, smooth=None, alpha=None, pi=None, sqrt2=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = trendflex(close=close, length=length, smooth=smooth, alpha=alpha, pi=pi, sqrt2=sqrt2, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tsignals(self, trend=None, asbool=None, trend_reset=None, trend_offset=None, offset=None, **kwargs): - if trend is None: - return self._df - else: - result = tsignals(trend, asbool=asbool, trend_offset=trend_offset, trend_reset=trend_reset, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vhf(self, length=None, drift=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = vhf(close=close, length=length, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vortex(self, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = vortex(high=high, low=low, close=close, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def xsignals(self, signal=None, xa=None, xb=None, above=None, long=None, asbool=None, trend_reset=None, trend_offset=None, offset=None, **kwargs): - if signal is None: - return self._df - else: - result = xsignals(signal=signal, xa=xa, xb=xb, above=above, long=long, asbool=asbool, trend_offset=trend_offset, trend_reset=trend_reset, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def zigzag(self, close=None, legs=None, deviation=None, retrace=None, last_extreme=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - if close is not None: - close = self._get_column(kwargs.pop("close", "close")) - result = zigzag(high=high, low=low, close=close, legs=legs, deviation=deviation, retrace=retrace, last_extreme=last_extreme, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Volatility - def aberration(self, length=None, atr_length=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = aberration(high=high, low=low, close=close, length=length, atr_length=atr_length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def accbands(self, length=None, c=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = accbands(high=high, low=low, close=close, length=length, c=c, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def atr(self, length=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = atr(high=high, low=low, close=close, length=length, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def atrts(self, length=None, ma_length=None, multiplier=None, mamode=None, talib=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = atrts(high=high, low=low, close=close, length=length, ma_length=ma_length, multiplier=multiplier, mamode=mamode, talib=talib, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def bbands(self, length=None, lower_std=None, upper_std=None, mamode=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = bbands(close=close, length=length, lower_std=lower_std, upper_std=upper_std, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def chandelier_exit(self, high_length=None, low_length=None, atr_length=None, multiplier=None, mamode=None, talib=None, use_close=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = chandelier_exit(high=high, low=low, close=close, high_length=high_length, low_length=low_length, atr_length=atr_length, multiplier=multiplier, mamode=mamode, talib=talib, use_close=use_close, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def donchian(self, lower_length=None, upper_length=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = donchian(high=high, low=low, lower_length=lower_length, upper_length=upper_length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def hwc(self, na=None, nb=None, nc=None, nd=None, scalar=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = hwc(close=close, na=na, nb=nb, nc=nc, nd=nd, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def kc(self, length=None, scalar=None, mamode=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = kc(high=high, low=low, close=close, length=length, scalar=scalar, mamode=mamode, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def massi(self, fast=None, slow=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = massi(high=high, low=low, fast=fast, slow=slow, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def natr(self, length=None, mamode=None, scalar=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = natr(high=high, low=low, close=close, length=length, mamode=mamode, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pdist(self, drift=None, offset=None, **kwargs): - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = pdist(open_=open_, high=high, low=low, close=close, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def rvi(self, length=None, scalar=None, refined=None, thirds=None, mamode=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = rvi(high=high, low=low, close=close, length=length, scalar=scalar, refined=refined, thirds=thirds, mamode=mamode, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def thermo(self, long=None, short= None, length=None, mamode=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - result = thermo(high=high, low=low, long=long, short=short, length=length, mamode=mamode, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def true_range(self, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - result = true_range(high=high, low=low, close=close, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def ui(self, length=None, scalar=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - result = ui(close=close, length=length, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - # Volume - def ad(self, open_=None, signed=True, offset=None, **kwargs): - if open_ is not None: - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = ad(high=high, low=low, close=close, volume=volume, open_=open_, signed=signed, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def adosc(self, open_=None, fast=None, slow=None, signed=True, offset=None, **kwargs): - if open_ is not None: - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = adosc(high=high, low=low, close=close, volume=volume, open_=open_, fast=fast, slow=slow, signed=signed, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def aobv(self, fast=None, slow=None, mamode=None, max_lookback=None, min_lookback=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = aobv(close=close, volume=volume, fast=fast, slow=slow, mamode=mamode, max_lookback=max_lookback, min_lookback=min_lookback, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def cmf(self, open_=None, length=None, offset=None, **kwargs): - if open_ is not None: - open_ = self._get_column(kwargs.pop("open", "open")) - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = cmf(high=high, low=low, close=close, volume=volume, open_=open_, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def efi(self, length=None, mamode=None, offset=None, drift=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = efi(close=close, volume=volume, length=length, offset=offset, mamode=mamode, drift=drift, **kwargs) - return self._post_process(result, **kwargs) - - def eom(self, length=None, divisor=None, offset=None, drift=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = eom(high=high, low=low, close=close, volume=volume, length=length, divisor=divisor, offset=offset, drift=drift, **kwargs) - return self._post_process(result, **kwargs) - - def kvo(self, fast=None, slow=None, length_sig=None, mamode=None, offset=None, drift=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = kvo(high=high, low=low, close=close, volume=volume, fast=fast, slow=slow, length_sig=length_sig, mamode=mamode, offset=offset, drift=drift, **kwargs) - return self._post_process(result, **kwargs) - - def mfi(self, length=None, drift=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = mfi(high=high, low=low, close=close, volume=volume, length=length, drift=drift, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def nvi(self, length=None, initial=None, signed=True, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = nvi(close=close, volume=volume, length=length, initial=initial, signed=signed, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def obv(self, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = obv(close=close, volume=volume, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pvi(self, length=None, initial=None, mamode=None, overlay=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvi(close=close, volume=volume, length=length, initial=initial, mamode=mamode, overlay=overlay, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pvo(self, fast=None, slow=None, signal=None, scalar=None, offset=None, **kwargs): - volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvo(volume=volume, fast=fast, slow=slow, signal=signal, scalar=scalar, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pvol(self, volume=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvol(close=close, volume=volume, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def pvr(self, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvr(close=close, volume=volume) - return self._post_process(result, **kwargs) - - def pvt(self, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = pvt(close=close, volume=volume, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def tsv(self, length=None, signal=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = tsv(close=close, volume=volume, signal=signal, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vhm(self, length=None, std_length=None, offset=None, **kwargs): - volume = self._get_column(kwargs.pop("volume", "volume")) - result = vhm(volume=volume, length=length, std_length=std_length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vwap(self, anchor=None, offset=None, **kwargs): - high = self._get_column(kwargs.pop("high", "high")) - low = self._get_column(kwargs.pop("low", "low")) - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - - if not self.datetime_ordered(): - volume.index = self._df.index - - result = vwap(high=high, low=low, close=close, volume=volume, anchor=anchor, offset=offset, **kwargs) - return self._post_process(result, **kwargs) - - def vwma(self, volume=None, length=None, offset=None, **kwargs): - close = self._get_column(kwargs.pop("close", "close")) - volume = self._get_column(kwargs.pop("volume", "volume")) - result = vwma(close=close, volume=volume, length=length, offset=offset, **kwargs) - return self._post_process(result, **kwargs) diff --git a/src/aiomql/ta_libs/pandas_ta/custom.py b/src/aiomql/ta_libs/pandas_ta/custom.py deleted file mode 100644 index e541810..0000000 --- a/src/aiomql/ta_libs/pandas_ta/custom.py +++ /dev/null @@ -1,177 +0,0 @@ -import importlib -import os -import sys -import types -from glob import glob -from os.path import abspath, basename, exists, join, splitext - -from . import __all__ as pandas_ta - -from ._typing import DictLike - - - -def bind(name: str, fn: types.FunctionType, method: types.MethodType = None): - """Bind - - Helper function to bind the function and class method defined in a custom - indicator module to the active pandas_ta instance. - - Parameters: - name (str): The name of the indicator within pandas_ta - fn (types.FunctionType): The indicator function - method (types.MethodType): The class method corresponding to the passed function - """ - setattr(pandas_ta, name, fn) - setattr(pandas_ta.AnalysisIndicators, name, method) - - -def create_dir(path: str, categories: bool = True, verbose: bool = True): - """Create Dir - - Sets up a suitable folder structure for working with custom indicators. - Use it **once** to setup and initialize the custom folder. - - Parameters: - path (str): Indicator directory full path - categories (bool): Create category sub-folders - verbose (bool): Verbose output - """ - - # ensure that the passed directory exists / is readable - if not exists(path): - os.makedirs(path) - if verbose: - print(f"[i] Created main directory '{path}'.") - - # list the contents of the directory - # dirs = glob(abspath(join(path, '*'))) - - # optionally add any missing category subdirectories - if categories: - for _ in [*pandas_ta.Category]: - d = abspath(join(path, _)) - if not exists(d): - os.makedirs(d) - if verbose: - dirname = basename(d) - print(f"[i] Created an empty sub-directory '{dirname}'.") - - -def get_module_functions(module: types.ModuleType) -> DictLike: - """Get Module Functions - - Returns a dictionary with the mapping: "name" to a _function_. - - Parameters: - module (types.ModuleType): python module - - Returns: - (DictLike): Returns a dictionary with the mapping: "name" to a _function_ - - Example: - Example return - ```py - { - "func1_name": func1, - "func2_name": func2, # ... - } - ``` - """ - module_functions = {} - - for name, item in vars(module).items(): - if isinstance(item, types.FunctionType): - module_functions[name] = item - - return module_functions - - -def import_dir(path: str, verbose: bool = True): - """Import Dir - - Import a directory of custom (proprietary) indicators into Pandas TA. - - Parameters: - path (str): Full path to indicator directory. - verbose (bool): Output process to STDOUT. - """ - # ensure that the passed directory exists / is readable - if not exists(path): - print(f"[X] Unable to read the directory '{path}'.") - return - - # list the contents of the directory - dirs = glob(abspath(join(path, "*"))) - - # traverse full directory, importing all modules found there - for d in dirs: - dirname = basename(d) - - # only look in directories which are valid pandas_ta categories - if dirname not in [*pandas_ta.Category]: - if verbose and dirname not in ["__pycache__", "__init__.py"]: - print( - f"[i] Skipping the sub-directory '{dirname}' since it's not a valid pandas_ta category." - ) - continue - - # for each module found in that category (directory)... - for module in glob(abspath(join(path, dirname, "*.py"))): - module_name = splitext(basename(module))[0] - if module_name not in ["__init__"]: - # ensure that the supplied path is included in our python path - if d not in sys.path: - sys.path.append(d) - - # (re)load the indicator module - module_functions = load_indicator_module(module_name) - - # figure out which of the modules functions to bind to pandas_ta - _callable = module_functions.get(module_name, None) - _method_callable = module_functions.get(f"{module_name}_method", None) - - if _callable == None: - print( - f"[X] Unable to find a function named '{module_name}' in the module '{module_name}.py'." - ) - continue - if _method_callable == None: - missing_method = f"{module_name}_method" - print( - f"[X] Unable to find a method function named '{missing_method}' in the module '{module_name}.py'." - ) - continue - - # add it to the correct category if it's not there yet - if module_name not in pandas_ta.Category[dirname]: - pandas_ta.Category[dirname].append(module_name) - - bind(module_name, _callable, _method_callable) - if verbose: - print( - f"[i] Successfully imported the custom indicator '{module}' into category '{dirname}'." - ) - - -def load_indicator_module(name: str) -> dict: - """ - Helper function to (re)load an indicator module. - - Returns: - dict: module functions mapping - ```{ - "func1_name": func1, - "func2_name": func2, # ... - }``` - - """ - try: - module = importlib.import_module(name) - except Exception as ex: - print(f"[X] An error occurred when attempting to load module {name}: {ex}") - sys.exit(1) - - # reload to refresh previously loaded module - module = importlib.reload(module) - return get_module_functions(module) diff --git a/src/aiomql/ta_libs/pandas_ta/cycle/__init__.py b/src/aiomql/ta_libs/pandas_ta/cycle/__init__.py deleted file mode 100644 index ae54cda..0000000 --- a/src/aiomql/ta_libs/pandas_ta/cycle/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# -*- coding: utf-8 -*- -from .ebsw import ebsw -from .reflex import reflex - -__all__ = [ - "ebsw", - "reflex", -] diff --git a/src/aiomql/ta_libs/pandas_ta/cycle/ebsw.py b/src/aiomql/ta_libs/pandas_ta/cycle/ebsw.py deleted file mode 100644 index 290ffdd..0000000 --- a/src/aiomql/ta_libs/pandas_ta/cycle/ebsw.py +++ /dev/null @@ -1,141 +0,0 @@ -from numpy import cos, exp, mean, nan, pi, roll, sin, sqrt, zeros -from pandas import Series -from .._typing import Int -from ..utils import v_bool, v_offset, v_pos_default, v_series - - - -def ebsw( - close: Series, length: Int = None, bars: Int = None, - initial_version: bool = None, - offset: Int = None, **kwargs: dict | None -) -> Series: - """Even Better SineWave - - This indicator attempts to quantify market cycles using a low pass filter. - - Sources: - * [rengel8](https://github.com/rengel8) - * J.F.Ehlers 'Cycle Analytics for Traders', 2014 - * [Pandas TA Issue #350](https://github.com/twopirllc/pandas-ta/issues/350) - * [Proreal Code](https://www.prorealcode.com/prorealtime-indicators/even-better-sinewave/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): Max cycle/trend period. Values between ```40-48``` work - as expected with minimum value: ```39```. Default: ```40``` - bars (int): Period of low pass filtering. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.Series): 1 column - - Note: - The _default_ is more cycle oriented and seems to be less - whipsaw-prune. The older version might offer earlier signals at medium - and stronger reversals. Compared to TradingView, returns very close - results but appears to be one bar earlier. - """ - # Validate - length = v_pos_default(length, 40) - close = v_series(close, length) - - if close is None: - return - - initial_version = v_bool(initial_version, False) - bars = v_pos_default(bars, 10) - offset = v_offset(offset) - - # Calculate - # allow initial version to be used (more responsive/caution!) - m = close.size - if isinstance(initial_version, bool) and initial_version: - # not the default version that is active - alpha1 = hp = 0 # alpha and HighPass - a1 = b1 = c1 = c2 = c3 = 0 - filter_ = power_ = wave = 0 - lastClose = lastHP = 0 - filtHist = [0, 0] # Filter history - - result = [nan for _ in range(0, length - 1)] + [0] - for i in range(length, m): - # HighPass filter cyclic components whose periods are shorter than - # Duration input - alpha1 = (1 - sin(360 / length)) / cos(360 / length) - hp = 0.5 * (1 + alpha1) * (close.iloc[i] - lastClose) + alpha1 * lastHP - - # Smooth with a Super Smoother Filter from equation 3-3 - a1 = exp(-sqrt(2) * pi / bars) - b1 = 2 * a1 * cos(sqrt(2) * 180 / bars) - c2 = b1 - c3 = -1 * a1 * a1 - c1 = 1 - c2 - c3 - filter_ = 0.5 * c1 * (hp + lastHP) + c2 * \ - filtHist[1] + c3 * filtHist[0] - # filter_ = float("{:.8f}".format(float(filter_))) # to fix for - # small scientific notations, the big ones fail - - # 3 Bar average of wave amplitude and power - wave = (filter_ + filtHist[1] + filtHist[0]) / 3 - power_ = (filter_ * filter_ + filtHist[1] * filtHist[1] \ - + filtHist[0] * filtHist[0]) / 3 - # Normalize the Average Wave to Square Root of the Average Power - wave = wave / sqrt(power_) - - # update storage, result - filtHist.append(filter_) # append new filter_ value - # remove first element of list (left) -> updating/trim - filtHist.pop(0) - lastHP = hp - lastClose = close.iloc[i] - result.append(wave) - - else: # Default - lastHP = lastClose = 0 - filtHist = zeros(3) - result = [nan] * (length - 1) + [0] - - angle = 2 * pi / length - alpha1 = (1 - sin(angle)) / cos(angle) - ang = 2 ** .5 * pi / bars - a1 = exp(-ang) - c2 = 2 * a1 * cos(ang) - c3 = -a1 ** 2 - c1 = 1 - c2 - c3 - - for i in range(length, m): - hp = 0.5 * (1 + alpha1) * (close.iloc[i] - lastClose) + alpha1 * lastHP - - # Rotate filters to overwrite oldest value - filtHist = roll(filtHist, -1) - filtHist[-1] = 0.5 * c1 * \ - (hp + lastHP) + c2 * filtHist[1] + c3 * filtHist[0] - - # Wave calculation - wave = mean(filtHist) - rms = sqrt(mean(filtHist ** 2)) - wave = wave / rms - - # Update past values - lastHP = hp - lastClose = close.iloc[i] - result.append(wave) - - ebsw = Series(result, index=close.index) - - # Offset - if offset != 0: - ebsw = ebsw.shift(offset) - - # Fill - if "fillna" in kwargs: - ebsw.fillna(kwargs["fillna"], inplace=True) - # Name and Category - ebsw.name = f"EBSW_{length}_{bars}" - ebsw.category = "cycle" - - return ebsw diff --git a/src/aiomql/ta_libs/pandas_ta/cycle/reflex.py b/src/aiomql/ta_libs/pandas_ta/cycle/reflex.py deleted file mode 100644 index 838bfb2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/cycle/reflex.py +++ /dev/null @@ -1,114 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import cos, exp, nan, sqrt, zeros_like -from numba import njit -from pandas import Series -from .._typing import Int, IntFloat -from ..utils import v_offset, v_pos_default, v_series - - -@njit(cache=True) -def np_reflex(x, n, k, alpha, pi, sqrt2): - m, ratio = x.size, 2 * sqrt2 / k - a = exp(-pi * ratio) - b = 2 * a * cos(180 * ratio) - c = a * a - b + 1 - - _f = zeros_like(x) - _ms = zeros_like(x) - result = zeros_like(x) - - for i in range(2, m): - _f[i] = 0.5 * c * (x[i] + x[i - 1]) + b * _f[i - 1] - a * a * _f[i - 2] - - for i in range(n, m): - slope = (_f[i - n] - _f[i]) / n - - _sum = 0 - for j in range(1, n): - _sum += _f[i] - _f[i - j] + j * slope - _sum /= n - - _ms[i] = alpha * _sum * _sum + (1 - alpha) * _ms[i - 1] - if _ms[i] != 0.0: - result[i] = _sum / sqrt(_ms[i]) - - return result - - -def reflex( - close: Series, length: Int = None, - smooth: Int = None, alpha: IntFloat = None, - pi: IntFloat = None, sqrt2: IntFloat = None, - offset: Int = None, **kwargs: dict | None -) -> Series: - """Reflex - - This cycle indicator, by John F. Ehlers, attempts to reduce lag. - - Sources: - * [rengel8](https://github.com/rengel8) (2021-08-11) based on the - implementation from "ProRealCode" - * [traders.com](http://traders.com/Documentation/FEEDbk_docs/2020/02/TradersTips.html) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/reflex-and-trendflex-indicators-john-f-ehlers/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - smooth (int): SuperSmoother period. Default: ```20``` - alpha (float): Alpha weight of Difference Sums. Default: ```0.04``` - pi (float): Ehlers's truncated value: ```3.14159```. - Default: ```3.14159``` - sqrt2 (float): Ehlers's truncated value: ```1.414```. - Default: ```1.414``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): Replaces ```na```'s with ```value```. - - Returns: - (pd.Series): 1 column - - Tip: - This implementation has a separate control parameter for the - internal applied SuperSmoother. - - Note: - John F. Ehlers introduced two indicators within the article - "Reflex: A New Zero-Lag Indicator” in February 2020, TASC magazine. - One of which is Reflex, a lag reduced cycle indicator. Both indicators - (Reflex/Trendflex) are oscillators that complement each other with the - focus for cycle and trend. - """ - # Validate - length = v_pos_default(length, 20) - smooth = v_pos_default(smooth, 20) - _length = max(length, smooth) + 1 - close = v_series(close, _length) - - if close is None: - return - - alpha = v_pos_default(alpha, 0.04) - pi = v_pos_default(pi, 3.14159) - sqrt2 = v_pos_default(sqrt2, 1.414) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - result = np_reflex(np_close, length, smooth, alpha, pi, sqrt2) - result[:length] = nan - result = Series(result, index=close.index) - - # Offset - if offset != 0: - result = result.shift(offset) - - # Fill - if "fillna" in kwargs: - result.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - result.name = f"REFLEX_{length}_{smooth}_{alpha}" - result.category = "cycle" - - return result diff --git a/src/aiomql/ta_libs/pandas_ta/ma.py b/src/aiomql/ta_libs/pandas_ta/ma.py deleted file mode 100644 index fecd096..0000000 --- a/src/aiomql/ta_libs/pandas_ta/ma.py +++ /dev/null @@ -1,72 +0,0 @@ -from pandas import Series -from ._typing import DictLike -from .overlap.dema import dema -from .overlap.ema import ema -from .overlap.fwma import fwma -from .overlap.hma import hma -from .overlap.linreg import linreg -from .overlap.midpoint import midpoint -from .overlap.pwma import pwma -from .overlap.rma import rma -from .overlap.sinwma import sinwma -from .overlap.sma import sma -from .overlap.ssf import ssf -from .overlap.swma import swma -from .overlap.t3 import t3 -from .overlap.tema import tema -from .overlap.trima import trima -from .overlap.vidya import vidya -from .overlap.wma import wma - - -def ma(name: str = None, source: Series = None, **kwargs: DictLike) -> Series: - """MA Selection Utility - - Available MAs: dema, ema, fwma, hma, linreg, midpoint, pwma, rma, - sinwma, sma, ssf, swma, t3, tema, trima, vidya, wma. - - Parameters: - name (str): One of the Available MAs. Default: "ema" - source (pd.Series): Input Series ```source```. - - Other Parameters: - kwargs (**kwargs): Additional args for the MA. - - Returns: - (pd.Series): Selected MA - - Esourceample: - ```py linenums="0" - ema8 = ta.ma("ema", df.close, length=8) - sma50 = ta.ma("sma", df.close, length=50) - pwma10 = ta.ma("pwma", df.close, length=10, asc=False) - ``` - """ - _mas = [ - "dema", "ema", "fwma", "hma", "linreg", "midpoint", "pwma", "rma", - "sinwma", "sma", "ssf", "swma", "t3", "tema", "trima", "vidya", "wma" - ] - if name is None and source is None: - return _mas - elif isinstance(name, str) and name.lower() in _mas: - name = name.lower() - else: # "ema" - name = _mas[1] - - if name == "dema": return dema(source, **kwargs) - elif name == "fwma": return fwma(source, **kwargs) - elif name == "hma": return hma(source, **kwargs) - elif name == "linreg": return linreg(source, **kwargs) - elif name == "midpoint": return midpoint(source, **kwargs) - elif name == "pwma": return pwma(source, **kwargs) - elif name == "rma": return rma(source, **kwargs) - elif name == "sinwma": return sinwma(source, **kwargs) - elif name == "sma": return sma(source, **kwargs) - elif name == "ssf": return ssf(source, **kwargs) - elif name == "swma": return swma(source, **kwargs) - elif name == "t3": return t3(source, **kwargs) - elif name == "tema": return tema(source, **kwargs) - elif name == "trima": return trima(source, **kwargs) - elif name == "vidya": return vidya(source, **kwargs) - elif name == "wma": return wma(source, **kwargs) - else: return ema(source, **kwargs) diff --git a/src/aiomql/ta_libs/pandas_ta/maps.py b/src/aiomql/ta_libs/pandas_ta/maps.py deleted file mode 100644 index 97f2a7d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/maps.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -from importlib.util import find_spec -from ._typing import Dict, IntFloat, ListStr - - -Imports: Dict[str, bool] = { - "talib": find_spec("talib") is not None, - "vectorbt": find_spec("vectorbt") is not None, - "yfinance": find_spec("yfinance") is not None, -} - - -# Not ideal and not dynamic but it works. -# TODO: find a dynamic solution later. -Category: Dict[str, ListStr] = { - "candle": [ - "cdl_pattern", "cdl_z", "ha" - ], - "cycle": ["ebsw", "reflex"], - "momentum": [ - "ao", "apo", "bias", "bop", "brar", "cci", "cfo", "cg", "cmo", - "coppock", "crsi", "cti", "er", "eri", "exhc", "fisher", - "inertia", "kdj", "kst", "macd", "mom", "pgo", "ppo", "psl", "qqe", - "roc", "rsi", "rsx", "rvgi", "slope", "smc", "smi", "squeeze", - "squeeze_pro", "stc", "stoch", "stochf", "stochrsi", "tmo", "trix", - "tsi", "uo", "willr" - ], - "overlap": [ - "alligator", "alma", "dema", "ema", "fwma", "hilo", "hl2", "hlc3", - "hma", "hwma", "ichimoku", "jma", "kama", "linreg", "mama", - "mcgd", "midpoint", "midprice", "ohlc4", "pivots", "pwma", "rma", - "sinwma", "sma", "smma", "ssf", "ssf3", "supertrend", "swma", "t3", - "tema", "trima", "vidya", "wcp", "wma", "zlma" - ], - "performance": ["log_return", "percent_return"], - "statistics": [ - "entropy", "kurtosis", "mad", "median", "quantile", "skew", "stdev", - "tos_stdevall", "variance", "zscore" - ], - "trend": [ - "adx", "alphatrend", "amat", "aroon", "chop", "cksp", "decay", - "decreasing", "dpo", "ht_trendline", "increasing", - "long_run", "psar", "qstick", "rwi", "short_run", "trendflex", - "vhf", "vortex", "zigzag" - ], - "volatility": [ - "aberration", "accbands", "atr", "atrts", "bbands", "chandelier_exit", - "donchian", "hwc", "kc", "massi", "natr", "pdist", "rvi", "thermo", - "true_range", "ui" - ], - # Note: "vp" or "Volume Profile" is excluded since it does not - # return a Time Series - "volume": [ - "ad", "adosc", "aobv", "cmf", "efi", "eom", "kvo", "mfi", "nvi", - "obv", "pvi", "pvo", "pvol", "pvr", "pvt", "tsv", "vhm", "vwap", - "vwma" - ], -} - - -CANDLE_AGG: Dict[str, str] = { - "open": "first", - "high": "max", - "low": "min", - "close": "last", - "volume": "sum" -} - - -# https://www.worldtimezone.com/markets24.php -EXCHANGE_TZ: Dict[str, IntFloat] = { - "NZSX": 12, "ASX": 11, - "TSE": 9, "HKE": 8, "SSE": 8, "SGX": 8, - "NSE": 5.5, "DIFX": 4, "RTS": 3, - "JSE": 2, "FWB": 1, "LSE": 1, - "BMF": -2, "NYSE": -4, "TSX": -4, - "GENR": 0 # Generated Data -} - - -RATE: Dict[str, IntFloat] = { - "DAYS_PER_MONTH": 21, - "MINUTES_PER_HOUR": 60, - "MONTHS_PER_YEAR": 12, - "QUARTERS_PER_YEAR": 4, - "TRADING_DAYS_PER_YEAR": 252, # Keep even - "TRADING_HOURS_PER_DAY": 6.5, - "WEEKS_PER_YEAR": 52, - "YEARLY": 1, -} diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/__init__.py b/src/aiomql/ta_libs/pandas_ta/momentum/__init__.py deleted file mode 100644 index f773d51..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/__init__.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -from .ao import ao -from .apo import apo -from .bias import bias -from .bop import bop -from .brar import brar -from .cci import cci -from .cfo import cfo -from .cg import cg -from .cmo import cmo -from .coppock import coppock -from .crsi import crsi -from .cti import cti -from .dm import dm -from .er import er -from .eri import eri -from .exhc import exhc -from .fisher import fisher -from .inertia import inertia -from .kdj import kdj -from .kst import kst -from .macd import macd -from .mom import mom -from .pgo import pgo -from .ppo import ppo -from .psl import psl -from .qqe import qqe -from .roc import roc -from .rsi import rsi -from .rsx import rsx -from .rvgi import rvgi -from .slope import slope -from .smc import smc -from .smi import smi -from .squeeze import squeeze -from .squeeze_pro import squeeze_pro -from .stc import stc -from .stoch import stoch -from .stochf import stochf -from .stochrsi import stochrsi -from .tmo import tmo -from .trix import trix -from .tsi import tsi -from .uo import uo -from .willr import willr - - -__all__ = [ - "ao", - "apo", - "bias", - "bop", - "brar", - "cci", - "cfo", - "cg", - "cmo", - "coppock", - "crsi", - "cti", - "dm", - "er", - "eri", - "exhc", - "fisher", - "inertia", - "kdj", - "kst", - "macd", - "mom", - "pgo", - "ppo", - "psl", - "qqe", - "roc", - "rsi", - "rsx", - "rvgi", - "slope", - "smc", - "smi", - "squeeze", - "squeeze_pro", - "stc", - "stoch", - "stochf", - "stochrsi", - "tmo", - "trix", - "tsi", - "uo", - "willr", -] diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/ao.py b/src/aiomql/ta_libs/pandas_ta/momentum/ao.py deleted file mode 100644 index 309ce8e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/ao.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from .._typing import Int -from ..overlap import sma -from ..utils import v_offset, v_pos_default, v_series - - -def ao( - high: Series, low: Series, fast: Int = None, slow: Int = None, - offset: Int = None, **kwargs: dict | None -) -> Series: - """Awesome Oscillator - - This indicator attempts to identify momentum with the intention to - affirm trends or anticipate possible reversals. - - Sources: - * [ifcm](https://www.ifcm.co.uk/ntx-indicators/awesome-oscillator) - * [tradingview](https://www.tradingview.com/wiki/Awesome_Oscillator_(AO)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - fast (int): Fast period. Default: ```5``` - slow (int): Slow period. Default: ```34``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - fast = v_pos_default(fast, 5) - slow = v_pos_default(slow, 34) - if slow < fast: - fast, slow = slow, fast - _length = max(fast, slow) - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - offset = v_offset(offset) - - # Calculate - median_price = 0.5 * (high + low) - fast_sma = sma(median_price, fast) - slow_sma = sma(median_price, slow) - ao = fast_sma - slow_sma - - # Offset - if offset != 0: - ao = ao.shift(offset) - - # Fill - if "fillna" in kwargs: - ao.fillna(kwargs["fillna"], inplace=True) - # Name and Category - ao.name = f"AO_{fast}_{slow}" - ao.category = "momentum" - - return ao diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/apo.py b/src/aiomql/ta_libs/pandas_ta/momentum/apo.py deleted file mode 100644 index 91c3b98..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/apo.py +++ /dev/null @@ -1,74 +0,0 @@ -from pandas import Series -from .._typing import DictLike, Int -from ..ma import ma -from ..maps import Imports -from ..utils import tal_ma, v_mamode, v_offset -from ..utils import v_pos_default, v_series, v_talib - - - -def apo( - close: Series, fast: Int = None, slow: Int = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Absolute Price Oscillator - - This indicator attempts to quantify momentum. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/xtrader-help/x-study/technical-indicator-definitions/absolute-price-oscillator-apo/) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): Fast period. Default: ```12``` - slow (int): Slow period. Default: ```26``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Simply the difference of two different EMAs. - * APO and MACD lines are equivalent. - """ - # Validate - fast = v_pos_default(fast, 12) - slow = v_pos_default(slow, 26) - if slow < fast: - fast, slow = slow, fast - close = v_series(close, max(fast, slow)) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import APO - apo = APO(close, fast, slow, tal_ma(mamode)) - else: - fastma = ma(mamode, close, length=fast, talib=mode_tal) - slowma = ma(mamode, close, length=slow, talib=mode_tal) - apo = fastma - slowma - - # Offset - if offset != 0: - apo = apo.shift(offset) - - # Fill - if "fillna" in kwargs: - apo.fillna(kwargs["fillna"], inplace=True) - # Name and Category - apo.name = f"APO_{fast}_{slow}" - apo.category = "momentum" - - return apo diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/bias.py b/src/aiomql/ta_libs/pandas_ta/momentum/bias.py deleted file mode 100644 index ee2e755..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/bias.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from .._typing import DictLike, Int -from ..ma import ma -from ..utils import v_mamode, v_offset, v_pos_default, v_series - - -def bias( - close: Series, length: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Bias - - This indicator computes the Rate of Change between the source and a - moving average. - - Sources: - * Few internet resources on definitive definition. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```26``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 26) - close = v_series(close, length) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - bma = ma(mamode, close, length=length, **kwargs) - bias = (close / bma) - 1 - - # Offset - if offset != 0: - bias = bias.shift(offset) - - # Fill - if "fillna" in kwargs: - bias.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - bias.name = f"BIAS_{bma.name}" - bias.category = "momentum" - - return bias diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/bop.py b/src/aiomql/ta_libs/pandas_ta/momentum/bop.py deleted file mode 100644 index ef4b3d1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/bop.py +++ /dev/null @@ -1,70 +0,0 @@ -from pandas import Series -from .._typing import DictLike, Int, IntFloat -from ..maps import Imports -from ..utils import ( - non_zero_range, - v_offset, - v_scalar, - v_series, - v_talib -) - -def bop( - open_: Series, high: Series, low: Series, close: Series, - scalar: IntFloat = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Balance of Power - - This indicator attempts to quantify the market strength of buyers - versus sellers. - - Sources: - * [worden](http://www.worden.com/TeleChartHelp/Content/Indicators/Balance_of_Power.htm) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - scalar (float): Scalar. Default: ```1``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - open_ = v_series(open_) - high = v_series(high) - low = v_series(low) - close = v_series(close) - scalar = v_scalar(scalar, 1) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal and close.size: - from talib import BOP - bop = BOP(open_, high, low, close) - else: - high_low_range = non_zero_range(high, low) - close_open_range = non_zero_range(close, open_) - bop = scalar * close_open_range / high_low_range - - # Offset - if offset != 0: - bop = bop.shift(offset) - - # Fill - if "fillna" in kwargs: - bop.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - bop.name = f"BOP" - bop.category = "momentum" - - return bop diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/brar.py b/src/aiomql/ta_libs/pandas_ta/momentum/brar.py deleted file mode 100644 index 1cf4666..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/brar.py +++ /dev/null @@ -1,91 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - non_zero_range, - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series -) - -def brar( - open_: Series, high: Series, low: Series, close: Series, - length: Int = None, scalar: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """BRAR - - BR and AR - - Sources: - * No internet resources on definitive definition. - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```26``` - scalar (float): Scalar. Default: ```100``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - length = v_pos_default(length, 26) - open_ = v_series(open_, length) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if open_ is None or high is None or low is None or close is None: - return - - scalar = v_scalar(scalar, 100) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - high_open_range = non_zero_range(high, open_) - open_low_range = non_zero_range(open_, low) - hcy = non_zero_range(high, close.shift(drift)) - cyl = non_zero_range(close.shift(drift), low) - - hcy[hcy < 0] = 0 # Zero negative values - cyl[cyl < 0] = 0 # "" - - ar = scalar * high_open_range.rolling(length).sum() \ - / open_low_range.rolling(length).sum() - - br = scalar * hcy.rolling(length).sum() \ - / cyl.rolling(length).sum() - - # Offset - if offset != 0: - ar = ar.shift(offset) - br = ar.shift(offset) - - # Fill - if "fillna" in kwargs: - ar.fillna(kwargs["fillna"], inplace=True) - br.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}" - ar.name = f"AR{_props}" - br.name = f"BR{_props}" - ar.category = br.category = "momentum" - - data = {ar.name: ar, br.name: br} - df = DataFrame(data, index=close.index) - df.name = f"BRAR{_props}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/cci.py b/src/aiomql/ta_libs/pandas_ta/momentum/cci.py deleted file mode 100644 index a9caf03..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/cci.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.overlap import hlc3, sma -from pandas_ta.statistics import mad -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib - - - -def cci( - high: Series, low: Series, close: Series, length: Int = None, - c: IntFloat = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Commodity Channel Index - - This indicator attempts to identify "overbought" and "oversold" levels - relative to a mean. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Commodity_Channel_Index_(CCI)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - c (float): Scaling Constant. Default: ```0.015``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if high is None or low is None or close is None: - return - - c = v_pos_default(c, 0.015) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import CCI - cci = CCI(high, low, close, length) - else: - typical_price = hlc3(high=high, low=low, close=close, talib=mode_tal) - mean_typical_price = sma(typical_price, length=length, talib=mode_tal) - mad_typical_price = mad(typical_price, length=length) - - cci = typical_price - mean_typical_price / (c * mad_typical_price) - - # Offset - if offset != 0: - cci = cci.shift(offset) - - # Fill - if "fillna" in kwargs: - cci.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - cci.name = f"CCI_{length}_{c}" - cci.category = "momentum" - - return cci diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/cfo.py b/src/aiomql/ta_libs/pandas_ta/momentum/cfo.py deleted file mode 100644 index 926205d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/cfo.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import linreg -from pandas_ta.utils import ( - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series -) - - - -def cfo( - close: Series, length: Int = None, - scalar: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Chande Forcast Oscillator - - This indicator attempts to calculate the percentage difference between - the actual price and the Time Series Forecast (the endpoint of a - linear regression line). - - Sources: - * [fmlabs](https://www.fmlabs.com/reference/default.htm?url=ForecastOscillator.htm) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```9``` - scalar (float): Scalar. Default: ```100``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 9) - close = v_series(close, length) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - # Finding linear regression of Series - cfo = scalar * (close - linreg(close, length=length, tsf=True)) / close - - # Offset - if offset != 0: - cfo = cfo.shift(offset) - - # Fill - if "fillna" in kwargs: - cfo.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - cfo.name = f"CFO_{length}" - cfo.category = "momentum" - - return cfo diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/cg.py b/src/aiomql/ta_libs/pandas_ta/momentum/cg.py deleted file mode 100644 index 4379701..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/cg.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series, weights - - - -def cg( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Center of Gravity - - This indicator, by John Ehlers, attempts to identify turning points with - minimal to zero lag and smoothing. - - Sources: - * [MESA Software](http://www.mesasoftware.com/papers/TheCGOscillator.pdf) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - coefficients = range(1, length + 1) - numerator = close.rolling(length).apply(weights(coefficients), raw=True) - cg = -numerator / close.rolling(length).sum() - - # Offset - if offset != 0: - cg = cg.shift(offset) - - # Fill - if "fillna" in kwargs: - cg.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - cg.name = f"CG_{length}" - cg.category = "momentum" - - return cg diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/cmo.py b/src/aiomql/ta_libs/pandas_ta/momentum/cmo.py deleted file mode 100644 index 5558fbf..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/cmo.py +++ /dev/null @@ -1,90 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.overlap import rma -from pandas_ta.utils import ( - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) - - - -def cmo( - close: Series, length: Int = None, scalar: IntFloat = None, - talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Chande Momentum Oscillator - - This indicator attempts to capture momentum. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/chande-momentum-oscillator-cmo/) - * [tradingview](https://www.tradingview.com/script/hdrf0fXV-Variable-Index-Dynamic-Average-VIDYA/) - - Parameters: - close (pd.Series): ```close``` Series - scalar (float): Scalar. Default: ```100``` - talib (bool): If installed, use TA Lib. Uses EMA if ```False```. - Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Overbought around 50 - * Oversold around -50. - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length + 1) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import CMO - cmo = CMO(close, length) - else: - mom = close.diff(drift) - positive = mom.copy().clip(lower=0) - negative = mom.copy().clip(upper=0).abs() - - if mode_tal: - pos_ = rma(positive, length) - neg_ = rma(negative, length) - else: - pos_ = positive.rolling(length).sum() - neg_ = negative.rolling(length).sum() - - cmo = scalar * (pos_ - neg_) / (pos_ + neg_) - - # Offset - if offset != 0: - cmo = cmo.shift(offset) - - # Fill - if "fillna" in kwargs: - cmo.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - cmo.name = f"CMO_{length}" - cmo.category = "momentum" - - return cmo diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/coppock.py b/src/aiomql/ta_libs/pandas_ta/momentum/coppock.py deleted file mode 100644 index 1fd6b85..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/coppock.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- -# from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import wma -from pandas_ta.utils import v_offset, v_pos_default, v_series -from .roc import roc - - - -def coppock( - close: Series, length: Int = None, fast: Int = None, slow: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Coppock Curve - - This indicator, by Edwin Coppock 1962, was originally called the - "Trendex Model", attempts to identify major upturns and downturns. - - Sources: - * [wikipedia](https://en.wikipedia.org/wiki/Coppock_curve) - - Parameters: - close (pd.Series): ```close``` Series - length (int): WMA period. Default: ```10``` - fast (int): Fast ROC period. Default: ```11``` - slow (int): Slow ROC period. Default: ```14``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Although designed for monthly use, a daily calculation over the same - period length can be made, converting the periods to 294-day and - 231-day rate of changes, and a 210-day WMA. - - """ - # Validate - length = v_pos_default(length, 10) - fast = v_pos_default(fast, 11) - slow = v_pos_default(slow, 14) - _length = length + fast + slow - close = v_series(close, _length) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - total_roc = roc(close, fast) + roc(close, slow) - coppock = wma(total_roc, length) - - # Offset - if offset != 0: - coppock = coppock.shift(offset) - - # Fill - if "fillna" in kwargs: - coppock.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - coppock.name = f"COPC_{fast}_{slow}_{length}" - coppock.category = "momentum" - - return coppock diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/crsi.py b/src/aiomql/ta_libs/pandas_ta/momentum/crsi.py deleted file mode 100644 index 5f4844e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/crsi.py +++ /dev/null @@ -1,105 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.momentum.rsi import rsi -from pandas_ta.utils import ( - consecutive_streak, - percent_rank, - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib, -) - - - -def crsi( - close: Series, rsi_length: Int = None, streak_length: Int = None, - rank_length: Int = None, scalar: IntFloat = None, talib: bool = None, - drift: Int = None, offset: Int = None, **kwargs: DictLike, -) -> Series: - """Connors Relative Strength Index - - This indicator attempts to identify momentum and potential reversals at - "overbought" or "oversold" conditions. - - Sources: - * [alvarezquanttrading](https://alvarezquanttrading.com/blog/connorsrsi-analysis/) - * [tradingview](https://www.tradingview.com/support/solutions/43000502017-connors-rsi-crsi/) - * An Introduction to ConnorsRSI. Connors Research Trading Strategy Series. - Connors, L., Alvarez, C., & Radtke, M. (2012). ISBN 978-0-9853072-9-5. - - Parameters: - close (pd.Series): ```close``` Series - rsi_length (int): The RSI period. Default: ```3``` - streak_length (int): Streak RSI period. Default: ```2``` - rank_length (int): Percent Rank length. Default: ```100``` - scalar (float): Scalar. Default: ```100``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - rsi_length = v_pos_default(rsi_length, 3) - streak_length = v_pos_default(streak_length, 2) - rank_length = v_pos_default(rank_length, 100) - _length = max(rsi_length, streak_length, rank_length) - close = v_series(close, _length) - - if "length" in kwargs: - kwargs.pop("length") - - if close is None: - return None - - scalar = v_scalar(scalar, 100) - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - streak = Series(consecutive_streak(np_close), index=close.index) - - if Imports["talib"] and mode_tal: - from talib import RSI - _rsi = RSI(close, rsi_length) - _streak_rsi = RSI(streak, streak_length) - else: - # Both TA-lib and Pandas-TA use the Wilder's RSI - # and its smoothing function - _rsi = rsi( - close, length=rsi_length, scalar=scalar, talib=talib, - drift=drift, offset=offset, **kwargs - ) - - _streak_rsi = rsi( - streak, length=streak_length, scalar=scalar, talib=talib, - drift=drift, offset=offset, **kwargs - ) - - _crsi = (_rsi + _streak_rsi + percent_rank(close, rank_length)) / 3.0 - crsi = Series(_crsi, index=close.index) - - # Offset - if offset != 0: - crsi = crsi.shift(offset) - - # Fill - if "fillna" in kwargs: - crsi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - crsi.name = f"CRSI_{rsi_length}_{streak_length}_{rank_length}" - crsi.category = "momentum" - - return crsi diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/cti.py b/src/aiomql/ta_libs/pandas_ta/momentum/cti.py deleted file mode 100644 index e757d53..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/cti.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import linreg -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def cti( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Correlation Trend Indicator - - This oscillator, by John Ehlers' in 2020, attempts to identify the - magnitude and direction of a trend using linear regession. - - Note: - This is a wrapper for ```ta.linreg(close, r=True)```. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```12``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 12) - close = v_series(close, length) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - cti = linreg(close, length=length, r=True) - - # Offset - if offset != 0: - cti = cti.shift(offset) - - # Fill - if "fillna" in kwargs: - cti.fillna(method=kwargs["fillna"], inplace=True) - - # Name and Category - cti.name = f"CTI_{length}" - cti.category = "momentum" - - return cti diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/dm.py b/src/aiomql/ta_libs/pandas_ta/momentum/dm.py deleted file mode 100644 index 4709e02..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/dm.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib, - zero -) - - - -def dm( - high: Series, low: Series, length: Int = None, - mamode: str = None, talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Directional Movement - - This indicator, by J. Welles Wilder in 1978, attempts to - determine direction. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=24&Name=Directional_Movement_Index) - * [tradingview](https://www.tradingview.com/pine-script-reference/#fun_dmi) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - length = v_pos_default(length, 14) - high = v_series(high, length) - low = v_series(low, length) - - if high is None or low is None: - return - - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - if Imports["talib"] and mode_tal and high.size and low.size: - from talib import MINUS_DM, PLUS_DM - pos = PLUS_DM(high, low, length) - neg = MINUS_DM(high, low, length) - else: - up = high - high.shift(drift) - dn = low.shift(drift) - low - - pos_ = ((up > dn) & (up > 0)) * up - neg_ = ((dn > up) & (dn > 0)) * dn - - pos_ = pos_.apply(zero) - neg_ = neg_.apply(zero) - - # Not the same values as TA Lib's -+DM (Good First Issue) - pos = ma(mamode, pos_, length=length, talib=mode_tal) - neg = ma(mamode, neg_, length=length, talib=mode_tal) - - # Offset - if offset != 0: - pos = pos.shift(offset) - neg = neg.shift(offset) - - # Fill - if "fillna" in kwargs: - pos.fillna(kwargs["fillna"], inplace=True) - neg.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}" - data = {f"DMP{_props}": pos, f"DMN{_props}": neg} - df = DataFrame(data, index=high.index) - df.name = f"DM{_props}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/er.py b/src/aiomql/ta_libs/pandas_ta/momentum/er.py deleted file mode 100644 index cd65087..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/er.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, concat, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - signals, - v_drift, - v_offset, - v_pos_default, - v_series -) - - - -def er( - close: Series, length: Int = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Efficiency Ratio - - This indicator, by Perry J. Kaufman, attempts to identify market noise - or volatility. - - Sources: - * "New Trading Systems and Methods", Perry J. Kaufman - * [tc2000](https://help.tc2000.com/m/69404/l/749623-kaufman-efficiency-ratio) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - It is calculated by dividing the net change in price movement over - ```n``` periods by the sum of the absolute net changes over the - same ```n``` periods. - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length + 1) - - if close is None: - return - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - abs_diff = close.diff(length).abs() - abs_volatility = close.diff(drift).abs() - abs_volatility_rsum = abs_volatility.rolling(window=length).sum() - - er = abs_diff / abs_volatility_rsum - - # Offset - if offset != 0: - er = er.shift(offset) - - # Fill - if "fillna" in kwargs: - er.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - er.name = f"ER_{length}" - er.category = "momentum" - - signal_indicators = kwargs.pop("signal_indicators", False) - if not signal_indicators: - return er - else: - signalsdf = concat( - [ - DataFrame({er.name: er}), - signals( - indicator=er, - xa=kwargs.pop("xa", 80), - xb=kwargs.pop("xb", 20), - xseries=kwargs.pop("xseries", None), - xseries_a=kwargs.pop("xseries_a", None), - xseries_b=kwargs.pop("xseries_b", None), - cross_values=kwargs.pop("cross_values", False), - cross_series=kwargs.pop("cross_series", True), - offset=offset, - ), - ], - axis=1, - ) - return signalsdf diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/eri.py b/src/aiomql/ta_libs/pandas_ta/momentum/eri.py deleted file mode 100644 index 02306cb..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/eri.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import ema -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def eri( - high: Series, low: Series, close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Elder Ray Index - - This indicator, by Dr Alexander Elder, attempts to identify market - strength. - - Sources: - * [admiralmarkets](https://admiralmarkets.com/education/articles/forex-indicators/bears-and-bulls-power-indicator) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - * Possible entry signals when used in combination with a trend, - * Bear Power attempts to quantify lower value appeal. - * Bull Power attempts the to quantify higher value appeal. - """ - # Validate - length = v_pos_default(length, 13) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - ema_ = ema(close, length) - bull = high - ema_ - bear = low - ema_ - - # Offset - if offset != 0: - bull = bull.shift(offset) - bear = bear.shift(offset) - - # Fill - if "fillna" in kwargs: - bull.fillna(kwargs["fillna"], inplace=True) - bear.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - bull.name = f"BULLP_{length}" - bear.name = f"BEARP_{length}" - bull.category = bear.category = "momentum" - - data = {bull.name: bull, bear.name: bear} - df = DataFrame(data, index=close.index) - df.name = f"ERI_{length}" - df.category = bull.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/exhc.py b/src/aiomql/ta_libs/pandas_ta/momentum/exhc.py deleted file mode 100644 index 4a039e1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/exhc.py +++ /dev/null @@ -1,123 +0,0 @@ -# -*- coding: utf-8 -*- -from math import isnan -from numpy import ( - clip, - cumsum, - diff, - float64, - int64, - isnan, - nan, - nan_to_num, - where, - zeros_like -) -from numba import njit -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - nb_ffill, - nb_idiff, - nb_shift, - v_bool, - v_int, - v_offset, - v_pos_default, - v_series -) - - - -@njit(cache=True) -def nb_exhc(x, n, cap, lb, ub, show_all): - x_diff = nb_idiff(x, n) - neg_diff, pos_diff = x_diff < 0, x_diff > 0 - - dn_csum = cumsum(neg_diff) - up_csum = cumsum(pos_diff) - - dn = dn_csum - nb_ffill(where(~neg_diff, dn_csum, nan)) - up = up_csum - nb_ffill(where(~pos_diff, up_csum, nan)) - - if cap > 0: - dn = clip(dn, 0, cap) - up = clip(up, 0, cap) - - if show_all: - dn = where(dn == 0, 0, dn) - up = where(up == 0, 0, up) - else: - between_lu = (dn >= lb) & (dn <= ub) - dn = where(between_lu, dn, 0) - up = where(between_lu, up, 0) - - return dn, up - - -def exhc( - close: Series, length: Int = None, cap: Int = None, - asint: bool = None, show_all: bool = None, nozeros: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Exhaustion Count - - This indicator attempts to identify rising/falling exhaustion. - - Sources: - * [demark](https://demark.com) - * [practicaltechnicalanalysis](http://practicaltechnicalanalysis.blogspot.com/2013/01/tom-demark-sequential.html) - - Parameters: - close (pd.Series): Series of close's - length (int): The period. Default: ```4``` - cap (int): Count cap. For no cap, set to ```0```. Default: ```13``` - show_all (bool): Counts 1 - 13. For 6 - 9, set to ```False```. - Default: ```True``` - asint (bool): Returns as ```Int```. Default: ```False``` - nozeros (bool): Replace zeros with ```np.nan```. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - Similar to TD Sequential - """ - # Validate - length = v_pos_default(length, 4) - close = v_series(close, length + 1) - - if close is None: - return - - cap = v_int(cap, 13, -1) - show_all = v_bool(show_all, True) - asint = v_bool(asint, False) - nozeros = v_bool(nozeros, False) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - dn, up = nb_exhc(np_close, length, cap, 6, 9, show_all) - - if asint: - dn = dn.astype(int64) - up = up.astype(int64) - - # Name and Category - data = { - "EXHC_DNa" if show_all else "EXHC_DN": dn, - "EXHC_UPa" if show_all else "EXHC_UP": up - } - df = DataFrame(data, index=close.index) - df.name = "EXHCa" if show_all else "EXHC" - df.category = "momentum" - - if nozeros: - df.replace({0: nan}, inplace=True) - - # Offset - if offset != 0: - df = df.shift(offset) - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/fisher.py b/src/aiomql/ta_libs/pandas_ta/momentum/fisher.py deleted file mode 100644 index 44c5faf..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/fisher.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, log, nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import hl2 -from pandas_ta.utils import high_low_range, v_offset, v_pos_default, v_series - - - -def fisher( - high: Series, low: Series, length: Int = None, signal: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Fisher Transform - - This indicator attempts to identify significant reversals through - normalization. - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - length (int): The period. Default: ```9``` - signal (int): Signal period. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Tip: Reversal Signal - When the two lines cross. - """ - # Validate - length = v_pos_default(length, 9) - signal = v_pos_default(signal, 1) - _length = max(length, signal) - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - offset = v_offset(offset) - - # Calculate - hl2_ = hl2(high, low) - highest_hl2 = hl2_.rolling(length).max() - lowest_hl2 = hl2_.rolling(length).min() - - hlr = high_low_range(highest_hl2, lowest_hl2) - hlr[hlr < 0.001] = 0.001 - - position = ((hl2_ - lowest_hl2) / hlr) - 0.5 - - v = 0 - m = high.size - result = [nan for _ in range(0, length - 1)] + [0] - for i in range(length, m): - v = 0.66 * position.iat[i] + 0.67 * v - if v < -0.99: - v = -0.999 - if v > 0.99: - v = 0.999 - result.append(0.5 * (log((1 + v) / (1 - v)) + result[i - 1])) - - fisher = Series(result, index=high.index) - if all(isnan(fisher)): - return # Emergency Break - - signalma = fisher.shift(signal) - - # Offset - if offset != 0: - fisher = fisher.shift(offset) - signalma = signalma.shift(offset) - - # Fill - if "fillna" in kwargs: - fisher.fillna(kwargs["fillna"], inplace=True) - signalma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{signal}" - fisher.name = f"FISHERT{_props}" - signalma.name = f"FISHERTs{_props}" - fisher.category = signalma.category = "momentum" - - data = {fisher.name: fisher, signalma.name: signalma} - df = DataFrame(data, index=high.index) - df.name = f"FISHERT{_props}" - df.category = fisher.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/inertia.py b/src/aiomql/ta_libs/pandas_ta/momentum/inertia.py deleted file mode 100644 index ca483da..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/inertia.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import linreg -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series -) -from pandas_ta.volatility import rvi - - - -def inertia( - close: Series, high: Series = None, low: Series = None, - length: Int = None, rvi_length: Int = None, scalar: IntFloat = None, - refined: bool = None, thirds: bool = None, - drift: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Inertia - - This indicator, by Donald Dorsey, is the _rvi_ smoothed by the Least Squares - MA. - - Sources: - * Donald Dorsey, some article in September, 1995. - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=285&Name=Inertia) - * [tradingview](https://www.tradingview.com/script/mLZJqxKn-Relative-Volatility-Index/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - rvi_length (int): RVI period. Default: ```14``` - refined (bool): Use 'refined' calculation. Default: ```False``` - thirds (bool): Use 'thirds' calculation. Default: ```False``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Negative Inertia when less than 50. - * Positive Inertia when greater than 50. - """ - # Validate - length = v_pos_default(length, 20) - rvi_length = v_pos_default(rvi_length, 14) - _length = 2 * max(length, rvi_length) - min(length, rvi_length) // 2 - 1 - close = v_series(close, _length) - - if close is None: - return - - refined = v_bool(refined, False) - thirds = v_bool(thirds, False) - - if refined or thirds: - high = v_series(high, _length) - low = v_series(low, _length) - if high is None or low is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if refined: - _mode = "r" - rvi_ = rvi( - close, high=high, low=low, length=rvi_length, - scalar=scalar, refined=refined, mamode=mamode - ) - elif thirds: - _mode = "t" - rvi_ = rvi( - close, high=high, low=low, length=rvi_length, - scalar=scalar, thirds=thirds, mamode=mamode - ) - else: - _mode = "" - rvi_ = rvi(close, length=rvi_length, scalar=scalar, mamode=mamode) - - if all(isnan(rvi_)): - return # Emergency Break - - inertia = linreg(rvi_, length=length) - if all(isnan(inertia)): - return # Emergency Break - - # Offset - if offset != 0: - inertia = inertia.shift(offset) - - # Fill - if "fillna" in kwargs: - inertia.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{rvi_length}" - inertia.name = f"INERTIA{_mode}{_props}" - inertia.category = "momentum" - - return inertia diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/kdj.py b/src/aiomql/ta_libs/pandas_ta/momentum/kdj.py deleted file mode 100644 index e256531..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/kdj.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - non_zero_range, - pd_rma, - v_offset, - v_pos_default, - v_series -) - - - -def kdj( - high: Series, low: Series, close: Series, - length: Int = None, signal: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """KDJ - - This indicator, derived from the Slow Stochastic, includes an - extra signal named the J line. The J line represents the divergence - of the %D value from the %K. - - Sources: - * [anychart](https://docs.anychart.com/Stock_Charts/Technical_Indicators/Mathematical_Description#kdj) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/kdj/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```9``` - signal (int): Signal period. Default: ```3``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - - Note: - The J can go beyond ```[0, 100]``` for %K and %D lines when charted. - """ - # Validate - length = v_pos_default(length, 9) - signal = v_pos_default(signal, 3) - _length = length + signal + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - highest_high = high.rolling(length).max() - lowest_low = low.rolling(length).min() - - fastk = 100 * (close - lowest_low) / \ - non_zero_range(highest_high, lowest_low) - - k = pd_rma(fastk, n=signal) - d = pd_rma(k, n=signal) - j = 3 * k - 2 * d - - # Offset - if offset != 0: - k = k.shift(offset) - d = d.shift(offset) - j = j.shift(offset) - - # Fill - if "fillna" in kwargs: - k.fillna(kwargs["fillna"], inplace=True) - d.fillna(kwargs["fillna"], inplace=True) - j.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{signal}" - k.name = f"K{_props}" - d.name = f"D{_props}" - j.name = f"J{_props}" - k.category = d.category = j.category = "momentum" - - data = {k.name: k, d.name: d, j.name: j} - df = DataFrame(data, index=close.index) - df.name = f"KDJ{_props}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/kst.py b/src/aiomql/ta_libs/pandas_ta/momentum/kst.py deleted file mode 100644 index d02fd8c..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/kst.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_drift, v_offset, v_pos_default, v_series -from .roc import roc - - - -def kst( - close: Series, signal: Int = None, - roc1: Int = None, roc2: Int = None, roc3: Int = None, roc4: Int = None, - sma1: Int = None, sma2: Int = None, sma3: Int = None, sma4: Int = None, - drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """'Know Sure Thing' - - This indicator, by Martin Pring, attempts to capture trends using a - smoothed indicator of four different smoothed ROCs. - - Sources: - * [incrediblecharts](https://www.incrediblecharts.com/indicators/kst.php) - * [tradingview](https://www.tradingview.com/wiki/Know_Sure_Thing_(KST)) - - Parameters: - close (pd.Series): ```close``` Series - roc1 (int): ROC 1 period. Default: ```10``` - roc2 (int): ROC 2 period. Default: ```15``` - roc3 (int): ROC 3 period. Default: ```20``` - roc4 (int): ROC 4 period. Default: ```30``` - sma1 (int): SMA 1 period. Default: ```10``` - sma2 (int): SMA 2 period. Default: ```10``` - sma3 (int): SMA 3 period. Default: ```10``` - sma4 (int): SMA 4 period. Default: ```15``` - signal (int): Signal period. Default: ```9``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - roc1 = int(roc1) if roc1 and roc1 > 0 else 10 - roc2 = int(roc2) if roc2 and roc2 > 0 else 15 - roc3 = int(roc3) if roc3 and roc3 > 0 else 20 - roc4 = int(roc4) if roc4 and roc4 > 0 else 30 - - sma1 = int(sma1) if sma1 and sma1 > 0 else 10 - sma2 = int(sma2) if sma2 and sma2 > 0 else 10 - sma3 = int(sma3) if sma3 and sma3 > 0 else 10 - sma4 = int(sma4) if sma4 and sma4 > 0 else 15 - - signal = v_pos_default(signal, 9) - _rmax = max(roc1, roc2, roc3, roc4) - _smax = max(sma1, sma2, sma3, sma4) - _length = _rmax + _smax - close = v_series(close, _length) - - if close is None: - return - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - rocma1 = roc(close, roc1).rolling(sma1).mean() - rocma2 = roc(close, roc2).rolling(sma2).mean() - rocma3 = roc(close, roc3).rolling(sma3).mean() - rocma4 = roc(close, roc4).rolling(sma4).mean() - - kst = 100 * (rocma1 + 2 * rocma2 + 3 * rocma3 + 4 * rocma4) - kst_signal = kst.rolling(signal).mean() - - # Offset - if offset != 0: - kst = kst.shift(offset) - kst_signal = kst_signal.shift(offset) - - # Fill - if "fillna" in kwargs: - kst.fillna(kwargs["fillna"], inplace=True) - kst_signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - kst.name = f"KST_{roc1}_{roc2}_{roc3}_{roc4}_{sma1}_{sma2}_{sma3}_{sma4}" - kst_signal.name = f"KSTs_{signal}" - kst.category = kst_signal.category = "momentum" - - data = {kst.name: kst, kst_signal.name: kst_signal} - df = DataFrame(data, index=close.index) - df.name = f"KST_{roc1}_{roc2}_{roc3}_{roc4}_{sma1}_{sma2}_{sma3}_{sma4}_{signal}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/macd.py b/src/aiomql/ta_libs/pandas_ta/momentum/macd.py deleted file mode 100644 index f7b99e8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/macd.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import concat, DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.overlap import ema -from pandas_ta.utils import ( - signals, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def macd( - close: Series, fast: Int = None, slow: Int = None, - signal: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Moving Average Convergence Divergence - - This indicator attempts to identify trends. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/MACD_(Moving_Average_Convergence/Divergence)) - * [tradingview (AS Mode)](https://tr.tradingview.com/script/YFlKXHnP/) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): Fast MA period. Default: ```12``` - slow (int): Slow MA period. Default: ```26``` - signal (int): Signal period. Default: ```9``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - asmode (value): Enable AS version of MACD. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - fast = v_pos_default(fast, 12) - slow = v_pos_default(slow, 26) - signal = v_pos_default(signal, 9) - if slow < fast: - fast, slow = slow, fast - _length = slow + signal - 1 - close = v_series(close, _length) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - as_mode = kwargs.setdefault("asmode", False) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import MACD - macd, signalma, histogram = MACD(close, fast, slow, signal) - else: - fastma = ema(close, length=fast, talib=mode_tal) - slowma = ema(close, length=slow, talib=mode_tal) - - macd = fastma - slowma - macd_fvi = macd.loc[macd.first_valid_index():, ] - signalma = ema(close=macd_fvi, length=signal, talib=mode_tal) - histogram = macd - signalma - - if as_mode: - macd = macd - signalma - macd_fvi = macd.loc[macd.first_valid_index():, ] - signalma = ema(close=macd_fvi, length=signal, talib=mode_tal) - histogram = macd - signalma - - # Offset - if offset != 0: - macd = macd.shift(offset) - histogram = histogram.shift(offset) - signalma = signalma.shift(offset) - - # Fill - if "fillna" in kwargs: - macd.fillna(kwargs["fillna"], inplace=True) - histogram.fillna(kwargs["fillna"], inplace=True) - signalma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _asmode = "AS" if as_mode else "" - _props = f"_{fast}_{slow}_{signal}" - macd.name = f"MACD{_asmode}{_props}" - histogram.name = f"MACD{_asmode}h{_props}" - signalma.name = f"MACD{_asmode}s{_props}" - macd.category = histogram.category = signalma.category = "momentum" - - data = { - macd.name: macd, - histogram.name: histogram, - signalma.name: signalma - } - df = DataFrame(data, index=close.index) - df.name = f"MACD{_asmode}{_props}" - df.category = macd.category - - signal_indicators = kwargs.pop("signal_indicators", False) - if not signal_indicators: - return df - else: - signalsdf = concat( - [ - df, - signals( - indicator=histogram, - xa=kwargs.pop("xa", 0), - xb=kwargs.pop("xb", None), - xseries=kwargs.pop("xseries", None), - xseries_a=kwargs.pop("xseries_a", None), - xseries_b=kwargs.pop("xseries_b", None), - cross_values=kwargs.pop("cross_values", True), - cross_series=kwargs.pop("cross_series", True), - offset=offset, - ), - signals( - indicator=macd, - xa=kwargs.pop("xa", 0), - xb=kwargs.pop("xb", None), - xseries=kwargs.pop("xseries", None), - xseries_a=kwargs.pop("xseries_a", None), - xseries_b=kwargs.pop("xseries_b", None), - cross_values=kwargs.pop("cross_values", False), - cross_series=kwargs.pop("cross_series", True), - offset=offset, - ), - ], - axis=1, - ) - - return signalsdf diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/mom.py b/src/aiomql/ta_libs/pandas_ta/momentum/mom.py deleted file mode 100644 index b6807c5..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/mom.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - nb_idiff, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -@njit(cache=True) -def nb_mom(x, n): - return nb_idiff(x, n) - - -def mom( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Momentum - - This indicator attempts to quantify speed by using the differences over - a bar length. - - Sources: - * [onlinetradingconcepts](http://www.onlinetradingconcepts.com/TechnicalAnalysis/Momentum.html) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length + 1) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import MOM - mom = MOM(close, length) - else: - np_close = close.to_numpy() - _mom = nb_mom(np_close, length) - mom = Series(_mom, index=close.index) - - # Offset - if offset != 0: - mom = mom.shift(offset) - - # Fill - if "fillna" in kwargs: - mom.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - mom.name = f"MOM_{length}" - mom.category = "momentum" - - return mom diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/pgo.py b/src/aiomql/ta_libs/pandas_ta/momentum/pgo.py deleted file mode 100644 index aca4235..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/pgo.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import ema, sma -from pandas_ta.utils import v_offset, v_pos_default, v_series -from pandas_ta.volatility import atr - - - -def pgo( - high: Series, low: Series, close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Pretty Good Oscillator - - This indicator, by Mark Johnson, attempts to identify breakouts for longer - time periods based on the distance of the current bar to its N-day - SMA, expressed in terms of an ATR over a similar length. - - Sources: - * [tradingtechnologies](https://library.tradingtechnologies.com/trade/chrt-ti-pretty-good-oscillator.html) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: Entry - * Long when greater than 3. - * Short when less than -3. - """ - # Validate - length = v_pos_default(length, 14) - _length = 2 * length - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - pgo = (close - sma(close, length)) \ - / ema(atr(high, low, close, length), length) - - # Offset - if offset != 0: - pgo = pgo.shift(offset) - - # Fill - if "fillna" in kwargs: - pgo.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pgo.name = f"PGO_{length}" - pgo.category = "momentum" - - return pgo diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/ppo.py b/src/aiomql/ta_libs/pandas_ta/momentum/ppo.py deleted file mode 100644 index 8f850c1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/ppo.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - tal_ma, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) - - - -def ppo( - close: Series, fast: Int = None, slow: Int = None, signal: Int = None, - scalar: IntFloat = None, mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Percentage Price Oscillator - - Similar to MACD. - - Sources: - * [investopedia](https://www.investopedia.com/terms/p/ppo.asp) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): Fast MA period. Default: ```12``` - slow (int): Slow MA period. Default: ```26``` - signal (int): Signal period. Default: ```9``` - scalar (float): Scalar. Default: ```100``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - fast = v_pos_default(fast, 12) - slow = v_pos_default(slow, 26) - signal = v_pos_default(signal, 9) - if slow < fast: - fast, slow = slow, fast - _length = max(fast, slow, signal) - close = v_series(close, _length) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import PPO - ppo = PPO(close, fast, slow, tal_ma(mamode)) - else: - fastma = ma(mamode, close, length=fast, talib=mode_tal) - slowma = ma(mamode, close, length=slow, talib=mode_tal) - ppo = scalar * (fastma - slowma) / slowma - - if all(isnan(ppo)): - return # Emergency Break - - signalma = ma("ema", ppo, length=signal, talib=mode_tal) - histogram = ppo - signalma - - # Offset - if offset != 0: - ppo = ppo.shift(offset) - histogram = histogram.shift(offset) - signalma = signalma.shift(offset) - - # Fill - if "fillna" in kwargs: - ppo.fillna(kwargs["fillna"], inplace=True) - histogram.fillna(kwargs["fillna"], inplace=True) - signalma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{fast}_{slow}_{signal}" - ppo.name = f"PPO{_props}" - histogram.name = f"PPOh{_props}" - signalma.name = f"PPOs{_props}" - ppo.category = histogram.category = signalma.category = "momentum" - - data = { - ppo.name: ppo, - histogram.name: histogram, - signalma.name: signalma - } - df = DataFrame(data, index=close.index) - df.name = f"PPO{_props}" - df.category = ppo.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/psl.py b/src/aiomql/ta_libs/pandas_ta/momentum/psl.py deleted file mode 100644 index 3838412..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/psl.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import sign -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - nb_idiff, - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series -) - - - -def psl( - close: Series, open_: Series = None, - length: Int = None, scalar: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Psychological Line - - This indicator compares the number of the rising bars to the total number - of bars. In other words, it is the percentage of bars that are above the - previous bar over a given length. - - Sources: - * [quantshare](https://www.quantshare.com/item-851-psychological-line) - - Parameters: - close (pd.Series): ```close``` Series - open_ (pd.Series): ```open``` Series - length (int): The period. Default: ```12``` - scalar (float): Scalar. Default: ```100``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 12) - close = v_series(close, length) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if open_ is not None: - open_ = v_series(open_) - diff = sign(close - open_) - else: - diff = sign(close.diff(drift)) - - diff.fillna(0, inplace=True) - diff[diff <= 0] = 0 # Set negative values to zero - - psl = scalar * diff.rolling(length).sum() / length - - # Offset - if offset != 0: - psl = psl.shift(offset) - - # Fill - if "fillna" in kwargs: - psl.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}" - psl.name = f"PSL{_props}" - psl.category = "momentum" - - return psl diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/qqe.py b/src/aiomql/ta_libs/pandas_ta/momentum/qqe.py deleted file mode 100644 index ddadb62..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/qqe.py +++ /dev/null @@ -1,174 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, maximum, minimum, nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series -) -from .rsi import rsi - - - -def qqe( - close: Series, length: Int = None, - smooth: Int = None, factor: IntFloat = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Quantitative Qualitative Estimation - - This indicator is similar to SuperTrend but uses a Smoothed ```rsi``` - with upper and lower bands. - - Sources: - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/qqe-quantitative-qualitative-estimation/) - * [tradingpedia](https://www.tradingpedia.com/forex-trading-indicators/quantitative-qualitative-estimation) - * [tradingview](https://www.tradingview.com/script/IYfA9R2k-QQE-MT4/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): RSI period. Default: ```14``` - smooth (int): RSI smoothing period. Default: ```5``` - factor (float): QQE Factor. Default: ```4.236``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - - Tip: Trend - * Long: When the Smoothed RSI crosses the previous upperband. - * Short: When the Smoothed RSI crosses the previous lowerband. - - Note: See also - * QQE.mq5 by EarnForex Copyright © 2010 - * Tim Hyder (2008) version - * Roman Ignatov (2006) version - """ - # Validate - length = v_pos_default(length, 14) - smooth = v_pos_default(smooth, 5) - wilders_length = 2 * length - 1 - _length = wilders_length + smooth - close = v_series(close, _length) - - if close is None: - return - - factor = v_scalar(factor, 4.236) - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - rsi_ = rsi(close, length) - _mode = mamode.lower()[0] if mamode != "ema" else "" - rsi_ma = ma(mamode, rsi_, length=smooth) - - # RSI MA True Range - rsi_ma_tr = rsi_ma.diff(drift).abs() - if all(isnan(rsi_ma_tr)): - return - - # Double Smooth the RSI MA True Range using Wilder's Length with a default - # width of 4.236. - smoothed_rsi_tr_ma = ma("ema", rsi_ma_tr, length=wilders_length) - if all(isnan(smoothed_rsi_tr_ma)): - return # Emergency Break - dar = factor * ma("ema", smoothed_rsi_tr_ma, length=wilders_length) - if all(isnan(dar)): - return # Emergency Break - - # Create the Upper and Lower Bands around RSI MA. - upperband = rsi_ma + dar - lowerband = rsi_ma - dar - - m = close.size - long = Series(0, index=close.index) - short = Series(0, index=close.index) - trend = Series(1, index=close.index) - qqe = Series(rsi_ma.iat[0], index=close.index) - qqe_long = Series(nan, index=close.index) - qqe_short = Series(nan, index=close.index) - - for i in range(1, m): - c_rsi, p_rsi = rsi_ma.iat[i], rsi_ma.iat[i - 1] - c_long, p_long = long.iat[i - 1], long.iat[i - 2] - c_short, p_short = short.iat[i - 1], short.iat[i - 2] - - # Long Line - if p_rsi > c_long and c_rsi > c_long: - long.iat[i] = maximum(c_long, lowerband.iat[i]) - else: - long.iat[i] = lowerband.iat[i] - - # Short Line - if p_rsi < c_short and c_rsi < c_short: - short.iat[i] = minimum(c_short, upperband.iat[i]) - else: - short.iat[i] = upperband.iat[i] - - # Trend & QQE Calculation - # Long: Current RSI_MA value Crosses the Prior Short Line Value - # Short: Current RSI_MA Crosses the Prior Long Line Value - if (c_rsi > c_short and p_rsi < p_short) or \ - (c_rsi <= c_short and p_rsi >= p_short): - trend.iat[i] = 1 - qqe.iat[i] = qqe_long.iat[i] = long.iat[i] - elif (c_rsi > c_long and p_rsi < p_long) or \ - (c_rsi <= c_long and p_rsi >= p_long): - trend.iat[i] = -1 - qqe.iat[i] = qqe_short.iat[i] = short.iat[i] - else: - trend.iat[i] = trend.iat[i - 1] - if trend.iat[i] == 1: - qqe.iat[i] = qqe_long.iat[i] = long.iat[i] - else: - qqe.iat[i] = qqe_short.iat[i] = short.iat[i] - - # Offset - if offset != 0: - rsi_ma = rsi_ma.shift(offset) - qqe = qqe.shift(offset) - long = long.shift(offset) - short = short.shift(offset) - - # Fill - if "fillna" in kwargs: - rsi_ma.fillna(kwargs["fillna"], inplace=True) - qqe.fillna(kwargs["fillna"], inplace=True) - qqe_long.fillna(kwargs["fillna"], inplace=True) - qqe_short.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"{_mode}_{length}_{smooth}_{factor}" - qqe.name = f"QQE{_props}" - rsi_ma.name = f"QQE{_props}_RSI{_mode.upper()}MA" - qqe_long.name = f"QQEl{_props}" - qqe_short.name = f"QQEs{_props}" - qqe.category = rsi_ma.category = "momentum" - qqe_long.category = qqe_short.category = qqe.category - - data = { - qqe.name: qqe, - rsi_ma.name: rsi_ma, - # long.name: long, - # short.name: short - qqe_long.name: qqe_long, - qqe_short.name: qqe_short - } - df = DataFrame(data, index=close.index) - df.name = f"QQE{_props}" - df.category = qqe.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/roc.py b/src/aiomql/ta_libs/pandas_ta/momentum/roc.py deleted file mode 100644 index 123fa93..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/roc.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding: utf-8 -*- -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - nb_idiff, - nb_shift, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) -from .mom import mom - - - -@njit(cache=True) -def nb_roc(x, n, k): - return k * nb_idiff(x, n) / nb_shift(x, n) - - -def roc( - close: Series, length: Int = None, - scalar: IntFloat = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rate of Change - - This indicator, also (confusingly) known as Momentum, is a pure - oscillator that quantifies the percent change. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Rate_of_Change_(ROC)) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - scalar (float): Scalar. Default: ```100``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length + 1) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import ROC - roc = ROC(close, length) - else: - # roc = scalar * mom(close=close, length=length, talib=mode_tal) \ - # / close.shift(length) - np_close = close.to_numpy() - _roc = nb_roc(np_close, length, scalar) - roc = Series(_roc, index=close.index) - - # Offset - if offset != 0: - roc = roc.shift(offset) - - # Fill - if "fillna" in kwargs: - roc.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - roc.name = f"ROC_{length}" - roc.category = "momentum" - - return roc diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/rsi.py b/src/aiomql/ta_libs/pandas_ta/momentum/rsi.py deleted file mode 100644 index bdcde4d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/rsi.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, concat, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.ma import ma -from pandas_ta.utils import ( - signals, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) - - - -def rsi( - close: Series, length: Int = None, scalar: IntFloat = None, - mamode: str = None, talib: bool = None, - drift: Int = None, offset: Int = None, - **kwargs: DictLike -) -> Series: - """Relative Strength Index - - This oscillator used to attempts to quantify "velocity" and "magnitude". - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Relative_Strength_Index_(RSI)) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - scalar (float): Scalar. Default: ```100``` - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9289853267851295)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length + 1) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import RSI - rsi = RSI(close, length) - else: - negative = close.diff(drift) - positive = negative.copy() - - positive[positive < 0] = 0 # Make negatives 0 for the positive series - negative[negative > 0] = 0 # Make positives 0 for the negative series - - positive_avg = ma(mamode, positive, length=length, talib=mode_tal) - negative_avg = ma(mamode, negative, length=length, talib=mode_tal) - - rsi = scalar * positive_avg / (positive_avg + negative_avg.abs()) - - # Offset - if offset != 0: - rsi = rsi.shift(offset) - - # Fill - if "fillna" in kwargs: - rsi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rsi.name = f"RSI_{length}" - rsi.category = "momentum" - - signal_indicators = kwargs.pop("signal_indicators", False) - if not signal_indicators: - return rsi - else: - signalsdf = concat( - [ - DataFrame({rsi.name: rsi}), - signals( - indicator=rsi, - xa=kwargs.pop("xa", 80), - xb=kwargs.pop("xb", 20), - xseries=kwargs.pop("xseries", None), - xseries_a=kwargs.pop("xseries_a", None), - xseries_b=kwargs.pop("xseries_b", None), - cross_values=kwargs.pop("cross_values", False), - cross_series=kwargs.pop("cross_series", True), - offset=offset, - ), - ], - axis=1, - ) - return signalsdf diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/rsx.py b/src/aiomql/ta_libs/pandas_ta/momentum/rsx.py deleted file mode 100644 index 7f01dbd..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/rsx.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas_ta._typing import DictLike, Int -from pandas import concat, DataFrame, Series -from pandas_ta.utils import ( - signals, - v_drift, - v_offset, - v_pos_default, - v_series -) -from shutil import which - - - -def rsx( - close: Series, length: Int = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Relative Strength Xtra - - This indicator, by Jurik Research, is an enhanced version of the RSI which - attemps to reduce noise and provide a clearer, though slightly - delayed, signal. - - Sources: - * [jurikres](http://www.jurikres.com/catalog1/ms_rsx.htm) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/jurik-rsx/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length) - - if close is None: - return - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - m = close.size - vC, v1C = 0, 0 - v4, v8, v10, v14, v18, v20 = 0, 0, 0, 0, 0, 0 - - f0, f8, f10, f18, f20, f28, f30, f38 = 0, 0, 0, 0, 0, 0, 0, 0 - f40, f48, f50, f58, f60, f68, f70, f78 = 0, 0, 0, 0, 0, 0, 0, 0 - f80, f88, f90 = 0, 0, 0 - - result = [nan for _ in range(0, length - 1)] + [50] - for i in range(length, m): - if f90 == 0: - f90 = 1.0 - f0 = 0.0 - if length - 1.0 >= 5: - f88 = length - 1.0 - else: - f88 = 5.0 - f8 = 100.0 * close.iat[i] - f18 = 3.0 / (length + 2.0) - f20 = 1.0 - f18 - else: - if f88 <= f90: - f90 = f88 + 1 - else: - f90 = f90 + 1 - f10 = f8 - f8 = 100 * close.iat[i] - v8 = f8 - f10 - f28 = f20 * f28 + f18 * v8 - f30 = f18 * f28 + f20 * f30 - vC = 1.5 * f28 - 0.5 * f30 - f38 = f20 * f38 + f18 * vC - f40 = f18 * f38 + f20 * f40 - v10 = 1.5 * f38 - 0.5 * f40 - f48 = f20 * f48 + f18 * v10 - f50 = f18 * f48 + f20 * f50 - v14 = 1.5 * f48 - 0.5 * f50 - f58 = f20 * f58 + f18 * abs(v8) - f60 = f18 * f58 + f20 * f60 - v18 = 1.5 * f58 - 0.5 * f60 - f68 = f20 * f68 + f18 * v18 - f70 = f18 * f68 + f20 * f70 - v1C = 1.5 * f68 - 0.5 * f70 - f78 = f20 * f78 + f18 * v1C - f80 = f18 * f78 + f20 * f80 - v20 = 1.5 * f78 - 0.5 * f80 - - if f88 >= f90 and f8 != f10: - f0 = 1.0 - if f88 == f90 and f0 == 0.0: - f90 = 0.0 - - if f88 < f90 and v20 > 0.0000000001: - v4 = (v14 / v20 + 1.0) * 50.0 - if v4 > 100.0: - v4 = 100.0 - if v4 < 0.0: - v4 = 0.0 - else: - v4 = 50.0 - result.append(v4) - rsx = Series(result, index=close.index) - - # Offset - if offset != 0: - rsx = rsx.shift(offset) - - # Fill - if "fillna" in kwargs: - rsx.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rsx.name = f"RSX_{length}" - rsx.category = "momentum" - - signal_indicators = kwargs.pop("signal_indicators", False) - if not signal_indicators: - return rsx - else: - signalsdf = concat( - [ - DataFrame({rsx.name: rsx}), - signals( - indicator=rsx, - xa=kwargs.pop("xa", 80), - xb=kwargs.pop("xb", 20), - xseries=kwargs.pop("xseries", None), - xseries_a=kwargs.pop("xseries_a", None), - xseries_b=kwargs.pop("xseries_b", None), - cross_values=kwargs.pop("cross_values", False), - cross_series=kwargs.pop("cross_series", True), - offset=offset, - ), - ], - axis=1 - ) - return signalsdf diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/rvgi.py b/src/aiomql/ta_libs/pandas_ta/momentum/rvgi.py deleted file mode 100644 index f47db37..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/rvgi.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import swma -from pandas_ta.utils import non_zero_range, v_offset, v_pos_default, v_series - - - -def rvgi( - open_: Series, high: Series, low: Series, close: Series, - length: Int = None, swma_length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Relative Vigor Index - - This indicator attempts to quantify the strength of a trend relative to - its trading range. - - Sources: - * [investopedia](https://www.investopedia.com/terms/r/relative_vigor_index.asp) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - swma_length (int): SWMA period. Default: ```4``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - swma_length = v_pos_default(swma_length, 4) - _length = length + swma_length - 1 - open_ = v_series(open_, _length) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if open_ is None or high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - high_low_range = non_zero_range(high, low) - close_open_range = non_zero_range(close, open_) - - numerator = swma(close_open_range, length=swma_length) \ - .rolling(length).sum() - denominator = swma(high_low_range, length=swma_length) \ - .rolling(length).sum() - - rvgi = numerator / denominator - signal = swma(rvgi, length=swma_length) - - if all(isnan(signal.to_numpy())): - return # Emergency Break - - # Offset - if offset != 0: - rvgi = rvgi.shift(offset) - signal = signal.shift(offset) - - # Fill - if "fillna" in kwargs: - rvgi.fillna(kwargs["fillna"], inplace=True) - signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rvgi.name = f"RVGI_{length}_{swma_length}" - signal.name = f"RVGIs_{length}_{swma_length}" - rvgi.category = signal.category = "momentum" - - data = {rvgi.name: rvgi, signal.name: signal} - df = DataFrame(data, index=close.index) - df.name = f"RVGI_{length}_{swma_length}" - df.category = rvgi.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/slope.py b/src/aiomql/ta_libs/pandas_ta/momentum/slope.py deleted file mode 100644 index f6469da..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/slope.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import arctan, pi, rad2deg -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - nb_idiff, - v_bool, - v_offset, - v_pos_default, - v_series -) - - - -def slope( - close: Series, length: Int = None, - as_angle: bool = None, to_degrees: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Slope - - Calculates a rolling slope. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - as_angle (bool): Converts slope to an angle in radians - per ```np.arctan()```. Default: ```False``` - to_degrees (value): If ```as_angle=True```, converts radians to - degrees. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length + 1) - - if close is None: - return - - as_angle = v_bool(as_angle, False) - to_degrees = v_bool(to_degrees, False) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - _slope = nb_idiff(np_close, length) / length - if as_angle: - _slope = arctan(_slope) - if to_degrees: - _slope = rad2deg(_slope) - slope = Series(_slope, index=close.index) - - # Offset - if offset != 0: - slope = slope.shift(offset) - - # Fill - if "fillna" in kwargs: - slope.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - slope.name = f"SLOPE_{length}" if not as_angle else f"ANGLE{'d' if to_degrees else 'r'}_{length}" - slope.category = "momentum" - - return slope diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/smc.py b/src/aiomql/ta_libs/pandas_ta/momentum/smc.py deleted file mode 100644 index c056812..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/smc.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -from sys import float_info as sflt -from numpy import isnan, maximum, minimum, nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) - - -def smc( - open_: Series, high: Series, low: Series, close: Series, - abr_length: Int = None, close_length: Int = None, vol_length: Int = None, - percent: Int = None, vol_ratio: IntFloat = None, asint: bool = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DictLike: - """Smart Money Concept - - This indicator combines several techniques in an attempt to identify - significant movements that might indicate "smart money" actions. - It uses candlestick patterns, moving averages, and imbalance calculations. - - Sources: - * [tradingview](https://www.tradingview.com/script/CnB3fSph-Smart-Money-Concepts-LuxAlgo/) - - Parameters: - abr_length (int): ABR length. Default: ```14``` - close_length (int): The ```close``` MA period. Default: ```50``` - vol_length (int): Volatility period. Default: ```20``` - percent (int): Percent of wick that exceeds the body. Default: ```5``` - vol_ratio (float): Volatility ratio (high) limit. Default: ```1.5``` - asint (bool): Returns as ```Int```. Default: ```True``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Returns: - (pd.DataFrame): 7 columns - """ - # Validate - abr_length = v_pos_default(abr_length, 14) - close_length = v_pos_default(close_length, 50) - vol_length = v_pos_default(vol_length, 20) - if close_length < abr_length: - abr_length, close_length = close_length, abr_length - _length = max(abr_length, close_length, vol_length) + 1 - - open_ = v_series(open_, _length) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if open_ is None or high is None or low is None or close is None: - return - - percent = v_pos_default(percent, 5) - body_percent = 0.01 * percent - vol_ratio = v_scalar(vol_ratio, 1.5) - asint = v_bool(asint) - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - body_high, body_low = maximum(open_, close), minimum(open_, close) - body = body_high - body_low + sflt.epsilon - close_ma = ma(mamode, body, length=close_length, talib=mode_tal) - - # Calculate imbalance sizes and percentages based on Average Bar Range (abr) - abr = high.rolling(window=abr_length).max() - low.rolling(window=abr_length).min() - top_imbalance = low.shift(2) - high - btm_imbalance = low - high.shift(2) - top_imbalance_pct = 100 * top_imbalance / abr - btm_imbalance_pct = 100 * btm_imbalance / abr - hld = high - low + sflt.epsilon - high_volatility = hld > vol_ratio * ma(mamode, hld, length=vol_length, talib=mode_tal) - - btm_imbalance_flag = (btm_imbalance > 0) & (btm_imbalance_pct > 1) - top_imbalance_flag = (top_imbalance > 0) & (top_imbalance_pct > 1) - - if asint: - high_volatility = high_volatility.astype(int) - btm_imbalance_flag = btm_imbalance_flag.astype(int) - top_imbalance_flag = top_imbalance_flag.astype(int) - - _props = f"_{abr_length}_{close_length}_{vol_length}_{percent}" - data = { - f"SMChv{_props}": high_volatility, - f"SMCbf{_props}": btm_imbalance_flag, - f"SMCbi{_props}": btm_imbalance, - f"SMCbp{_props}": btm_imbalance_pct, - f"SMCtf{_props}": top_imbalance_flag, - f"SMCti{_props}": top_imbalance, - f"SMCtp{_props}": top_imbalance_pct, - } - df = DataFrame(data, index=close.index) - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - df.ffill(inplace=True) - df.bfill(inplace=True) - - # Name and Category - df.name = f"SMC{_props}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/smi.py b/src/aiomql/ta_libs/pandas_ta/momentum/smi.py deleted file mode 100644 index 7a513e8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/smi.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_scalar, v_series -from .tsi import tsi - - - -def smi( - close: Series, fast: Int = None, slow: Int = None, - signal: Int = None, scalar: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """SMI Ergodic Indicator - - This indicator, by William Blau, is the same as the TSI except the SMI - includes a signal line. A trend is considered bullish when crossing above - zero and bearish when crossing below zero. This implementation includes - both the SMI Ergodic Indicator and SMI Ergodic Oscillator. - - Sources: - * [motivewave](https://www.motivewave.com/studies/smi_ergodic_indicator.htm) - * [tradingview A](https://www.tradingview.com/script/Xh5Q0une-SMI-Ergodic-Oscillator/) - * [tradingview B](https://www.tradingview.com/script/cwrgy4fw-SMIIO/) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): The short period. Default: ```5``` - slow (int): The long period. Default: ```20``` - signal (int): Signal period. Default: ```5``` - scalar (float): Scalar. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - fast = v_pos_default(fast, 5) - slow = v_pos_default(slow, 20) - signal = v_pos_default(signal, 5) - if slow < fast: - fast, slow = slow, fast - _length = slow + signal + 1 - close = v_series(close, _length) - - if close is None: - return - - scalar = v_scalar(scalar, 1) - offset = v_offset(offset) - - # Calculate - tsi_df = tsi(close, fast=fast, slow=slow, signal=signal, scalar=scalar) - if tsi_df is None: - return # Emergency Break - - smi = tsi_df.iloc[:, 0] - signalma = tsi_df.iloc[:, 1] - if all(isnan(signalma)): - return # Emergency Break - osc = smi - signalma - - # Offset - if offset != 0: - smi = smi.shift(offset) - signalma = signalma.shift(offset) - osc = osc.shift(offset) - - # Fill - if "fillna" in kwargs: - smi.fillna(kwargs["fillna"], inplace=True) - signalma.fillna(kwargs["fillna"], inplace=True) - osc.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - # _scalar = f"_{scalar}" if scalar != 1 else "" - _props = f"_{fast}_{slow}_{signal}_{scalar}" - smi.name = f"SMI{_props}" - signalma.name = f"SMIs{_props}" - osc.name = f"SMIo{_props}" - smi.category = signalma.category = osc.category = "momentum" - - data = {smi.name: smi, signalma.name: signalma, osc.name: osc} - df = DataFrame(data, index=close.index) - df.name = f"SMI{_props}" - df.category = smi.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/squeeze.py b/src/aiomql/ta_libs/pandas_ta/momentum/squeeze.py deleted file mode 100644 index cb306cb..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/squeeze.py +++ /dev/null @@ -1,205 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import ema, linreg, sma -from pandas_ta.trend import decreasing, increasing -from pandas_ta.utils import ( - simplify_columns, - unsigned_differences, - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_series -) -from pandas_ta.volatility import bbands, kc -from .mom import mom - - - -def squeeze( - high: Series, low: Series, close: Series, - bb_length: Int = None, bb_std: IntFloat = None, - kc_length: Int = None, kc_scalar: IntFloat = None, - mom_length: Int = None, mom_smooth: Int = None, - use_tr: bool = None, mamode: str = None, - prenan: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Squeeze - - This indicator, based on John Carter's "TTM Squeeze" indicator, attempts - identify momentum using volatility. - - Sources: - * "Mastering the Trade" (chapter 11), John Carter - * [thinkorswim](https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/T-U/TTM-Squeeze) - * [tradestation](https://tradestation.tradingappstore.com/products/TTMSqueeze) - * [tradingview](https://www.tradingview.com/scripts/lazybear/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - bb_length (int): BB period. Default: ```20``` - bb_std (float): BB Std. Dev. Default: ```2``` - kc_length (int): KC period. Default: ```20``` - kc_scalar (float): KC scalar. Default: ```1.5``` - mom_length (int): Momentum Period. Default: ```12``` - mom_smooth (int): Momentum Smoothing period. Default: ```6``` - mamode (str): One of: "ema" or "sma". Default: ```"sma"``` - prenan (bool): Apply prenans. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - tr (value): Use True Range for Keltner Channels. Default: ```True``` - asint (bool): Returns as ```Int```. Default: ```True``` - lazybear (value): LazyBear's TradingView. Default: ```False``` - detailed (value): Extra detailed. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): - * Default: 4 columns - * Detailed: 10 columns - - Note: Volatility - * Increasing: ```kc``` and ```bbands``` difference increases - * Decreasing: ```kc``` and ```bbands``` difference decreases - """ - # Validate - bb_length = v_pos_default(bb_length, 20) - kc_length = v_pos_default(kc_length, 20) - mom_length = v_pos_default(mom_length, 12) - mom_smooth = v_pos_default(mom_smooth, 6) - _length = max(bb_length, kc_length, mom_length, mom_smooth) + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - bb_std = v_pos_default(bb_std, 2.0) - kc_scalar = v_pos_default(kc_scalar, 1.5) - mamode = v_mamode(mamode, "sma") - prenan = v_bool(prenan, False) - offset = v_offset(offset) - - use_tr = kwargs.pop("tr", True) - asint = kwargs.pop("asint", True) - detailed = kwargs.pop("detailed", False) - lazybear = kwargs.pop("lazybear", False) - - # Calculate - bbd = bbands(close, length=bb_length, std=bb_std, mamode=mamode) - kch = kc( - high, low, close, length=kc_length, scalar=kc_scalar, - mamode=mamode, tr=use_tr - ) - - # Simplify KC and BBAND column names for dynamic access - bbd.columns = simplify_columns(bbd) - kch.columns = simplify_columns(kch) - - if lazybear: - highest_high = high.rolling(kc_length).max() - lowest_low = low.rolling(kc_length).min() - avg_ = 0.5 * (0.5 * (highest_high + lowest_low) + kch.b) - - squeeze = linreg(close - avg_, length=kc_length) - - else: - momo = mom(close, length=mom_length) - if mamode.lower() == "ema": - squeeze = ema(momo, length=mom_smooth) - else: # "sma" - squeeze = sma(momo, length=mom_smooth) - - # Classify Squeezes - squeeze_on = (bbd.l > kch.l) & (bbd.u < kch.u) - squeeze_off = (bbd.l < kch.l) & (bbd.u > kch.u) - no_squeeze = ~squeeze_on & ~squeeze_off - - # Offset - if offset != 0: - squeeze = squeeze.shift(offset) - squeeze_on = squeeze_on.shift(offset) - squeeze_off = squeeze_off.shift(offset) - no_squeeze = no_squeeze.shift(offset) - - # Fill - if "fillna" in kwargs: - squeeze.fillna(kwargs["fillna"], inplace=True) - squeeze_on.fillna(kwargs["fillna"], inplace=True) - squeeze_off.fillna(kwargs["fillna"], inplace=True) - no_squeeze.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = "" if use_tr else "hlr" - _props += f"_{bb_length}_{bb_std}_{kc_length}_{kc_scalar}" - _props += "_LB" if lazybear else "" - squeeze.name = f"SQZ{_props}" - - if asint: - squeeze_on = squeeze_on.astype(int) - squeeze_off = squeeze_off.astype(int) - no_squeeze = no_squeeze.astype(int) - - if prenan: - nanlength = max(bb_length, kc_length) - 2 - squeeze_on[:nanlength] = nan - squeeze_off[:nanlength] = nan - no_squeeze[:nanlength] = nan - - data = { - squeeze.name: squeeze, - f"SQZ_ON": squeeze_on, - f"SQZ_OFF": squeeze_off, - f"SQZ_NO": no_squeeze - } - df = DataFrame(data, index=close.index) - df.name = squeeze.name - df.category = squeeze.category = "momentum" - - # More Detail - if detailed: - pos_squeeze = squeeze[squeeze >= 0] - neg_squeeze = squeeze[squeeze < 0] - - pos_inc, pos_dec = unsigned_differences(pos_squeeze, asint=True) - neg_inc, neg_dec = unsigned_differences(neg_squeeze, asint=True) - - pos_inc *= squeeze - pos_dec *= squeeze - neg_dec *= squeeze - neg_inc *= squeeze - - pos_inc.replace(0, nan, inplace=True) - pos_dec.replace(0, nan, inplace=True) - neg_dec.replace(0, nan, inplace=True) - neg_inc.replace(0, nan, inplace=True) - - sqz_inc = squeeze * increasing(squeeze) - sqz_dec = squeeze * decreasing(squeeze) - sqz_inc.replace(0, nan, inplace=True) - sqz_dec.replace(0, nan, inplace=True) - - # Handle fills - if "fillna" in kwargs: - sqz_inc.fillna(kwargs["fillna"], inplace=True) - sqz_dec.fillna(kwargs["fillna"], inplace=True) - pos_inc.fillna(kwargs["fillna"], inplace=True) - pos_dec.fillna(kwargs["fillna"], inplace=True) - neg_dec.fillna(kwargs["fillna"], inplace=True) - neg_inc.fillna(kwargs["fillna"], inplace=True) - - df[f"SQZ_INC"] = sqz_inc - df[f"SQZ_DEC"] = sqz_dec - df[f"SQZ_PINC"] = pos_inc - df[f"SQZ_PDEC"] = pos_dec - df[f"SQZ_NDEC"] = neg_dec - df[f"SQZ_NINC"] = neg_inc - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/squeeze_pro.py b/src/aiomql/ta_libs/pandas_ta/momentum/squeeze_pro.py deleted file mode 100644 index 690f713..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/squeeze_pro.py +++ /dev/null @@ -1,222 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.momentum import mom -from pandas_ta.trend import decreasing, increasing -from pandas_ta.utils import ( - simplify_columns, - unsigned_differences, - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series -) -from pandas_ta.volatility import bbands, kc - - - -def squeeze_pro( - high: Series, low: Series, close: Series, - bb_length: Int = None, bb_std: IntFloat = None, - kc_length: Int = None, kc_scalar_narrow: IntFloat = None, - kc_scalar_normal: IntFloat = None, kc_scalar_wide: IntFloat = None, - mom_length: Int = None, mom_smooth: Int = None, - use_tr: bool = None, mamode: str = None, - prenan: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Squeeze Pro - - This indicator, based on John Carter's "TTM Squeeze" indicator, attempts - identify momentum using volatility with additional details. - - Sources: - * [usethinkscript](https://usethinkscript.com/threads/john-carters-squeeze-pro-indicator-for-thinkorswim-free.4021/) - * [tradingview](https://www.tradingview.com/script/TAAt6eRX-Squeeze-PRO-Indicator-Makit0/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - bb_length (int): BB period. Default: ```20``` - bb_std (float): BB Std. Dev. Default: ```2``` - kc_length (int): KC period. Default: ```20``` - kc_scalar_normal (float): Keltner Channel scalar for normal channel. - Default: ```1.5``` - kc_scalar_narrow (float): Narrow channel KC scalar. Default: ```1``` - kc_scalar_wide (float): Wide channel KC scalar. Default: ```2``` - mom_length (int): Momentum Period. Default: ```12``` - mom_smooth (int): Momentum Smoothing period. Default: ```6``` - mamode (str): One of: "ema" or "sma". Default: ```"sma"``` - prenan (bool): Apply prenans. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - tr (value): Use True Range for Keltner Channels. - Default: ```True``` - asint (bool): Returns as ```Int```. Default: ```True``` - mamode (value): Which MA to use. Default: ```"sma"``` - detailed (value): Extra detailed. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 6 columns (_default_) or 12 columns if ```detailed=True``` - - Warning: - May be depreciated in the future and combined with ```squeeze```. - """ - # Validate - bb_length = v_pos_default(bb_length, 20) - kc_length = v_pos_default(kc_length, 20) - mom_length = v_pos_default(mom_length, 12) - mom_smooth = v_pos_default(mom_smooth, 6) - _length = max(bb_length, kc_length, mom_length, mom_smooth) + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - kc_scalar_narrow = v_scalar(kc_scalar_narrow, 1) - kc_scalar_normal = v_scalar(kc_scalar_normal, 1.5) - kc_scalar_wide = v_scalar(kc_scalar_wide, 2) - prenan = v_bool(prenan, False) - valid_kc_scaler = kc_scalar_wide > kc_scalar_normal \ - and kc_scalar_normal > kc_scalar_narrow - - if not valid_kc_scaler: - return - - bb_std = v_pos_default(bb_std, 2.0) - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - use_tr = kwargs.pop("tr", True) - asint = kwargs.pop("asint", True) - detailed = kwargs.pop("detailed", False) - - # Calculate - bbd = bbands(close, length=bb_length, std=bb_std, mamode=mamode) - kch_wide = kc( - high, low, close, length=kc_length, scalar=kc_scalar_wide, - mamode=mamode, tr=use_tr - ) - kch_normal = kc( - high, low, close, length=kc_length, scalar=kc_scalar_normal, - mamode=mamode, tr=use_tr - ) - kch_narrow = kc( - high, low, close, length=kc_length, scalar=kc_scalar_narrow, - mamode=mamode, tr=use_tr - ) - - # Simplify KC and BBAND column names for dynamic access - bbd.columns = simplify_columns(bbd) - kch_wide.columns = simplify_columns(kch_wide) - kch_normal.columns = simplify_columns(kch_normal) - kch_narrow.columns = simplify_columns(kch_narrow) - - momo = mom(close, length=mom_length) - squeeze = ma(mamode, momo, length=mom_smooth) - - # Classify Squeezes - squeeze_on_wide = (bbd.l > kch_wide.l) & (bbd.u < kch_wide.u) - squeeze_on_normal = (bbd.l > kch_normal.l) & (bbd.u < kch_normal.u) - squeeze_on_narrow = (bbd.l > kch_narrow.l) & (bbd.u < kch_narrow.u) - squeeze_off_wide = (bbd.l < kch_wide.l) & (bbd.u > kch_wide.u) - no_squeeze = ~squeeze_on_wide & ~squeeze_off_wide - - # Offset - if offset != 0: - squeeze = squeeze.shift(offset) - squeeze_on_wide = squeeze_on_wide.shift(offset) - squeeze_on_normal = squeeze_on_normal.shift(offset) - squeeze_on_narrow = squeeze_on_narrow.shift(offset) - squeeze_off_wide = squeeze_off_wide.shift(offset) - no_squeeze = no_squeeze.shift(offset) - - # Fill - if "fillna" in kwargs: - squeeze.fillna(kwargs["fillna"], inplace=True) - squeeze_on_wide.fillna(kwargs["fillna"], inplace=True) - squeeze_on_normal.fillna(kwargs["fillna"], inplace=True) - squeeze_on_narrow.fillna(kwargs["fillna"], inplace=True) - squeeze_off_wide.fillna(kwargs["fillna"], inplace=True) - no_squeeze.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = "" if use_tr else "hlr" - _props += f"_{bb_length}_{bb_std}_{kc_length}_{kc_scalar_wide}_{kc_scalar_normal}_{kc_scalar_narrow}" - squeeze.name = f"SQZPRO{_props}" - - if asint: - squeeze_on_wide = squeeze_on_wide.astype(int) - squeeze_on_narrow = squeeze_on_narrow.astype(int) - squeeze_on_normal = squeeze_on_normal.astype(int) - squeeze_off_wide = squeeze_off_wide.astype(int) - no_squeeze = no_squeeze.astype(int) - - if prenan: - nanlength = max(bb_length, kc_length) - 2 - squeeze_on_wide[:nanlength] = nan - squeeze_on_narrow[:nanlength] = nan - squeeze_on_normal[:nanlength] = nan - squeeze_off_wide[:nanlength] = nan - no_squeeze[:nanlength] = nan - - data = { - squeeze.name: squeeze, - f"SQZPRO_ON_WIDE": squeeze_on_wide, - f"SQZPRO_ON_NORMAL": squeeze_on_normal, - f"SQZPRO_ON_NARROW": squeeze_on_narrow, - f"SQZPRO_OFF": squeeze_off_wide, - f"SQZPRO_NO": no_squeeze - } - df = DataFrame(data, index=close.index) - df.name = squeeze.name - df.category = squeeze.category = "momentum" - - # More Detail - if detailed: - pos_squeeze = squeeze[squeeze >= 0] - neg_squeeze = squeeze[squeeze < 0] - - pos_inc, pos_dec = unsigned_differences(pos_squeeze, asint=True) - neg_inc, neg_dec = unsigned_differences(neg_squeeze, asint=True) - - pos_inc *= squeeze - pos_dec *= squeeze - neg_dec *= squeeze - neg_inc *= squeeze - - pos_inc.replace(0, nan, inplace=True) - pos_dec.replace(0, nan, inplace=True) - neg_dec.replace(0, nan, inplace=True) - neg_inc.replace(0, nan, inplace=True) - - sqz_inc = squeeze * increasing(squeeze) - sqz_dec = squeeze * decreasing(squeeze) - sqz_inc.replace(0, nan, inplace=True) - sqz_dec.replace(0, nan, inplace=True) - - # Fill - if "fillna" in kwargs: - sqz_inc.fillna(kwargs["fillna"], inplace=True) - sqz_dec.fillna(kwargs["fillna"], inplace=True) - pos_inc.fillna(kwargs["fillna"], inplace=True) - pos_dec.fillna(kwargs["fillna"], inplace=True) - neg_dec.fillna(kwargs["fillna"], inplace=True) - neg_inc.fillna(kwargs["fillna"], inplace=True) - - df[f"SQZPRO_INC"] = sqz_inc - df[f"SQZPRO_DEC"] = sqz_dec - df[f"SQZPRO_PINC"] = pos_inc - df[f"SQZPRO_PDEC"] = pos_dec - df[f"SQZPRO_NDEC"] = neg_dec - df[f"SQZPRO_NINC"] = neg_inc - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/stc.py b/src/aiomql/ta_libs/pandas_ta/momentum/stc.py deleted file mode 100644 index 528e12d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/stc.py +++ /dev/null @@ -1,175 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import ema -from pandas_ta.utils import ( - non_zero_range, - v_offset, - v_pos_default, - v_series -) - - - -def schaff_tc(close: Series, seed: Series, tc_length: int, factor: IntFloat): - lowest_xmacd = seed.rolling(tc_length).min() - xmacd_range = non_zero_range(seed.rolling(tc_length).max(), lowest_xmacd) - m = len(seed) - - # Initialize lists - stoch1, pf = [0] * m, [0] * m - stoch2, pff = [0] * m, [0] * m - - for i in range(1, m): - # %Fast K of MACD - if lowest_xmacd.iloc[i] > 0: - stoch1[i] = 100 * ((seed.iloc[i] - lowest_xmacd.iloc[i]) / xmacd_range.iloc[i]) - else: - stoch1[i] = stoch1[i - 1] - # Smoothed Calculation for % Fast D of MACD - pf[i] = round(pf[i - 1] + (factor * (stoch1[i] - pf[i - 1])), 8) - - # find min and max so far - if i < tc_length: - # If there are not enough elements for a full tclength window, - # use what is available - lowest_pf = min(pf[:i+1]) - highest_pf = max(pf[:i+1]) - else: - lowest_pf = min(pf[i - tc_length + 1:i + 1]) - highest_pf = max(pf[i - tc_length + 1:i + 1]) - - # Ensure non-zero range - pf_range = highest_pf - lowest_pf if highest_pf - lowest_pf > 0 else 1 - - # % of Fast K of PF - if pf_range > 0: - stoch2[i] = 100 * ((pf[i] - lowest_pf) / pf_range) - else: - stoch2[i] = stoch2[i - 1] - pff[i] = round(pff[i - 1] + (factor * (stoch2[i] - pff[i - 1])), 8) - - pf_series = Series(pf, index=close.index) - pff_series = Series(pff, index=close.index) - - return pff_series, pf_series - - -def stc( - close: Series, tc_length: Int = None, - fast: Int = None, slow: Int = None, factor: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Schaff Trend Cycle - - This indicator is an evolved MACD with additional smoothing. - - Sources: - * [rengel8](https://github.com/rengel8) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/schaff-trend-cycle2/) - - Parameters: - close (pd.Series): ```close``` Series - tc_length (int): TC period. (Adjust to the half of cycle) - Default: ```10``` - fast (int): Fast MA period. Default: ```12``` - slow (int): Slow MA period. Default: ```26``` - factor (float): Smoothing factor for last stoch. calculation. - Default: ```0.5``` - offset (int): How many bars to shift the results. Default: ```0`` - - Other Parameters: - ma1 (Series): User chosen MA. Default: ```False``` - ma2 (Series): User chosen MA. Default: ```False``` - osc (Series): User chosen oscillator. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - - Note: - Can also seed STC with two MAs, ```ma1``` and ```ma2```, or an oscillator ```osc```. - - * ```ma1``` and ```ma2``` are **both** required if this option is used. - """ - # Validate - fast = v_pos_default(fast, 12) - slow = v_pos_default(slow, 26) - tc_length = v_pos_default(tc_length, 10) - if slow < fast: - fast, slow = slow, fast - _length = max(tc_length, fast, slow) - close = v_series(close, _length) - - if close is None: - return - - factor = v_pos_default(factor, 0.5) - offset = v_offset(offset) - - # Calculate - # kwargs allows for three more series (ma1, ma2 and osc) which can be passed - # here ma1 and ma2 input negate internal ema calculations, osc substitutes - # both ma's. - ma1 = kwargs.pop("ma1", False) - ma2 = kwargs.pop("ma2", False) - osc = kwargs.pop("osc", False) - - if isinstance(ma1, Series) and isinstance(ma2, Series) and not osc: - ma1 = v_series(ma1, _length) - ma2 = v_series(ma2, _length) - - if ma1 is None or ma2 is None: - return - seed = ma1 - ma2 - - elif isinstance(osc, Series): - osc = v_series(osc, _length) - if osc is None: - return - seed = osc - - else: - fastma = ema(close, length=fast) - slowma = ema(close, length=slow) - seed = fastma - slowma - - pff, pf = schaff_tc(close, seed, tc_length, factor) - pf[:_length - 1] = nan - - stc = Series(pff, index=close.index) - macd = Series(seed, index=close.index) - stoch = Series(pf, index=close.index) - - stc.iloc[:_length - 1] = nan - - # Offset - if offset != 0: - stc = stc.shift(offset) - macd = macd.shift(offset) - stoch = stoch.shift(offset) - - # Fill - if "fillna" in kwargs: - stc.fillna(kwargs["fillna"], inplace=True) - macd.fillna(kwargs["fillna"], inplace=True) - stoch.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{tc_length}_{fast}_{slow}_{factor}" - stc.name = f"STC{_props}" - macd.name = f"STCmacd{_props}" - stoch.name = f"STCstoch{_props}" - stc.category = macd.category = stoch.category = "momentum" - - data = { - stc.name: stc, - macd.name: macd, - stoch.name: stoch - } - df = DataFrame(data, index=close.index) - df.name = f"STC{_props}" - df.category = stc.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/stoch.py b/src/aiomql/ta_libs/pandas_ta/momentum/stoch.py deleted file mode 100644 index 74ba7e4..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/stoch.py +++ /dev/null @@ -1,121 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - non_zero_range, - tal_ma, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def stoch( - high: Series, low: Series, close: Series, - k: Int = None, d: Int = None, smooth_k: Int = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Stochastic - - This indicator, by George Lane in the 1950's, attempts to identify and - quantify momentum; it assumes that momentum precedes value change. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=332&Name=KD_-_Slow) - * [tradingview](https://www.tradingview.com/wiki/Stochastic_(STOCH)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - k (int): The Fast %K period. Default: ```14``` - d (int): The Slow %D period. Default: ```3``` - smooth_k (int): The Slow %K period. Default: ```3``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - k = v_pos_default(k, 14) - d = v_pos_default(d, 3) - smooth_k = v_pos_default(smooth_k, 3) - _length = k + d + smooth_k - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mode_tal = v_talib(talib) - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal and smooth_k > 2: - from talib import STOCH - stoch_ = STOCH( - high, low, close, k, d, tal_ma(mamode), d, tal_ma(mamode) - ) - stoch_k, stoch_d = stoch_[0], stoch_[1] - else: - ll = low.rolling(k).min() - hh = high.rolling(k).max() - - stoch = 100 * (close - ll) / non_zero_range(hh, ll) - - if stoch is None: return - - stoch_fvi = stoch.loc[stoch.first_valid_index():, ] - if smooth_k == 1: - stoch_k = stoch - else: - stoch_k = ma(mamode, stoch_fvi, length=smooth_k) - - stochk_fvi = stoch_k.loc[stoch_k.first_valid_index():, ] - stoch_d = ma(mamode, stochk_fvi, length=d) - - stoch_h = stoch_k - stoch_d # Histogram - - # Offset - if offset != 0: - stoch_k = stoch_k.shift(offset) - stoch_d = stoch_d.shift(offset) - stoch_h = stoch_h.shift(offset) - - # Fill - if "fillna" in kwargs: - stoch_k.fillna(kwargs["fillna"], inplace=True) - stoch_d.fillna(kwargs["fillna"], inplace=True) - stoch_h.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _name = "STOCH" - _props = f"_{k}_{d}_{smooth_k}" - stoch_k.name = f"{_name}k{_props}" - stoch_d.name = f"{_name}d{_props}" - stoch_h.name = f"{_name}h{_props}" - stoch_k.category = stoch_d.category = stoch_h.category = "momentum" - - data = { - stoch_k.name: stoch_k, - stoch_d.name: stoch_d, - stoch_h.name: stoch_h - } - df = DataFrame(data, index=close.index) - df.name = f"{_name}{_props}" - df.category = stoch_k.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/stochf.py b/src/aiomql/ta_libs/pandas_ta/momentum/stochf.py deleted file mode 100644 index 28f822d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/stochf.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - non_zero_range, - tal_ma, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def stochf( - high: Series, low: Series, close: Series, - k: Int = None, d: Int = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Fast Stochastic - - This indicator, by George Lane in the 1950's, attempts to identify and - quantify momentum like STOCH, but is more volatile. - - Sources: - * [corporatefinanceinstitute](https://corporatefinanceinstitute.com/resources/knowledge/trading-investing/fast-stochastic-indicator/) - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=333&Name=KD_-_Fast) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - k (int): The Fast %K period. Default: ```14``` - d (int): The Slow %D period. Default: ```3``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - k = v_pos_default(k, 14) - d = v_pos_default(d, 3) - _length = k + d - 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import STOCHF - stochf_ = STOCHF(high, low, close, k, d, tal_ma(mamode)) - stochf_k, stochf_d = stochf_[0], stochf_[1] - else: - lowest_low = low.rolling(k).min() - highest_high = high.rolling(k).max() - - stochf_k = 100 * (close - lowest_low) \ - / non_zero_range(highest_high, lowest_low) - stochfk_fvi = stochf_k.loc[stochf_k.first_valid_index():, ] - stochf_d = ma(mamode, stochfk_fvi, length=d, talib=mode_tal) - - # Offset - if offset != 0: - stochf_k = stochf_k.shift(offset) - stochf_d = stochf_d.shift(offset) - - # Fill - if "fillna" in kwargs: - stochf_k.fillna(kwargs["fillna"], inplace=True) - stochf_d.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _name = "STOCHF" - _props = f"_{k}_{d}" - stochf_k.name = f"{_name}k{_props}" - stochf_d.name = f"{_name}d{_props}" - stochf_k.category = stochf_d.category = "momentum" - - data = {stochf_k.name: stochf_k, stochf_d.name: stochf_d} - df = DataFrame(data, index=close.index) - df.name = f"{_name}{_props}" - df.category = stochf_k.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/stochrsi.py b/src/aiomql/ta_libs/pandas_ta/momentum/stochrsi.py deleted file mode 100644 index 1432921..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/stochrsi.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.momentum import rsi -from pandas_ta.utils import ( - non_zero_range, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def stochrsi( - close: Series, length: Int = None, rsi_length: Int = None, - k: Int = None, d: Int = None, mamode: str = None, - talib: bool = None, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Stochastic RSI - - This indicator attempts to quantify RSI relative to its High-Low range. - - Sources: - * "Stochastic RSI and Dynamic Momentum Index", Tushar Chande and - Stanley Kroll, Stock & Commodities V.11:5 (189-199) - * [tradingview](https://www.tradingview.com/wiki/Stochastic_(STOCH)) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - rsi_length (int): RSI period. Default: ```14``` - k (int): The Fast %K period. Default: ```3``` - d (int): The Slow %K period. Default: ```3``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - May be more sensitive to RSI and thus identify potential "overbought" - or "oversold" signals. - """ - # Validate - length = v_pos_default(length, 14) - rsi_length = v_pos_default(rsi_length, 14) - k = v_pos_default(k, 3) - d = v_pos_default(d, 3) - _length = length + rsi_length + 2 - close = v_series(close, _length) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - # if Imports["talib"] and mode_tal: - # from talib import RSI - # rsi_ = RSI(close, length) - # else: - - rsi_ = rsi(close, length=rsi_length) - lowest_rsi = rsi_.rolling(length).min() - highest_rsi = rsi_.rolling(length).max() - - stoch = 100 * (rsi_ - lowest_rsi) / non_zero_range(highest_rsi, lowest_rsi) - - stochrsi_k = ma(mamode, stoch, length=k) - stochrsi_d = ma(mamode, stochrsi_k, length=d) - - # Offset - if offset != 0: - stochrsi_k = stochrsi_k.shift(offset) - stochrsi_d = stochrsi_d.shift(offset) - - # Fill - if "fillna" in kwargs: - stochrsi_k.fillna(kwargs["fillna"], inplace=True) - stochrsi_d.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _name = "STOCHRSI" - _props = f"_{length}_{rsi_length}_{k}_{d}" - stochrsi_k.name = f"{_name}k{_props}" - stochrsi_d.name = f"{_name}d{_props}" - stochrsi_k.category = stochrsi_d.category = "momentum" - - data = {stochrsi_k.name: stochrsi_k, stochrsi_d.name: stochrsi_d} - df = DataFrame(data, index=close.index) - df.name = f"{_name}{_props}" - df.category = stochrsi_k.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/tmo.py b/src/aiomql/ta_libs/pandas_ta/momentum/tmo.py deleted file mode 100644 index 8e25f0b..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/tmo.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, zeros -from pandas import DataFrame, Series - -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - sum_signed_rolling_deltas, - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - -def tmo( - open_: Series, close: Series, - tmo_length: Int = None, calc_length: Int = None, smooth_length: Int = None, - momentum: bool = None, normalize: bool = None, exclusive: bool = None, - mamode: str = None, offset: Int = None, **kwargs: DictLike, -) -> DataFrame: - """True Momentum Oscillator - - This indicator attempts to quantify momentum. - - Sources: - * [tradingview A](https://www.tradingview.com/script/VRwDppqd-True-Momentum-Oscillator/) - * [tradingview B](https://www.tradingview.com/script/65vpO7T5-True-Momentum-Oscillator-Universal-Edition/) - - Parameters: - open_ (pd.Series): ```open``` Series - close (pd.Series): ```close``` Series - tmo_length (int): TMO period. Default: ```14``` - calc_length (int): Initial MA period. Default: ```5``` - smooth_length (int): Main and smooth signal MA period. Default: ```3``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - momentum (bool): Compute main and smooth momentum. Default: ```False``` - normalize (bool): Normalize. Default: ```False``` - exclusive (bool): Exclusive period over ```n``` bars, or inclusively - over ```n-1``` bars. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): DataFrame.fillna(value) - - Returns: - (pd.DataFrame): 4 columns - """ - # Validate - tmo_length = v_pos_default(tmo_length, 14) - calc_length = v_pos_default(calc_length, 5) - smooth_length = v_pos_default(smooth_length, 3) - _length = max(tmo_length, calc_length, smooth_length) - - open_ = v_series(open_, _length) - close = v_series(close, _length) - offset = v_offset(offset) - - if "length" in kwargs: - kwargs.pop("length") - - if open_ is None or close is None: - return None - - mamode = v_mamode(mamode, "ema") - compute_momentum = v_bool(momentum, False) - normalize_signal = v_bool(normalize, False) - exclusive = v_bool(exclusive, True) - - signed_diff_sum = sum_signed_rolling_deltas( - open_, close, tmo_length, exclusive=exclusive - ) - if all(isnan(signed_diff_sum)): - return None # Emergency Break - - initial_ma = ma(mamode, signed_diff_sum, length=calc_length) - if all(isnan(initial_ma)): - return None # Emergency Break - - main = ma(mamode, initial_ma, length=smooth_length) - if all(isnan(main)): - return None # Emergency Break - - smooth = ma(mamode, main, length=smooth_length) - if all(isnan(smooth)): - return None # Emergency Break - - if compute_momentum: - mom_main = main - main.shift(tmo_length) - mom_smooth = smooth - smooth.shift(tmo_length) - else: - zero_array = zeros(main.size) - mom_main = Series(zero_array, index=main.index) - mom_smooth = Series(zero_array, index=smooth.index) - - # Offset - if offset != 0: - main = main.shift(offset) - smooth = smooth.shift(offset) - mom_main = mom_main.shift(offset) - mom_smooth = mom_smooth.shift(offset) - - # Fill - if "fillna" in kwargs: - main.fillna(kwargs["fillna"], inplace=True) - smooth.fillna(kwargs["fillna"], inplace=True) - mom_main.fillna(kwargs["fillna"], inplace=True) - mom_smooth.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{tmo_length}_{calc_length}_{smooth_length}" - main.name = f"TMO{_props}" - smooth.name = f"TMOs{_props}" - mom_main.name = f"TMOM{_props}" - mom_smooth.name = f"TMOMs{_props}" - main.category = smooth.category = "momentum" - mom_main.category = mom_smooth.category = main.category - - data = { - main.name: main, - smooth.name: smooth, - mom_main.name: mom_main, - mom_smooth.name: mom_smooth, - } - df = DataFrame(data, index=close.index) - df.name = f"TMO{_props}" - df.category = main.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/trix.py b/src/aiomql/ta_libs/pandas_ta/momentum/trix.py deleted file mode 100644 index c2c827d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/trix.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap.ema import ema -from pandas_ta.utils import ( - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series -) - - - -def trix( - close: Series, length: Int = None, signal: Int = None, - scalar: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Trix - - This indicator attempts to identify divergences as an oscillator. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/TRIX) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```18``` - signal (int): Signal period. Default: ```9``` - scalar (float): Scalar. Default: ```100``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 30) - signal = v_pos_default(signal, 9) - if length < signal: - length, signal = signal, length - _length = 3 * length - 1 - close = v_series(close, _length) - - if close is None: - return - - scalar = v_scalar(scalar, 100) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - ema1 = ema(close=close, length=length, **kwargs) - if all(isnan(ema1)): - return # Emergency Break - - ema2 = ema(close=ema1, length=length, **kwargs) - if all(isnan(ema2)): - return # Emergency Break - - ema3 = ema(close=ema2, length=length, **kwargs) - if all(isnan(ema3)): - return # Emergency Break - - trix = scalar * ema3.pct_change(drift) - trix_signal = trix.rolling(signal).mean() - - # Offset - if offset != 0: - trix = trix.shift(offset) - trix_signal = trix_signal.shift(offset) - - # Fill - if "fillna" in kwargs: - trix.fillna(kwargs["fillna"], inplace=True) - trix_signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - trix.name = f"TRIX_{length}_{signal}" - trix_signal.name = f"TRIXs_{length}_{signal}" - trix.category = trix_signal.category = "momentum" - - data = {trix.name: trix, trix_signal.name: trix_signal} - df = DataFrame(data, index=close.index) - df.name = f"TRIX_{length}_{signal}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/tsi.py b/src/aiomql/ta_libs/pandas_ta/momentum/tsi.py deleted file mode 100644 index cc2de79..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/tsi.py +++ /dev/null @@ -1,106 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.overlap import ema -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series -) - - - -def tsi( - close: Series, fast: Int = None, slow: Int = None, - signal: Int = None, scalar: IntFloat = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """True Strength Index - - This indicator attempts to identify short-term swings in trend direction - as well as identifying possible "overbought" and "oversold" signals. - - Sources: - * [investopedia](https://www.investopedia.com/terms/t/tsi.asp) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): Fast MA period. Default: ```13``` - slow (int): Slow MA period. Default: ```25``` - signal (int): Signal period. Default: ```13``` - scalar (float): Scalar. Default: ```100``` - mamode (str): Signal MA. See ```help(ta.ma)```. Default: ```"ema"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - fast = v_pos_default(fast, 13) - slow = v_pos_default(slow, 25) - signal = v_pos_default(signal, 13) - if slow < fast: - fast, slow = slow, fast - _length = slow + signal + 1 - close = v_series(close, _length) - - if "length" in kwargs: - kwargs.pop("length") - - if close is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - diff = close.diff(drift) - slow_ema = ema(close=diff, length=slow, **kwargs) - if all(isnan(slow_ema)): - return # Emergency Break - fast_slow_ema = ema(close=slow_ema, length=fast, **kwargs) - - abs_diff = diff.abs() - abs_slow_ema = ema(close=abs_diff, length=slow, **kwargs) - if all(isnan(abs_slow_ema)): - return # Emergency Break - abs_fast_slow_ema = ema(close=abs_slow_ema, length=fast, **kwargs) - - tsi = scalar * fast_slow_ema / abs_fast_slow_ema - if all(isnan(tsi)): - return # Emergency Break - tsi_signal = ma(mamode, tsi, length=signal) - - # Offset - if offset != 0: - tsi = tsi.shift(offset) - tsi_signal = tsi_signal.shift(offset) - - # Fill - if "fillna" in kwargs: - tsi.fillna(kwargs["fillna"], inplace=True) - tsi_signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - tsi.name = f"TSI_{fast}_{slow}_{signal}" - tsi_signal.name = f"TSIs_{fast}_{slow}_{signal}" - tsi.category = tsi_signal.category = "momentum" - - data = {tsi.name: tsi, tsi_signal.name: tsi_signal} - df = DataFrame(data, index=close.index) - df.name = f"TSI_{fast}_{slow}_{signal}" - df.category = "momentum" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/uo.py b/src/aiomql/ta_libs/pandas_ta/momentum/uo.py deleted file mode 100644 index ed9365e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/uo.py +++ /dev/null @@ -1,105 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_drift, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def uo( - high: Series, low: Series, close: Series, - fast: Int = None, medium: Int = None, slow: Int = None, - fast_w: IntFloat = None, medium_w: IntFloat = None, slow_w: IntFloat = None, - talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Ultimate Oscillator - - This indicator, by Larry Williams, attempts to identify momentum. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Ultimate_Oscillator_(UO)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - fast (int): The Fast %K period. Default: ```7``` - medium (int): The Slow %K period. Default: ```14``` - slow (int): The Slow %D period. Default: ```28``` - fast_w (float): The Fast %K period. Default: ```4.0``` - medium_w (float): The Slow %K period. Default: ```2.0``` - slow_w (float): The Slow %D period. Default: ```1.0``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - fast = v_pos_default(fast, 7) - medium = v_pos_default(medium, 14) - slow = v_pos_default(slow, 28) - _length = max(fast, medium, slow) + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - fast_w = v_pos_default(fast_w, 4.0) - medium_w = v_pos_default(medium_w, 2.0) - slow_w = v_pos_default(slow_w, 1.0) - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import ULTOSC - uo = ULTOSC(high, low, close, fast, medium, slow) - else: - close_drift = close.shift(drift) - tdf = DataFrame({ - "high": high, "low": low, f"close_{drift}": close_drift - }) - max_h_or_pc = tdf.loc[:, ["high", f"close_{drift}"]].max(axis=1) - min_l_or_pc = tdf.loc[:, ["low", f"close_{drift}"]].min(axis=1) - del tdf - - bp = close - min_l_or_pc - tr = max_h_or_pc - min_l_or_pc - - fast_avg = bp.rolling(fast).sum() / tr.rolling(fast).sum() - medium_avg = bp.rolling(medium).sum() / tr.rolling(medium).sum() - slow_avg = bp.rolling(slow).sum() / tr.rolling(slow).sum() - - total_weight = fast_w + medium_w + slow_w - weights = (fast_w * fast_avg) + (medium_w * medium_avg) \ - + (slow_w * slow_avg) - uo = 100 * weights / total_weight - - # Offset - if offset != 0: - uo = uo.shift(offset) - - # Fill - if "fillna" in kwargs: - uo.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - uo.name = f"UO_{fast}_{medium}_{slow}" - uo.category = "momentum" - - return uo diff --git a/src/aiomql/ta_libs/pandas_ta/momentum/willr.py b/src/aiomql/ta_libs/pandas_ta/momentum/willr.py deleted file mode 100644 index a6b5ab8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/momentum/willr.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib - - - -def willr( - high: Series, low: Series, close: Series, - length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """William's Percent R - - This indicator attempts to identify "overbought" and "oversold" - conditions similar to the RSI. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Williams_%25R_(%25R)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - _length = max(length, min_periods) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import WILLR - willr = WILLR(high, low, close, length) - else: - lowest_low = low.rolling(length, min_periods=min_periods).min() - highest_high = high.rolling(length, min_periods=min_periods).max() - - willr = 100 * ((close - lowest_low) / (highest_high - lowest_low) - 1) - - # Offset - if offset != 0: - willr = willr.shift(offset) - - # Fill - if "fillna" in kwargs: - willr.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - willr.name = f"WILLR_{length}" - willr.category = "momentum" - - return willr diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/__init__.py b/src/aiomql/ta_libs/pandas_ta/overlap/__init__.py deleted file mode 100644 index d68ac52..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -from .alligator import alligator -from .alma import alma -from .dema import dema -from .ema import ema -from .fwma import fwma -from .hilo import hilo -from .hl2 import hl2 -from .hlc3 import hlc3 -from .hma import hma -from .hwma import hwma -from .ichimoku import ichimoku -from .jma import jma -from .kama import kama -from .linreg import linreg -from .mama import mama -from .mcgd import mcgd -from .midpoint import midpoint -from .midprice import midprice -from .ohlc4 import ohlc4 -from .pivots import pivots -from .pwma import pwma -from .rma import rma -from .sinwma import sinwma -from .sma import sma -from .smma import smma -from .ssf import ssf -from .ssf3 import ssf3 -from .supertrend import supertrend -from .swma import swma -from .t3 import t3 -from .tema import tema -from .trima import trima -from .vidya import vidya -from .wcp import wcp -from .wma import wma -from .zlma import zlma - - -__all__ = [ - "alligator", - "alma", - "dema", - "ema", - "fwma", - "hilo", - "hl2", - "hlc3", - "hma", - "hwma", - "ichimoku", - "jma", - "kama", - "linreg", - "mama", - "mcgd", - "midpoint", - "midprice", - "ohlc4", - "pivots", - "pwma", - "rma", - "sinwma", - "sma", - "smma", - "ssf", - "ssf3", - "supertrend", - "swma", - "t3", - "tema", - "trima", - "vidya", - "wcp", - "wma", - "zlma", -] diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/alligator.py b/src/aiomql/ta_libs/pandas_ta/overlap/alligator.py deleted file mode 100644 index d3412f2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/alligator.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .smma import smma -# from posix import pread - - - -def alligator( - close: Series, jaw: Int = None, teeth: Int = None, lips: Int = None, - talib: bool = None, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Bill Williams Alligator - - This indicator, by Bill Williams, attempts to identify trends. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=175&Name=Bill_Williams_Alligator) - * [tradingview](https://www.tradingview.com/scripts/alligator/) - - Parameters: - close (pd.Series): ```close``` Series - jaw (int): Jaw period. Default: ```13``` - teeth (int): Teeth period. Default: ```8``` - lips (int): Lips period. Default: ```5``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - - Tip: - To avoid data leaks, offsets are to be done manually. - - Note: - Williams believed the fx market trends between 15% and 30% of the - time. Otherwise it is range bound. Inspired by fractal geometry, - where the outputs are meant to resemble an alligator opening and - closing its mouth. It It consists of 3 lines: Jaw, Teeth, and - Lips which each have differing lengths. - """ - # Validate - jaw = v_pos_default(jaw, 13) - teeth = v_pos_default(teeth, 8) - lips = v_pos_default(lips, 5) - close = v_series(close, max(jaw, teeth, lips)) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - gator_jaw = smma(close, length=jaw, talib=mode_tal) - gator_teeth = smma(close, length=teeth, talib=mode_tal) - gator_lips = smma(close, length=lips, talib=mode_tal) - - # Offset - if offset != 0: - gator_jaw = gator_jaw.shift(offset) - gator_teeth = gator_teeth.shift(offset) - gator_lips = gator_lips.shift(offset) - - # Fill - if "fillna" in kwargs: - gator_jaw.fillna(kwargs["fillna"], inplace=True) - gator_teeth.fillna(kwargs["fillna"], inplace=True) - gator_lips.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{jaw}_{teeth}_{lips}" - data = { - f"AGj{_props}": gator_jaw, - f"AGt{_props}": gator_teeth, - f"AGl{_props}": gator_lips - } - df = DataFrame(data, index=close.index) - - df.name = f"AG{_props}" - df.category = "overlap" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/alma.py b/src/aiomql/ta_libs/pandas_ta/overlap/alma.py deleted file mode 100644 index c0e140a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/alma.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import append, arange, array, exp, floor, nan, tensordot -from numpy.version import version as np_version -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas import Series -from pandas_ta.utils import strided_window, v_offset, v_pos_default, v_series - - - -def alma( - close: Series, length: Int = None, - sigma: IntFloat = None, dist_offset: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Arnaud Legoux Moving Average - - This indicator attempts to reduce lag with Gaussian smoothing. - - Sources: - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/alma-arnaud-legoux-moving-average/) - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=475&Name=Moving_Average_-_Arnaud_Legoux) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```9``` - sigma (float): Smoothing value. Default ```6.0``` - dist_offset (float): Distribution offset, range ```[0, 1]```. - Default ```0.85``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 9) - close = v_series(close, length) - - if close is None: - return - - sigma = v_pos_default(sigma, 6.0) - - if isinstance(dist_offset, float) and 0 <= dist_offset <= 1: - offset_ = float(dist_offset) - else: - offset_ = 0.85 - - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - x = arange(length) - k = floor(offset_ * (length - 1)) - weights = exp(-0.5 * ((sigma / length) * (x - k)) ** 2) - weights /= weights.sum() - - if np_version >= "1.20.0": - from numpy.lib.stride_tricks import sliding_window_view - window = sliding_window_view(np_close, length) - else: - window = strided_window(np_close, length) - result = append(array([nan] * (length - 1)), - tensordot(window, weights, axes=1)) - alma = Series(result, index=close.index) - - # Offset - if offset != 0: - alma = alma.shift(offset) - - # Fill - if "fillna" in kwargs: - alma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - alma.name = f"ALMA_{length}_{sigma}_{offset_}" - alma.category = "overlap" - - return alma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/dema.py b/src/aiomql/ta_libs/pandas_ta/overlap/dema.py deleted file mode 100644 index 414eb17..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/dema.py +++ /dev/null @@ -1,75 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .ema import ema - - - -def dema( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Double Exponential Moving Average - - This indicator attempts to create a smoother average with less lag than - the EMA. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/double-exponential-moving-average-dema/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9999894518202522)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import DEMA - dema = DEMA(close, length) - else: - ema1 = ema(close=close, length=length, talib=mode_tal) - ema2 = ema(close=ema1, length=length, talib=mode_tal) - dema = 2 * ema1 - ema2 - - if all(isnan(dema.to_numpy())): - return # Emergency Break - - # Offset - if offset != 0: - dema = dema.shift(offset) - - # Fill - if "fillna" in kwargs: - dema.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - dema.name = f"DEMA_{length}" - dema.category = "overlap" - - return dema diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/ema.py b/src/aiomql/ta_libs/pandas_ta/overlap/ema.py deleted file mode 100644 index 392a4a1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/ema.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from numba import njit -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_bool, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def ema( - close: Series, length: Int = None, - talib: bool = None, presma: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Exponential Moving Average - - This Moving Average is more responsive than the Simple Moving - Average (SMA). - - Sources: - * [investopedia](https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp) - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - presma (bool): Initialize with SMA like TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - adjust (bool): Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - mode_tal = v_talib(talib) - presma = v_bool(presma, True) - offset = v_offset(offset) - adjust = kwargs.setdefault("adjust", False) - - # Calculate - if Imports["talib"] and mode_tal and length > 1: - from talib import EMA - ema = EMA(close, length) - else: - if presma: # TA Lib implementation - close = close.copy() - sma_nth = close.iloc[0:length].mean() - close.iloc[:length - 1] = nan - close.iloc[length - 1] = sma_nth - ema = close.ewm(span=length, adjust=adjust).mean() - - # Offset - if offset != 0: - ema = ema.shift(offset) - - # Fill - if "fillna" in kwargs: - ema.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ema.name = f"EMA_{length}" - ema.category = "overlap" - - return ema diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/fwma.py b/src/aiomql/ta_libs/pandas_ta/overlap/fwma.py deleted file mode 100644 index 1c08b36..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/fwma.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - fibonacci, - v_ascending, - v_offset, - v_pos_default, - v_series, - weights -) - - - -def fwma( - close: Series, length: Int = None, asc: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Fibonacci's Weighted Moving Average - - This indicator, by Kevin Johnson, is similar to a Weighted Moving Average - (WMA) where the weights are based on the Fibonacci Sequence. - - Sources: - * Kevin Johnson - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - asc (bool): Recent values weigh more. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - asc = v_ascending(asc) - offset = v_offset(offset) - - # Calculate - fibs = fibonacci(n=length, weighted=True) - fwma = close.rolling(length, min_periods=length) \ - .apply(weights(fibs), raw=True) - - # Offset - if offset != 0: - fwma = fwma.shift(offset) - - # Fill - if "fillna" in kwargs: - fwma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - fwma.name = f"FWMA_{length}" - fwma.category = "overlap" - - return fwma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/hilo.py b/src/aiomql/ta_libs/pandas_ta/overlap/hilo.py deleted file mode 100644 index 0287cd6..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/hilo.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series - - - -def hilo( - high: Series, low: Series, close: Series, - high_length: Int = None, low_length: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Gann HiLo Activator - - This indicator, by Robert Krausz, uses two different Moving Averages to - identify trends. - - Sources: - * Gann HiLo Activator, , Stocks & Commodities Magazine, 1998 - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=447&Name=Gann_HiLo_Activator) - * [tradingview](https://www.tradingview.com/script/XNQSLIYb-Gann-High-Low/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - high_length (int): High period. Default: ```13``` - low_length (int): Low period. Default: ```21``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - - Note: - Increasing ```high_length``` and decreasing ```low_length``` is - better for short trades and vice versa for long trades. - """ - # Validate - high_length = v_pos_default(high_length, 13) - low_length = v_pos_default(low_length, 21) - _length = max(high_length, low_length) + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - m = close.size - hilo = Series(nan, index=close.index) - long = Series(nan, index=close.index) - short = Series(nan, index=close.index) - - high_ma = ma(mamode, high, length=high_length) - low_ma = ma(mamode, low, length=low_length) - - for i in range(1, m): - if close.iat[i] > high_ma.iat[i - 1]: - hilo.iat[i] = long.iat[i] = low_ma.iat[i] - elif close.iat[i] < low_ma.iat[i - 1]: - hilo.iat[i] = short.iat[i] = high_ma.iat[i] - else: - hilo.iat[i] = hilo.iat[i - 1] - long.iat[i] = short.iat[i] = hilo.iat[i - 1] - - # Offset - if offset != 0: - hilo = hilo.shift(offset) - long = long.shift(offset) - short = short.shift(offset) - - # Fill - if "fillna" in kwargs: - hilo.fillna(kwargs["fillna"], inplace=True) - long.fillna(kwargs["fillna"], inplace=True) - short.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{high_length}_{low_length}" - data = { - f"HILO{_props}": hilo, - f"HILOl{_props}": long, - f"HILOs{_props}": short - } - df = DataFrame(data, index=close.index) - - df.name = f"HILO{_props}" - df.category = "overlap" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/hl2.py b/src/aiomql/ta_libs/pandas_ta/overlap/hl2.py deleted file mode 100644 index 9c3d5db..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/hl2.py +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_series - - - -def hl2( - high: Series, low: Series, - offset: Int = None, **kwargs: DictLike -) -> Series: - """HL2 - - HL2 is the midpoint/average of high and low. - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)```. - Only works when offset. - - Returns: - (pd.Series): 1 column - """ - # Validate - high = v_series(high) - low = v_series(low) - offset = v_offset(offset) - - if high is None or low is None: - return - - # Calculate - avg = 0.5 * (high.to_numpy() + low.to_numpy()) - hl2 = Series(avg, index=high.index) - - # Offset - if offset != 0: - hl2 = hl2.shift(offset) - - # Fill - if "fillna" in kwargs: - hl2.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - hl2.name = "HL2" - hl2.category = "overlap" - - return hl2 diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/hlc3.py b/src/aiomql/ta_libs/pandas_ta/overlap/hlc3.py deleted file mode 100644 index fb82dc0..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/hlc3.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_series, v_talib - - - -def hlc3( - high: Series, low: Series, close: Series, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """HLC3 - - HLC3 is the average of high, low and close. - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)```. - Only works when offset. - - Returns: - (pd.Series): 1 column - """ - # Validate - high = v_series(high) - low = v_series(low) - close = v_series(close) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - if high is None or low is None or close is None: - return - - # Calculate - if Imports["talib"] and mode_tal and close.size: - from talib import TYPPRICE - hlc3 = TYPPRICE(high, low, close) - else: - avg = (high.to_numpy() + low.to_numpy() + close.to_numpy()) / 3.0 - hlc3 = Series(avg, index=close.index) - - # Offset - if offset != 0: - hlc3 = hlc3.shift(offset) - - # Fill - if "fillna" in kwargs: - hlc3.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - hlc3.name = "HLC3" - hlc3.category = "overlap" - - return hlc3 diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/hma.py b/src/aiomql/ta_libs/pandas_ta/overlap/hma.py deleted file mode 100644 index b25a7cd..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/hma.py +++ /dev/null @@ -1,71 +0,0 @@ -from sys import modules as module_ -from numpy import sqrt -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series -from .ema import ema -from .sma import sma -from .wma import wma - - - -def hma( - close: Series, length: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Hull Moving Average - - This indicator, by Alan Hull, attempts to reduce lag compared to - classical moving averages. - - Sources: - * [Alan Hull](https://alanhull.com/hull-moving-average) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - mamode (str): One of: 'ema', 'sma', or 'wma'. Default: ```"wma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length + 2) - - if close is None: - return - - mamode = v_mamode(mamode, "wma") - offset = v_offset(offset) - - if mamode not in ["ema", "sma", "wma"]: - return - - _ma = getattr(module_[__name__], mamode) - - # Calculate - half_length = int(length / 2) - sqrt_length = int(sqrt(length)) - - maf = _ma(close, length=half_length) - mas = _ma(close, length=length) - hma = _ma(close=2 * maf - mas, length=sqrt_length) - - # Offset - if offset != 0: - hma = hma.shift(offset) - - # Fill - if "fillna" in kwargs: - hma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - hma.name = f"HMA{'' if mamode == 'wma' else mamode[0]}_{length}" - hma.category = "overlap" - - return hma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/hwma.py b/src/aiomql/ta_libs/pandas_ta/overlap/hwma.py deleted file mode 100644 index ca25edf..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/hwma.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_series -from shutil import which - - - -def hwma( - close: Series, - na: IntFloat = None, nb: IntFloat = None, nc: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Holt-Winter Moving Average - - This indicator uses a three parameter Holt-Winter Moving Average for - smoothing. - - Sources: - * [rengel8](https://github.com/rengel8) based on a publication for - MetaTrader 5. - * [mql5](https://www.mql5.com/en/code/20856) - - Parameters: - close (pd.Series): ```close``` Series - na (float): Smoothed series parameter (from 0 to 1). Default: 0.2 - nb (float): Trend parameter (from 0 to 1). Default: 0.1 - nc (float): Seasonality parameter (from 0 to 1). Default: 0.1 - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - pd.Series: hwma - """ - # Validate - close = v_series(close, 1) - na = float(na) if isinstance(na, float) and 0 < na < 1 else 0.2 - nb = float(nb) if isinstance(nb, float) and 0 < nb < 1 else 0.1 - nc = float(nc) if isinstance(nc, float) and 0 < nc < 1 else 0.1 - offset = v_offset(offset) - - if close is None: - return - - # Calculate - last_a = last_v = 0 - last_f = close.iloc[0] - - result = [] - m = close.size - for i in range(m): - F = (1.0 - na) * (last_f + last_v + 0.5 * last_a) + na * close.iloc[i] - V = (1.0 - nb) * (last_v + last_a) + nb * (F - last_f) - A = (1.0 - nc) * last_a + nc * (V - last_v) - result.append((F + V + 0.5 * A)) - last_a, last_f, last_v = A, F, V # update values - - hwma = Series(result, index=close.index) - - # Offset - if offset != 0: - hwma = hwma.shift(offset) - - # Fill - if "fillna" in kwargs: - hwma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - hwma.name = f"HWMA_{na}_{nb}_{nc}" - hwma.category = "overlap" - - return hwma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/ichimoku.py b/src/aiomql/ta_libs/pandas_ta/overlap/ichimoku.py deleted file mode 100644 index 319a9db..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/ichimoku.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, RangeIndex, Timedelta, Series, concat, date_range -from pandas_ta._typing import DictLike, Int, Tuple -from pandas_ta.utils import v_offset, v_pos_default, v_series -from .midprice import midprice - - - -def ichimoku( - high: Series, low: Series, close: Series, - tenkan: Int = None, kijun: Int = None, senkou: Int = None, - include_chikou: bool = True, - offset: Int = None, **kwargs: DictLike -) -> Tuple[DataFrame, DataFrame]: - """Ichimoku Kinkō Hyō - - A forecasting model used in Japaese financial markets Pre WWII. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/ichimoku-ich/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - tenkan (int): Tenkan period. Default: ```9``` - kijun (int): Kijun period. Default: ```26``` - senkou (int): Senkou period. Default: ```52``` - include_chikou (bool): Whether to include chikou component. - Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - lookahead (value): To avoid data leakage set to ```False```. - - Returns: - (Tuple[pd.DataFrame, pd.DataFrame]): - * Historical DataFrame, 5 columns - * Forward Looking DataFrame, 2 columns - - Danger: Possible Data Leak - Set ```lookahead=False``` to avoid data leakage. Issue [#60](https://github.com/twopirllc/pandas-ta/issues/60#). - """ - # Validate - tenkan = v_pos_default(tenkan, 9) - kijun = v_pos_default(kijun, 26) - senkou = v_pos_default(senkou, 52) - _length = max(tenkan, kijun, senkou) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return None, None - - offset = v_offset(offset) - if not kwargs.get("lookahead", True): - include_chikou = False - - # Calculate - tenkan_sen = midprice(high=high, low=low, length=tenkan) - kijun_sen = midprice(high=high, low=low, length=kijun) - span_a = 0.5 * (tenkan_sen + kijun_sen) - span_b = midprice(high=high, low=low, length=senkou) - - # Copy Span A and B values before their shift - _span_a = span_a[-kijun:].shift(-1).copy() - _span_b = span_b[-kijun:].shift(-1).copy() - - span_a = span_a.shift(kijun - 1) - span_b = span_b.shift(kijun - 1) - chikou_span = close.shift(-kijun + 1) - - # Offset - if offset != 0: - tenkan_sen = tenkan_sen.shift(offset) - kijun_sen = kijun_sen.shift(offset) - span_a = span_a.shift(offset) - span_b = span_b.shift(offset) - chikou_span = chikou_span.shift(offset) - - # Fill - if "fillna" in kwargs: - span_a.fillna(kwargs["fillna"], inplace=True) - span_b.fillna(kwargs["fillna"], inplace=True) - chikou_span.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - span_a.name = f"ISA_{tenkan}" - span_b.name = f"ISB_{kijun}" - tenkan_sen.name = f"ITS_{tenkan}" - kijun_sen.name = f"IKS_{kijun}" - chikou_span.name = f"ICS_{kijun}" - - chikou_span.category = kijun_sen.category = tenkan_sen.category = "overlap" - span_b.category = span_a.category = chikou_span - - # Prepare Ichimoku DataFrame - data = { - span_a.name: span_a, - span_b.name: span_b, - tenkan_sen.name: tenkan_sen, - kijun_sen.name: kijun_sen, - } - if include_chikou: - data[chikou_span.name] = chikou_span - - ichimokudf = DataFrame(data, index=close.index) - ichimokudf.name = f"ICHIMOKU_{tenkan}_{kijun}_{senkou}" - ichimokudf.category = "overlap" - - # Prepare Span DataFrame - last = close.index[-1] - if close.index.dtype == "int64": - ext_index = RangeIndex(start=last + 1, stop=last + kijun + 1) - spandf = DataFrame(index=ext_index, columns=[span_a.name, span_b.name]) - _span_a.index = _span_b.index = ext_index - else: - df_freq = close.index.value_counts().mode()[0] - tdelta = Timedelta(df_freq, unit="d") - new_dt = date_range(start=last + tdelta, periods=kijun, freq="B") - spandf = DataFrame(index=new_dt, columns=[span_a.name, span_b.name]) - _span_a.index = _span_b.index = new_dt - - spandf[span_a.name] = _span_a - spandf[span_b.name] = _span_b - spandf.name = f"ICHISPAN_{tenkan}_{kijun}" - spandf.category = "overlap" - - return ichimokudf, spandf diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/jma.py b/src/aiomql/ta_libs/pandas_ta/overlap/jma.py deleted file mode 100644 index 8e58dbe..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/jma.py +++ /dev/null @@ -1,118 +0,0 @@ -# -*- coding: utf-8 -*- -# from numpy import average, log, nan, power, sqrt, zeros_like -from numpy import average, log, nan, sqrt, zeros_like -from numpy import power as np_power -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_float, v_offset, v_pos_default, v_series - - - -def jma( - close: Series, length: IntFloat = None, phase: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Jurik Moving Average Average - - This indicator, by Mark Jurik, attempts to eliminate noise. It claims - to have extremely low lag, is very smooth and is responsive to gaps. - - Sources: - * [mql5](https://c.mql5.com/forextsd/forum/164/jurik_1.pdf) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/jurik-volatility-bands/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```7``` - phase (float): Phase value between [-100, 100]. Default: ```0``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - _length = v_pos_default(length, 7) - close = v_series(close, _length) - - if close is None: - return - - phase = v_float(phase, 0.0) - offset = v_offset(offset) - - # Calculate - jma = zeros_like(close) - volty = zeros_like(close) - v_sum = zeros_like(close) - - kv = det0 = det1 = ma2 = 0.0 - jma[0] = ma1 = uBand = lBand = close.iloc[0] - - # Static variables - sum_length = 10 - length = 0.5 * (_length - 1) - pr = 0.5 if phase < -100 else 2.5 if phase > 100 else 1.5 + phase * 0.01 - length1 = max((log(sqrt(length)) / log(2.0)) + 2.0, 0) - pow1 = max(length1 - 2.0, 0.5) - length2 = length1 * sqrt(length) - bet = length2 / (length2 + 1) - beta = 0.45 * (_length - 1) / (0.45 * (_length - 1) + 2.0) - - m = close.shape[0] - for i in range(1, m): - price = close.iloc[i] - - # Price volatility - del1 = price - uBand - del2 = price - lBand - volty[i] = max(abs(del1), abs(del2)) if abs(del1) != abs(del2) else 0 - - # Relative price volatility factor - v_sum[i] = v_sum[i - 1] + \ - (volty[i] - volty[max(i - sum_length, 0)]) / sum_length - avg_volty = average(v_sum[max(i - 65, 0):i + 1]) - d_volty = 0 if avg_volty == 0 else volty[i] / avg_volty - r_volty = max(1.0, min(np_power(length1, 1 / pow1), d_volty)) - # r_volty = max(1.0, min(length1 **(1 / pow1), d_volty)) - - # Jurik volatility bands - pow2 = np_power(r_volty, pow1) - kv = np_power(bet, sqrt(pow2)) - uBand = price if (del1 > 0) else price - (kv * del1) - lBand = price if (del2 < 0) else price - (kv * del2) - - # Jurik Dynamic Factor - power = np_power(r_volty, pow1) - alpha = np_power(beta, power) - - # 1st stage - preliminary smoothing by adaptive EMA - ma1 = (1 - alpha) * price + alpha * ma1 - - # 2nd stage - one more preliminary smoothing by Kalman filter - det0 = (1 - beta) * (price - ma1) + beta * det0 - ma2 = ma1 + pr * det0 - - # 3rd stage - final smoothing by unique Jurik adaptive filter - det1 = ((ma2 - jma[i - 1]) * (1 - alpha) * \ - (1 - alpha)) + (alpha * alpha * det1) - jma[i] = jma[i - 1] + det1 - - jma = Series(jma, index=close.index) - jma.iloc[0:_length - 1] = nan - - # Offset - if offset != 0: - jma = jma.shift(offset) - - # Fill - if "fillna" in kwargs: - jma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - jma.name = f"JMA_{_length}_{phase}" - jma.category = "overlap" - - return jma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/kama.py b/src/aiomql/ta_libs/pandas_ta/overlap/kama.py deleted file mode 100644 index d076c12..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/kama.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - non_zero_range, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def kama( - close: Series, length: Int = None, fast: Int = None, slow: Int = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Kaufman's Adaptive Moving Average - - This indicator, by Perry Kaufman, attempts to find the overall trend by - adapting to volatility. - - Sources: - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:kaufman_s_adaptive_moving_average) - * [tradingview](https://www.tradingview.com/script/wZGOIz9r-REPOST-Indicators-3-Different-Adaptive-Moving-Averages/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - fast (int): Fast MA period. Default: ```2``` - slow (int): Slow MA period. Default: ```30``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - fast = v_pos_default(fast, 2) - slow = v_pos_default(slow, 30) - close = v_series(close, max(fast, slow, length)) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - def weight(length: int) -> float: - return 2 / (length + 1) - - fr = weight(fast) - sr = weight(slow) - - abs_diff = non_zero_range(close, close.shift(length)).abs() - peer_diff = non_zero_range(close, close.shift(drift)).abs() - peer_diff_sum = peer_diff.rolling(length).sum() - er = abs_diff / peer_diff_sum - x = er * (fr - sr) + sr - sc = x * x - - m = close.size - ma0 = ma(mamode, close.iloc[:length], length=length, **kwargs).iloc[-1] - result = [nan for _ in range(0, length - 1)] + [ma0] - for i in range(length, m): - result.append(sc.iat[i] * close.iat[i] \ - + (1 - sc.iat[i]) * result[i - 1]) - - kama = Series(result, index=close.index) - - # Offset - if offset != 0: - kama = kama.shift(offset) - - # Fill - if "fillna" in kwargs: - kama.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - kama.name = f"KAMA_{length}_{fast}_{slow}" - kama.category = "overlap" - - return kama diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/linreg.py b/src/aiomql/ta_libs/pandas_ta/overlap/linreg.py deleted file mode 100644 index 525906e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/linreg.py +++ /dev/null @@ -1,164 +0,0 @@ -# -*- coding: utf-8 -*- -from sys import float_info as sflt -from numpy import arctan, nan, pi, zeros_like -from numpy.version import version as np_version -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - strided_window, - v_offset, - v_pos_default, - v_series, - v_talib, - zero -) - - - -def linreg( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Linear Regression Moving Average - - This indicator is a simplified version of Standard Linear Regression. It is - one variable rolling regression whereas a Standard Linear Regression is - between two or more variables. - - Sources: - * [TA Lib](https://ta-lib.org) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - angle (bool): Returns the slope angle in radians. - Default: ```False``` - degrees (bool): Return the slope angle in degrees. - Default: ```False``` - intercept (bool): Return the intercept. Default: ```False``` - r (bool): Return the 'r' correlation. Default: ```False``` - slope (bool): Return the slope. Default: ```False``` - tsf (bool): Return the Time Series Forecast value. - Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9985638477660118)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - angle = kwargs.pop("angle", False) - intercept = kwargs.pop("intercept", False) - degrees = kwargs.pop("degrees", False) - r = kwargs.pop("r", False) - slope = kwargs.pop("slope", False) - tsf = kwargs.pop("tsf", False) - - # Calculate - np_close = close.to_numpy() - - if Imports["talib"] and mode_tal and not r: - from talib import LINEARREG, LINEARREG_ANGLE, LINEARREG_INTERCEPT, LINEARREG_SLOPE, TSF - if tsf: - linreg = TSF(close, timeperiod=length) - elif slope: - linreg = LINEARREG_SLOPE(close, timeperiod=length) - elif intercept: - linreg = LINEARREG_INTERCEPT(close, timeperiod=length) - elif angle: - linreg = LINEARREG_ANGLE(close, timeperiod=length) - else: - linreg = LINEARREG(close, timeperiod=length) - else: - linreg_ = zeros_like(np_close) - # [1, 2, ..., n] from 1 to n keeps Sum(xy) low - x = range(1, length + 1) - x_sum = 0.5 * length * (length + 1) - x2_sum = x_sum * (2 * length + 1) / 3 - divisor = length * x2_sum - x_sum * x_sum - - # Needs to be reworked outside the method - def linear_regression(series): - y_sum = series.sum() - xy_sum = (x * series).sum() - - m = (length * xy_sum - x_sum * y_sum) / divisor - if slope: - return m - b = (y_sum * x2_sum - x_sum * xy_sum) / divisor - if intercept: - return b - - if angle: - theta = arctan(m) - if degrees: - theta *= 180 / pi - return theta - - if r: - y2_sum = (series * series).sum() - rn = length * xy_sum - x_sum * y_sum - rd = (divisor * (length * y2_sum - y_sum * y_sum)) ** 0.5 - if zero(rd) == 0: - rd = sflt.epsilon - return rn / rd - - return m * length + b if not tsf else m * (length - 1) + b - - if np_version >= "1.20.0": - from numpy.lib.stride_tricks import sliding_window_view - linreg_ = [ - linear_regression(_) for _ in sliding_window_view( - np_close, length) - ] - - else: - linreg_ = [ - linear_regression(_) for _ in strided_window( - np_close, length) - ] - - linreg = Series([nan] * (length - 1) + linreg_, index=close.index) - - # Offset - if offset != 0: - linreg = linreg.shift(offset) - - # Fill - if "fillna" in kwargs: - linreg.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - linreg.name = f"LINREG" - if slope: - linreg.name += "m" - if intercept: - linreg.name += "b" - if angle: - linreg.name += "a" - if r: - linreg.name += "r" - - linreg.name += f"_{length}" - linreg.category = "overlap" - - return linreg diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/mama.py b/src/aiomql/ta_libs/pandas_ta/overlap/mama.py deleted file mode 100644 index 37c690a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/mama.py +++ /dev/null @@ -1,167 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import arctan, isnan, nan, zeros_like -from numba import njit -from pandas import DataFrame, Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib - - - -# Ehler's Mother of Adaptive Moving Averages -# http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html -@njit(cache=True) -def nb_mama(x, fastlimit, slowlimit, prenan): - a, b, m = 0.0962, 0.5769, x.size - p_w, smp_w, smp_w_c = 0.2, 0.33, 0.67 - - wma4 = zeros_like(x) - dt, smp = zeros_like(x), zeros_like(x) - i1, i2 = zeros_like(x), zeros_like(x) - ji, jq = zeros_like(x), zeros_like(x) - q1, q2 = zeros_like(x), zeros_like(x) - re, im, alpha = zeros_like(x), zeros_like(x), zeros_like(x) - period, phase = zeros_like(x), zeros_like(x) - mama, fama = zeros_like(x), zeros_like(x) - - # Ehler's starts from 6, TV-LB from 3, TALib from 32 - for i in range(3, m): - adj_prev_period = 0.075 * period[i - 1] + 0.54 - - # WMA(x,4) & Detrended WMA(x,4) - wma4[i] = 0.4 * x[i] + 0.3 * x[i - 1] + 0.2 * x[i - 2] + 0.1 * x[i - 3] - dt[i] = adj_prev_period * (a * wma4[i] + b * wma4[i - 2] - b * wma4[i - 4] - a * wma4[i - 6]) - - # Quadrature(Detrender) and In Phase Component - q1[i] = adj_prev_period * (a * dt[i] + b * dt[i - 2] - b * dt[i - 4] - a * dt[i - 6]) - i1[i] = dt[i - 3] - - # Phase Q1 and I1 by 90 degrees - ji[i] = adj_prev_period * (a * i1[i] + b * i1[i - 2] - b * i1[i - 4] - a * i1[i - 6]) - jq[i] = adj_prev_period * (a * q1[i] + b * q1[i - 2] - b * q1[i - 4] - a * q1[i - 6]) - - # Phasor Addition for 3 Bar Averaging - i2[i] = i1[i] - jq[i] - q2[i] = q1[i] + ji[i] - - # Smooth I2 & Q2 - i2[i] = p_w * i2[i] + (1 - p_w) * i2[i - 1] - q2[i] = p_w * q2[i] + (1 - p_w) * q2[i - 1] - - # Homodyne Discriminator - re[i] = i2[i] * i2[i - 1] + q2[i] * q2[i - 1] - im[i] = i2[i] * q2[i - 1] + q2[i] * i2[i - 1] - - # Smooth Re & Im - re[i] = p_w * re[i] + (1 - p_w) * re[i - 1] - im[i] = p_w * im[i] + (1 - p_w) * im[i - 1] - - if im[i] != 0.0 and re[i] != 0.0: - period[i] = 360 / arctan(im[i] / re[i]) - else: - period[i] = 0 - - if period[i] > 1.5 * period[i - 1]: - period[i] = 1.5 * period[i - 1] - if period[i] < 0.67 * period[i - 1]: - period[i] = 0.67 * period[i - 1] - if period[i] < 6: - period[i] = 6 - if period[i] > 50: - period[i] = 50 - - period[i] = p_w * period[i] + (1 - p_w) * period[i - 1] - smp[i] = smp_w * period[i] + smp_w_c * smp[i - 1] - - if i1[i] != 0.0: - phase[i] = arctan(q1[i] / i1[i]) - - dphase = phase[i - 1] - phase[i] - if dphase < 1: - dphase = 1 - - alpha[i] = fastlimit / dphase - if alpha[i] > fastlimit: - alpha[i] = fastlimit - if alpha[i] < slowlimit: - alpha[i] = slowlimit - - mama[i] = alpha[i] * x[i] + (1 - alpha[i]) * mama[i - 1] - fama[i] = 0.5 * alpha[i] * mama[i] + (1 - 0.5 * alpha[i]) * fama[i - 1] - - mama[:prenan], fama[:prenan] = nan, nan - return mama, fama - - -def mama( - close: Series, fastlimit: IntFloat = None, slowlimit: IntFloat = None, - prenan: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """MESA Adaptive Moving Average - - This indicator, aka the Mother of All Moving Averages by John Ehlers, - attempts to adapt to volatility by using a Hilbert Transform Discriminator - - Sources: - * [Ehlers's Mother of Adaptive Moving Averages](http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html) - * [tradingview](https://www.tradingview.com/script/foQxLbU3-Ehlers-MESA-Adaptive-Moving-Average-LazyBear/) - - Parameters: - close (pd.Series): ```close``` Series - fastlimit (float): Fast limit. Default: ```0.5``` - slowlimit (float): Slow limit. Default: ```0.05``` - prenan (int): Prenans to apply. TV-LB ```3```, Ehler's ```6```, - TA Lib ```32```. Default: ```3``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Tip: - **FAMA** also included - """ - # Validate - close = v_series(close, 1) - - if close is None: - return - - fastlimit = v_pos_default(fastlimit, 0.5) - slowlimit = v_pos_default(slowlimit, 0.05) - prenan = v_pos_default(prenan, 3) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - if Imports["talib"] and mode_tal: - from talib import MAMA - mama, fama = MAMA(np_close, fastlimit, slowlimit) - else: - mama, fama = nb_mama(np_close, fastlimit, slowlimit, prenan) - - if all(isnan(mama)) or all(isnan(fama)): - return # Emergency Break - - # Name and Category - _props = f"_{fastlimit}_{slowlimit}" - data = {f"MAMA{_props}": mama, f"FAMA{_props}": fama} - df = DataFrame(data, index=close.index) - - df.name = f"MAMA{_props}" - df.category = "overlap" - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/mcgd.py b/src/aiomql/ta_libs/pandas_ta/overlap/mcgd.py deleted file mode 100644 index 3e02551..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/mcgd.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def _mcgd(x, n, k): - d = (k * n * (x[1] / x[0]) ** 4) - x[1] = (x[0] + ((x[1] - x[0]) / d)) - return x[1] - - -def mcgd( - close: Series, length: Int = None, c: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """McGinley Dynamic Indicator - - This indicator, by John R. McGinley, is not a moving average but a - differential smoothing technique. - - Sources: - * John R. McGinley, a Certified Market Technician (CMT) and former - editor of the Market Technicians Association's Journal of - Technical Analysis. - * [investopedia](https://www.investopedia.com/articles/forex/09/mcginley-dynamic-indicator.asp) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - c (float): Denominator multiplier. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Sometimes ```c``` is set to ```0.6```. - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - c = float(c) if isinstance(c, float) and 0 < c <= 1 else 1 - offset = v_offset(offset) - - # Calculate - close = close.copy() - - mcg_ds = close[0:].rolling(2, min_periods=2) \ - .apply(_mcgd, kwargs={"n": length, "k": c}, raw=True) - - # Offset - if offset != 0: - mcg_ds = mcg_ds.shift(offset) - - # Fill - if "fillna" in kwargs: - mcg_ds.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - mcg_ds.name = f"MCGD_{length}" - mcg_ds.category = "overlap" - - return mcg_ds diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/midpoint.py b/src/aiomql/ta_libs/pandas_ta/overlap/midpoint.py deleted file mode 100644 index 245f3d1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/midpoint.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib - - - -def midpoint( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Midpoint - - The Midpoint is the average of the rolling high and low of period length. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```2``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 2) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import MIDPOINT - midpoint = MIDPOINT(close, length) - else: - lowest = close.rolling(length, min_periods=min_periods).min() - highest = close.rolling(length, min_periods=min_periods).max() - midpoint = 0.5 * (lowest + highest) - - # Offset - if offset != 0: - midpoint = midpoint.shift(offset) - - # Fill - if "fillna" in kwargs: - midpoint.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - midpoint.name = f"MIDPOINT_{length}" - midpoint.category = "overlap" - - return midpoint diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/midprice.py b/src/aiomql/ta_libs/pandas_ta/overlap/midprice.py deleted file mode 100644 index 0696aa4..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/midprice.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib - - - -def midprice( - high: Series, low: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Midprice - - The Midprice is the average of the rolling high and low of period length. - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - length (int): The period. Default: ```2``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 2) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - _length = max(length, min_periods) - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import MIDPRICE - midprice = MIDPRICE(high, low, length) - else: - lowest_low = low.rolling(length, min_periods=min_periods).min() - highest_high = high.rolling(length, min_periods=min_periods).max() - midprice = 0.5 * (lowest_low + highest_high) - - # Offset - if offset != 0: - midprice = midprice.shift(offset) - - # Fill - if "fillna" in kwargs: - midprice.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - midprice.name = f"MIDPRICE_{length}" - midprice.category = "overlap" - - return midprice diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/ohlc4.py b/src/aiomql/ta_libs/pandas_ta/overlap/ohlc4.py deleted file mode 100644 index 9f77535..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/ohlc4.py +++ /dev/null @@ -1,53 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_series - - - -def ohlc4( - open_: Series, high: Series, low: Series, close: Series, - offset: Int = None, **kwargs: DictLike -) -> Series: - """OHLC4 - - OHLC4 is the average of open, high, low and close. - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)```. - Only works when offset. - - Returns: - (pd.Series): 1 column - """ - # Validate - open_ = v_series(open_) - high = v_series(high) - low = v_series(low) - close = v_series(close) - offset = v_offset(offset) - - # Calculate - avg = 0.25 * (open_.to_numpy() + high.to_numpy() + low.to_numpy() + close.to_numpy()) - ohlc4 = Series(avg, index=close.index) - - # Offset - if offset != 0: - ohlc4 = ohlc4.shift(offset) - - # Fill - if "fillna" in kwargs: - ohlc4.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ohlc4.name = "OHLC4" - ohlc4.category = "overlap" - - return ohlc4 diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/pivots.py b/src/aiomql/ta_libs/pandas_ta/overlap/pivots.py deleted file mode 100644 index 9ee33c5..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/pivots.py +++ /dev/null @@ -1,264 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import greater, nan, zeros_like -from numba import njit -from pandas import DataFrame, DateOffset, Series, infer_freq -from pandas_ta._typing import DictLike -from pandas_ta.utils import ( - nb_nonzero_range, - v_datetime_ordered, - v_series, - v_str -) - -# Support for Pandas v1.4.x and v2.2.x -td_mapping = { - 'Y': 'years', - 'YE': 'years', - 'M': 'months', - 'ME': 'months', - 'D': 'days', -} - - - -@njit(cache=True) -def pivot_camarilla(high, low, close): - tp = (high + low + close) / 3 - hl_range = nb_nonzero_range(high, low) - - s1 = close - 11 / 120 * hl_range - s2 = close - 11 / 60 * hl_range - s3 = close - 0.275 * hl_range - s4 = close - 0.55 * hl_range - - r1 = close + 11 / 120 * hl_range - r2 = close + 11 / 60 * hl_range - r3 = close + 0.275 * hl_range - r4 = close + 0.55 * hl_range - - return tp, s1, s2, s3, s4, r1, r2, r3, r4 - - -@njit(cache=True) -def pivot_classic(high, low, close): - tp = (high + low + close) / 3 - hl_range = nb_nonzero_range(high, low) - - s1 = 2 * tp - high - s2 = tp - hl_range - s3 = tp - 2 * hl_range - s4 = tp - 3 * hl_range - - r1 = 2 * tp - low - r2 = tp + hl_range - r3 = tp + 2 * hl_range - r4 = tp + 3 * hl_range - - return tp, s1, s2, s3, s4, r1, r2, r3, r4 - - -@njit(cache=True) -def pivot_demark(open_, high, low, close): - if (open_ == close).all(): - tp = 0.25 * (high + low + 2 * close) - elif greater(close, open_).all(): - tp = 0.25 * (2 * high + low + close) - else: - tp = 0.25 * (high + 2 * low + close) - - s1 = 2 * tp - high - r1 = 2 * tp - low - - return tp, s1, r1 - - -@njit(cache=True) -def pivot_fibonacci(high, low, close): - tp = (high + low + close) / 3 - hl_range = nb_nonzero_range(high, low) - - s1 = tp - 0.382 * hl_range - s2 = tp - 0.618 * hl_range - s3 = tp - hl_range - - r1 = tp + 0.382 * hl_range - r2 = tp + 0.618 * hl_range - r3 = tp + hl_range - - return tp, s1, s2, s3, r1, r2, r3 - - -@njit(cache=True) -def pivot_traditional(high, low, close): - tp = (high + low + close) / 3 - hl_range = nb_nonzero_range(high, low) - - s1 = 2 * tp - high - s2 = tp - hl_range - s3 = tp - 2 * hl_range - s4 = tp - 2 * hl_range - - r1 = 2 * tp - low - r2 = tp + hl_range - r3 = tp + 2 * hl_range - r4 = tp + 2 * hl_range - - return tp, s1, s2, s3, s4, r1, r2, r3, r4 - - -@njit(cache=True) -def pivot_woodie(open_, high, low): - tp = (2 * open_ + high + low) / 4 - hl_range = nb_nonzero_range(high, low) - - s1 = 2 * tp - high - s2 = tp - hl_range - s3 = low - 2 * (high - tp) - s4 = s3 - hl_range - - r1 = 2 * tp - low - r2 = tp + hl_range - r3 = high + 2 * (tp - low) - r4 = r3 + hl_range - - return tp, s1, s2, s3, s4, r1, r2, r3, r4 - - -def pivots( - open_: Series, high: Series, - low: Series, close: Series, - method: str = None, anchor: str = None, - **kwargs: DictLike -) -> DataFrame: - """Pivot Points - - Pivot Points attempt to identify support and resistance levels. - There are many different methods of calculating Pivot Points. The most - common (and default) method is: Traditional. Other methods include: - Camarilla, Classic, Demark, Fibonacci, and Woodie. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/PivotPoints.html) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - method (str): Pivot methode. Default: ```'traditional'``` - anchor (str): Anchor frequency. Default: ```'D'``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3, 7 or 9 columns - - Note: - [Pandas Offset Aliases](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases) - """ - # Validate - open_ = v_series(open_) - high = v_series(high) - low = v_series(low) - close = v_series(close) - - if open_ is None or high is None or low is None or close is None: - return None - - methods = [ - "traditional", "fibonacci", "woodie", "classic", "demark", "camarilla" - ] - method = v_str(method, methods[0]) - - if close.index.size < 3: - return # Emergency Break - - if not v_datetime_ordered(close): - print("[!] Pivots requires an ordered DatetimeIndex.") - return - - dt_index = close.index - freq = infer_freq(dt_index) - - if anchor and isinstance(anchor, str) and len(anchor) >= 1: - anchor = anchor.upper() - else: - anchor = "D" - - # Resample if freq does not match the anchor - if freq is not anchor: - df = DataFrame( - data={ - "open": open_.resample(anchor).first(), - "high": high.resample(anchor).max(), - "low": low.resample(anchor).min(), - "close": close.resample(anchor).last() - } - ) - df.dropna(inplace=True) - else: - df = DataFrame( - data={"open": open_, "high": high, "low": low, "close": close}, - index=dt_index - ) - - np_open = df.open.to_numpy() - np_high = df.high.to_numpy() - np_low = df.low.to_numpy() - np_close = df.close.to_numpy() - - # Create nan arrays for "demark" and "fibonacci" pivots - _nan_array = zeros_like(np_close) - _nan_array[:] = nan - tp = s1 = s2 = s3 = s4 = r1 = r2 = r3 = r4 = _nan_array - - # Calculate - if method == "camarilla": - tp, s1, s2, s3, s4, r1, r2, r3, r4 = \ - pivot_camarilla(np_high, np_low, np_close) - - elif method == "classic": - tp, s1, s2, s3, s4, r1, r2, r3, r4 = \ - pivot_classic(np_high, np_low, np_close) - - elif method == "demark": - tp, s1, r1 = pivot_demark(np_open, np_high, np_low, np_close) - - elif method == "fibonacci": - tp, s1, s2, s3, r1, r2, r3 = pivot_fibonacci(np_high, np_low, np_close) - - elif method == "woodie": - tp, s1, s2, s3, s4, r1, r2, r3, r4 = \ - pivot_woodie(np_open, np_high, np_low) - - else: # Traditional - tp, s1, s2, s3, s4, r1, r2, r3, r4 = \ - pivot_traditional(np_high, np_low, np_close) - - # Name and Category - _props = f"PIVOTS_{method[:4].upper()}_{anchor}" - df[f"{_props}_P"] = tp - df[f"{_props}_S1"], df[f"{_props}_S2"] = s1, s2 - df[f"{_props}_S3"], df[f"{_props}_S4"] = s3, s4 - df[f"{_props}_R1"], df[f"{_props}_R2"] = r1, r2 - df[f"{_props}_R3"], df[f"{_props}_R4"] = r3, r4 - - time_unit = td_mapping.get(anchor.upper(), None) - if time_unit: - time_delta = DateOffset(**{time_unit: 1}) - df.index = df.index + time_delta - else: - print(f"[!] Unsupported time anchor {anchor}.") - - if freq is not anchor: - df = df.reindex(dt_index, method="ffill") - df = df.iloc[:,4:] - - if method in ["demark", "fibonacci"]: - df.drop(columns=[x for x in df.columns if all(df[x].isna())], inplace=True) - - df.name = _props - df.category = "overlap" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/pwma.py b/src/aiomql/ta_libs/pandas_ta/overlap/pwma.py deleted file mode 100644 index dd1a004..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/pwma.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -# from numpy.version import version as np_version -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - pascals_triangle, - v_offset, - v_ascending, - v_pos_default, - v_series, - weights -) - - - -def pwma( - close: Series, length: Int = None, asc: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Pascal's Weighted Moving Average - - This indicator, by Kevin Johnson, creates a weighted moving average using - Pascal's Triangle. - - Sources: - * Kevin Johnson - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - asc (bool): Ascending. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - asc = v_ascending(asc) - offset = v_offset(offset) - - # Calculate - triangle = pascals_triangle(n=length - 1, weighted=True) - pwma = close.rolling(length, min_periods=length) \ - .apply(weights(triangle), raw=True) - - # Offset - if offset != 0: - pwma = pwma.shift(offset) - - # Fill - if "fillna" in kwargs: - pwma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pwma.name = f"PWMA_{length}" - pwma.category = "overlap" - - return pwma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/rma.py b/src/aiomql/ta_libs/pandas_ta/overlap/rma.py deleted file mode 100644 index de65d5d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/rma.py +++ /dev/null @@ -1,56 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def rma( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """wildeR's Moving Average - - This indicator, by Wilder, is simply an EMA where _alpha_ is - the recipical of its _length_. - - Sources: - * [incrediblecharts](https://www.incrediblecharts.com/indicators/wilder_moving_average.php) - * [thinkorswim](https://tlc.thinkorswim.com/center/reference/Tech-Indicators/studies-library/V-Z/WildersSmoothing) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - alpha = (1.0 / length) if length > 0 else 0.5 - offset = v_offset(offset) - - rma = close.ewm(alpha=alpha, adjust=False).mean() - - # Offset - if offset != 0: - rma = rma.shift(offset) - - # Fill - if "fillna" in kwargs: - rma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rma.name = f"RMA_{length}" - rma.category = "overlap" - - return rma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/sinwma.py b/src/aiomql/ta_libs/pandas_ta/overlap/sinwma.py deleted file mode 100644 index 8ae0226..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/sinwma.py +++ /dev/null @@ -1,63 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import pi, sin -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series, weights - - - -def sinwma( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Sine Weighted Moving Average - - This indicator is a weighted average using sine cycles where the central - values have greater weight. - - Source: - * [Everget](https://www.tradingview.com/u/everget/) - * [tradingview](https://www.tradingview.com/script/6MWFvnPO-Sine-Weighted-Moving-Average/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - sines = Series( - [sin((i + 1) * pi / (length + 1)) for i in range(0, length)] - ) - w = sines / sines.sum() - - sinwma = close.rolling(length, min_periods=length) \ - .apply(weights(w), raw=True) - - # Offset - if offset != 0: - sinwma = sinwma.shift(offset) - - # Fill - if "fillna" in kwargs: - sinwma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - sinwma.name = f"SINWMA_{length}" - sinwma.category = "overlap" - - return sinwma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/sma.py b/src/aiomql/ta_libs/pandas_ta/overlap/sma.py deleted file mode 100644 index 84a2d83..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/sma.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import convolve, ones -from numba import njit -from pandas import Series -from .._typing import Array, DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - nb_prepend, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -# Fast SMA Options: https://github.com/numba/numba/issues/4119 -@njit(cache=True) -def nb_sma(x, n): - result = convolve(ones(n) / n, x)[n - 1:1 - n] - return nb_prepend(result, n - 1) - - -def sma( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Simple Moving Average - - This indicator is the the textbook moving average, a rolling sum of - values divided by the window period (or length). - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/simple-moving-average-sma/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - adjust (bool): Adjust the values. Default: ```True``` - presma (bool): If True, uses SMA for initial value. - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal and length > 1: - from talib import SMA - sma = SMA(close, length) - else: - np_close = close.to_numpy() - sma = nb_sma(np_close, length) - sma = Series(sma, index=close.index) - - # Offset - if offset != 0: - sma = sma.shift(offset) - - # Fill - if "fillna" in kwargs: - sma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - sma.name = f"SMA_{length}" - sma.category = "overlap" - - return sma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/smma.py b/src/aiomql/ta_libs/pandas_ta/overlap/smma.py deleted file mode 100644 index 67c4860..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/smma.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def smma( - close: Series, length: Int = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """SMoothed Moving Average - - This indicator attempts to confirm trends and identify support and - resistance areas. It tries to reduce noise in contrast to reducing lag. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=173&Name=Moving_Average_-_Smoothed) - * [tradingview](https://www.tradingview.com/scripts/smma/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - A core component of Bill Williams Alligator indicator. - """ - # Validate - length = v_pos_default(length, 7) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - m = close.size - smma = close.copy() - smma[:length - 1] = nan - smma.iloc[length - 1] = ma(mamode, close[0:length], length=length, talib=mode_tal).iloc[-1] - - for i in range(length, m): - smma.iat[i] = ((length - 1) * smma.iat[i - 1] + smma.iat[i]) / length - - # Offset - if offset != 0: - smma = smma.shift(offset) - - # Fill - if "fillna" in kwargs: - smma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - smma.name = f"SMMA_{length}" - smma.category = "overlap" - - return smma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/ssf.py b/src/aiomql/ta_libs/pandas_ta/overlap/ssf.py deleted file mode 100644 index 11abcea..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/ssf.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import copy, cos, exp, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.utils import v_bool, v_offset, v_pos_default, v_series - - - -# Ehlers's Super Smoother Filter -# http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html -@njit(cache=True) -def nb_ssf(x, n, pi, sqrt2): - m, ratio, result = x.size, sqrt2 / n, copy(x) - a = exp(-pi * ratio) - b = 2 * a * cos(180 * ratio) - c = a * a - b + 1 - - # result[:2] = x[:2] - for i in range(2, m): - result[i] = 0.5 * c * (x[i] + x[i - 1]) + b * result[i - 1] \ - - a * a * result[i - 2] - - return result - - -# John F. Ehlers's Super Smoother Filter by Everget (2 poles), Tradingview -# https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/ -@njit(cache=True) -def nb_ssf_everget(x, n, pi, sqrt2): - m, arg, result = x.size, pi * sqrt2 / n, copy(x) - a = exp(-arg) - b = 2 * a * cos(arg) - - # result[:2] = x[:2] - for i in range(2, m): - result[i] = 0.5 * (a * a - b + 1) * (x[i] + x[i - 1]) \ - + b * result[i - 1] - a * a * result[i - 2] - - return result - - -def ssf( - close: Series, length: Int = None, - everget: bool = None, pi: IntFloat = None, sqrt2: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Ehlers's Super Smoother Filter - - This indicator, by John F. Ehlers's © 2013, is a (Recursive) Digital - Filter that attempts to reduce lag and remove aliases. This version - has two poles. - - Sources: - * [mql5](https://www.mql5.com/en/code/588) - * [traders.com](http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html) - * [tradingview](https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - everget (bool): Everget's implementation of ssf that uses pi - instead of 180 for the b factor of ssf. Default: ```False``` - pi (float): The default is Ehlers's truncated value: ```3.14159```. - Default: ```3.14159``` - sqrt2 (float): The default is Ehlers's truncated value: ```1.414```. - Default: ```1.414``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Everget's calculation on TradingView: - ```pi=np.pi```, ```sqrt2=np.sqrt(2)``` - - Danger: - Possible Data Leak - """ - # Validate - length = v_pos_default(length, 20) - close = v_series(close, length) - - if close is None: - return - - pi = v_pos_default(pi, 3.14159) - sqrt2 = v_pos_default(sqrt2, 1.414) - everget = v_bool(everget, False) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - if everget: - ssf = nb_ssf_everget(np_close, length, pi, sqrt2) - else: - ssf = nb_ssf(np_close, length, pi, sqrt2) - ssf = Series(ssf, index=close.index) - - # Offset - if offset != 0: - ssf = ssf.shift(offset) - - # Fill - if "fillna" in kwargs: - ssf.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ssf.name = f"SSF{'e' if everget else ''}_{length}" - ssf.category = "overlap" - - return ssf diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/ssf3.py b/src/aiomql/ta_libs/pandas_ta/overlap/ssf3.py deleted file mode 100644 index b250220..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/ssf3.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import copy, cos, exp, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -# John F. Ehler's Super Smoother Filter by Everget (3 poles), Tradingview -# https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/ -@njit(cache=True) -def nb_ssf3(x, n, pi, sqrt3): - m, result = x.size, copy(x) - a = exp(-pi / n) - b = 2 * a * cos(-pi * sqrt3 / n) - c = a * a - - d4 = c * c - d3 = -c * (1 + b) - d2 = b + c - d1 = 1 - d2 - d3 - d4 - - # result[:3] = x[:3] - for i in range(3, m): - result[i] = d1 * x[i] + d2 * result[i - 1] \ - + d3 * result[i - 2] + d4 * result[i - 3] - - return result - - -def ssf3( - close: Series, length: Int = None, - pi: IntFloat = None, sqrt3: IntFloat = None, - offset: Int = None, **kwargs: DictLike -): - """Ehlers's 3 Pole Super Smoother Filter - - This indicator, by John F. Ehlers's © 2013, is a (Recursive) Digital - Filter that attempts to reduce lag and remove aliases. This version - has two poles. - - Sources: - * [mql5](https://www.mql5.com/en/code/589) - * [tradingview](https://www.tradingview.com/script/VdJy0yBJ-Ehlers-Super-Smoother-Filter/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - pi (float): The value of ```PI```. The default is Ehler's truncated - value: ```3.14159```. Default: ```3.14159``` - sqrt3 (float): The value of ```sqrt(3)``` to use. The default is - Ehler's truncated value: ```1.732```. Default: ```1.732``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Everget's calculation on TradingView: - ```pi=np.pi```, ```sqrt2=np.sqrt(2)``` - """ - # Validate - length = v_pos_default(length, 20) - close = v_series(close, length) - - if close is None: - return - - pi = v_pos_default(pi, 3.14159) - sqrt3 = v_pos_default(sqrt3, 1.732) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - ssf = nb_ssf3(np_close, length, pi, sqrt3) - ssf = Series(ssf, index=close.index) - - # Offset - if offset != 0: - ssf = ssf.shift(offset) - - # Fill - if "fillna" in kwargs: - ssf.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ssf.name = f"SSF3_{length}" - ssf.category = "overlap" - - return ssf diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/supertrend.py b/src/aiomql/ta_libs/pandas_ta/overlap/supertrend.py deleted file mode 100644 index adf3ab1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/supertrend.py +++ /dev/null @@ -1,108 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import hl2 -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series -from pandas_ta.volatility import atr - - - -def supertrend( - high: Series, low: Series, close: Series, - length: Int = None, atr_length: Int = None, - multiplier: IntFloat = None, - atr_mamode : str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Supertrend - - This indicator attempts to identify trend direction as well as support and - resistance levels. - - Sources: - * [freebsensetips](http://www.freebsensetips.com/blog/detail/7/What-is-supertrend-indicator-its-calculation) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```7``` - atr_length (int): ATR period. Default: ```length``` - multiplier (float): Coefficient for upper and lower band distance to - midrange. Default: ```3.0``` - atr_mamode (str) : MA type to be used for ATR calculation. - See ```help(ta.ma)```. Default: ```"rma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - """ - # Validate - length = v_pos_default(length, 7) - atr_length = v_pos_default(atr_length, length) - high = v_series(high, length + 1) - low = v_series(low, length + 1) - close = v_series(close, length + 1) - - if high is None or low is None or close is None: - return - - multiplier = v_pos_default(multiplier, 3.0) - atr_mamode = v_mamode(atr_mamode, "rma") - offset = v_offset(offset) - - # Calculate - m = close.size - dir_, trend = [1] * m, [0] * m - long, short = [nan] * m, [nan] * m - - hl2_ = hl2(high, low) - matr = multiplier * atr(high, low, close, atr_length, mamode=atr_mamode) - lb = hl2_ - matr - ub = hl2_ + matr - - for i in range(1, m): - if close.iat[i] > ub.iat[i - 1]: - dir_[i] = 1 - elif close.iat[i] < lb.iat[i - 1]: - dir_[i] = -1 - else: - dir_[i] = dir_[i - 1] - if dir_[i] > 0 and lb.iat[i] < lb.iat[i - 1]: - lb.iat[i] = lb.iat[i - 1] - if dir_[i] < 0 and ub.iat[i] > ub.iat[i - 1]: - ub.iat[i] = ub.iat[i - 1] - - if dir_[i] > 0: - trend[i] = long[i] = lb.iat[i] - else: - trend[i] = short[i] = ub.iat[i] - - trend[0] = nan - dir_[:length] = [nan] * length - - _props = f"_{length}_{multiplier}" - data = { - f"SUPERT{_props}": trend, - f"SUPERTd{_props}": dir_, - f"SUPERTl{_props}": long, - f"SUPERTs{_props}": short - } - df = DataFrame(data, index=close.index) - - df.name = f"SUPERT{_props}" - df.category = "overlap" - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/swma.py b/src/aiomql/ta_libs/pandas_ta/overlap/swma.py deleted file mode 100644 index 9e27df2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/swma.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - symmetric_triangle, - v_offset, - v_pos_default, - v_series, - weights -) - - - -def swma( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Symmetric Weighted Moving Average - - This indicator is based on a Symmetric Weighted Moving Average where - weights are based on a symmetric triangle. - - Source: - * [tradingview](https://www.tradingview.com/study-script-reference/#fun_swma) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * ```n=3``` -> ```[1, 2, 1]``` - * ```n=4``` -> ```[1, 2, 2, 1]``` - * etc... - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - triangle = symmetric_triangle(length, weighted=True) - swma = close.rolling(length, min_periods=length) \ - .apply(weights(triangle), raw=True) - - # Offset - if offset != 0: - swma = swma.shift(offset) - - # Fill - if "fillna" in kwargs: - swma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - swma.name = f"SWMA_{length}" - swma.category = "overlap" - - return swma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/t3.py b/src/aiomql/ta_libs/pandas_ta/overlap/t3.py deleted file mode 100644 index c90b2ce..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/t3.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .ema import ema - - - -def t3( - close: Series, length: Int = None, a: IntFloat = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """T3 - - This indicator, by Tim Tillson, attempts to be smoother and more - responsive relative to other moving averages. - - Sources: - * [binarytribune](http://www.binarytribune.com/forex-trading-indicators/t3-moving-average-indicator/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - a (float): The a factor, 0 < a < 1. Default: ```0.7``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - adjust (bool): Default: True - presma (bool): If True, uses SMA for initial value. - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9999994265973177)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, 5 * (length + 1)) - - if close is None: - return - - a = float(a) if isinstance(a, float) and 0 < a < 1 else 0.7 - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import T3 - t3 = T3(close, length, a) - else: - c1 = -a * a**2 - c2 = 3 * a**2 + 3 * a**3 - c3 = -6 * a**2 - 3 * a - 3 * a**3 - c4 = a**3 + 3 * a**2 + 3 * a + 1 - - e1 = ema(close=close, length=length, talib=mode_tal, **kwargs) - e2 = ema(close=e1, length=length, talib=mode_tal, **kwargs) - e3 = ema(close=e2, length=length, talib=mode_tal, **kwargs) - e4 = ema(close=e3, length=length, talib=mode_tal, **kwargs) - e5 = ema(close=e4, length=length, talib=mode_tal, **kwargs) - e6 = ema(close=e5, length=length, talib=mode_tal, **kwargs) - t3 = c1 * e6 + c2 * e5 + c3 * e4 + c4 * e3 - - # Offset - if offset != 0: - t3 = t3.shift(offset) - - # Fill - if "fillna" in kwargs: - t3.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - t3.name = f"T3_{length}_{a}" - t3.category = "overlap" - - return t3 diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/tema.py b/src/aiomql/ta_libs/pandas_ta/overlap/tema.py deleted file mode 100644 index a2faee8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/tema.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .ema import ema - - - -def tema( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Triple Exponential Moving Average - - This indicator attempts to be less laggy than the EMA. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triple-exponential-moving-average-tema/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - adjust (bool): Default: ```True``` - presma (bool): If True, uses SMA for initial value. - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9999355450605516)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, 3 * length) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import TEMA - tema = TEMA(close, length) - else: - ema1 = ema(close=close, length=length, talib=mode_tal, **kwargs) - ema2 = ema(close=ema1, length=length, talib=mode_tal, **kwargs) - ema3 = ema(close=ema2, length=length, talib=mode_tal, **kwargs) - tema = 3 * (ema1 - ema2) + ema3 - - # Offset - if offset != 0: - tema = tema.shift(offset) - - # Fill - if "fillna" in kwargs: - tema.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - tema.name = f"TEMA_{length}" - tema.category = "overlap" - - return tema diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/trima.py b/src/aiomql/ta_libs/pandas_ta/overlap/trima.py deleted file mode 100644 index 21fc48f..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/trima.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .sma import sma - - - -def trima( - close: Series, length: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Triangular Moving Average - - This indicator is a weighted moving average where the shape of the - weights are triangular with the greatest weight is in the middle - of the period. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/triangular-moving-average-trima/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - adjust (bool): Default: True - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - tma = sma(sma(src, ceil(length / 2)), floor(length / 2) + 1) # Tradingview - trima = sma(sma(x, n), n) # Tradingview - - Warning: - TA-Lib Correlation: ```np.float64(0.9991752493891967)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import TRIMA - trima = TRIMA(close, length) - else: - half_length = round(0.5 * (length + 1)) - sma1 = sma(close, length=half_length, talib=mode_tal) - trima = sma(sma1, length=half_length, talib=mode_tal) - - # Offset - if offset != 0: - trima = trima.shift(offset) - - # Fill - if "fillna" in kwargs: - trima.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - trima.name = f"TRIMA_{length}" - trima.category = "overlap" - - return trima diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/vidya.py b/src/aiomql/ta_libs/pandas_ta/overlap/vidya.py deleted file mode 100644 index 095c01a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/vidya.py +++ /dev/null @@ -1,113 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_drift, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def vidya( - close: Series, length: Int = None, - talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Variable Index Dynamic Average - - This indicator, by Tushar Chande, is similar to an EMA but it has a - dynamically adjusted lookback period dependent based on CMO. - - Sources: - * [perfecttrendsystem](https://www.perfecttrendsystem.com/blog_mt4_2/en/vidya-indicator-for-mt4) - * [tradingview](https://www.tradingview.com/script/hdrf0fXV-Variable-Index-Dynamic-Average-VIDYA/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Sometimes used as a moving average or a trend identifier. - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length + 1) - - if close is None: - return - - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - m = close.size - alpha = 2 / (length + 1) - - if Imports["talib"] and mode_tal: - from talib import CMO - cmo_ = 0.01 * CMO(close, length) - else: - cmo_ = _cmo(close, length, drift) - abs_cmo = cmo_.abs().astype(float) - - vidya = Series(0.0, index=close.index) - for i in range(length, m): - vidya.iloc[i] = alpha * abs_cmo.iloc[i] * close.iloc[i] + \ - vidya.iloc[i - 1] * (1 - alpha * abs_cmo.iloc[i]) - vidya.replace({0: nan}, inplace=True) - - # Offset - if offset != 0: - vidya = vidya.shift(offset) - - # Fill - if "fillna" in kwargs: - vidya.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - vidya.name = f"VIDYA_{length}" - vidya.category = "overlap" - - return vidya - - -def _cmo(x: Series, length: Int, drift: Int): - """Chande Momentum Oscillator Patch - - Unguarded CMO Patch - - Parameters: - x (pd.Series): ```x``` Series - length (int): The period. - drift (int): Difference amount. - - Returns: - (pd.Series): 1 column - - Info: Weird Circular TypeError!? - For some reason: from pandas_ta.momentum import cmo causes - pandas_ta.momentum.coppock to not be able to import it's _wma_ like - from pandas_ta.overlap import wma? - """ - mom = x.diff(drift) - positive = mom.copy().clip(lower=0) - negative = mom.copy().clip(upper=0).abs() - pos_sum = positive.rolling(length).sum() - neg_sum = negative.rolling(length).sum() - - return (pos_sum - neg_sum) / (pos_sum + neg_sum) diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/wcp.py b/src/aiomql/ta_libs/pandas_ta/overlap/wcp.py deleted file mode 100644 index fe96bcc..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/wcp.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_series, v_talib - - - -def wcp( - high: Series, low: Series, close: Series, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Weighted Closing Price - - This indicator is a weighted value of: high, low and twice the close. - - Sources: - * [fmlabs](https://www.fmlabs.com/reference/default.htm?url=WeightedCloses.htm) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - _length = 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import WCLPRICE - wcp = WCLPRICE(high, low, close) - else: - weight = high.to_numpy() + low.to_numpy() + 2 * close.to_numpy() - wcp = Series(weight, index=close.index) - - # Offset - if offset != 0: - wcp = wcp.shift(offset) - - # Fill - if "fillna" in kwargs: - wcp.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - wcp.name = "WCP" - wcp.category = "overlap" - - return wcp diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/wma.py b/src/aiomql/ta_libs/pandas_ta/overlap/wma.py deleted file mode 100644 index 4a8b539..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/wma.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import arange, dot, float64, nan, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_ascending, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -@njit(cache=True) -def nb_wma(x, n, asc, prenan): - m = x.size - w = arange(1, n + 1, dtype=float64) - result = zeros_like(x, dtype=float64) - - if not asc: - w = w[::-1] - - for i in range(n - 1, m): - result[i] = (w * x[i - n + 1:i + 1]).sum() - result *= 2 / (n * n + n) - - if prenan: - result[:n - 1] = nan - - return result - - -def wma( - close: Series, length: Int = None, - asc: bool = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Weighted Moving Average - - This indicator is a Moving Average where the weights are linearly - increasing and the most recent data has the heaviest weight. - - Sources: - * [wikipedia](https://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - asc (bool): Recent values weigh more. Default: ```True``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - asc = v_ascending(asc) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import WMA - wma = WMA(close, length) - else: - np_close = close.to_numpy() - wma_ = nb_wma(np_close, length, asc, True) - wma = Series(wma_, index=close.index) - - # Offset - if offset != 0: - wma = wma.shift(offset) - - # Fill - if "fillna" in kwargs: - wma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - wma.name = f"WMA_{length}" - wma.category = "overlap" - - return wma diff --git a/src/aiomql/ta_libs/pandas_ta/overlap/zlma.py b/src/aiomql/ta_libs/pandas_ta/overlap/zlma.py deleted file mode 100644 index f0e3efc..0000000 --- a/src/aiomql/ta_libs/pandas_ta/overlap/zlma.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -from sys import modules as sys_modules -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series - -# Available MAs for zlma -from .dema import dema -from .ema import ema -from .fwma import fwma -from .hma import hma -from .linreg import linreg -from .midpoint import midpoint -from .pwma import pwma -from .rma import rma -from .sinwma import sinwma -from .sma import sma -from .ssf import ssf -from .swma import swma -from .t3 import t3 -from .tema import tema -from .trima import trima -from .vidya import vidya -from .wma import wma - - - -def zlma( - close: Series, length: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Zero Lag Moving Average - - This indicator, by John Ehlers and Ric Way, attempts to eliminate the lag - often introduced in other moving averages. - - Sources: - * [wikipedia](https://en.wikipedia.org/wiki/Zero_lag_exponential_moving_average) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - mamode (str): One of: "dema", "ema", "fwma", "hma", "linreg", - "midpoint", "pwma", "rma", "sinwma", "ssf", "swma", "t3", - "tema", "trima", "vidya", or "wma". Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - - if close is None: - return - - mamode = v_mamode(mamode, "ema") - supported_mas = [ - "dema", "ema", "fwma", "hma", "linreg", "midpoint", "pwma", "rma", - "sinwma", "sma", "ssf", "swma", "t3", "tema", "trima", "vidya", "wma" - ] - - if mamode not in supported_mas: - return - - offset = v_offset(offset) - - # Calculate - lag = int(0.5 * (length - 1)) - close_ = 2 * close - close.shift(lag) - - kwargs.update({"close": close_}) - kwargs.update({"length": length}) - - fn = getattr(sys_modules[__name__], mamode) - zlma = fn(**kwargs) - - if zlma is None or all(isnan(zlma)): - return # Emergency Break - - # Offset - if offset != 0: - zlma = zlma.shift(offset) - - # Fill - if "fillna" in kwargs: - zlma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - zlma.name = f"ZL_{zlma.name}" - zlma.category = "overlap" - - return zlma diff --git a/src/aiomql/ta_libs/pandas_ta/performance/__init__.py b/src/aiomql/ta_libs/pandas_ta/performance/__init__.py deleted file mode 100644 index c30db9e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/performance/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -from .drawdown import drawdown -from .log_return import log_return -from .percent_return import percent_return - -__all__ = [ - "drawdown", - "log_return", - "percent_return", -] diff --git a/src/aiomql/ta_libs/pandas_ta/performance/drawdown.py b/src/aiomql/ta_libs/pandas_ta/performance/drawdown.py deleted file mode 100644 index 36a067a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/performance/drawdown.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import log, seterr -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_series - - - -def drawdown( - close: Series, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Drawdown - - This indicator traces the peak-to-trough decline over a specific period. - Commonly quoted as the percentage between the peak and the subsequent - trough. - - Sources: - * [investopedia](https://www.investopedia.com/terms/d/drawdown.asp) - - Parameters: - close (pd.Series): ```close``` Series. - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - close = v_series(close) - offset = v_offset(offset) - - # Calculate - max_close = close.cummax() - dd = max_close - close - dd_pct = 1 - (close / max_close) - - _np_err = seterr() - seterr(divide="ignore", invalid="ignore") - dd_log = log(max_close) - log(close) - seterr(divide=_np_err["divide"], invalid=_np_err["invalid"]) - - # Offset - if offset != 0: - dd = dd.shift(offset) - dd_pct = dd_pct.shift(offset) - dd_log = dd_log.shift(offset) - - # Fill - if "fillna" in kwargs: - dd.fillna(kwargs["fillna"], inplace=True) - dd_pct.fillna(kwargs["fillna"], inplace=True) - dd_log.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - dd.name = "DD" - dd_pct.name = f"{dd.name}_PCT" - dd_log.name = f"{dd.name}_LOG" - dd.category = dd_pct.category = dd_log.category = "performance" - - data = {dd.name: dd, dd_pct.name: dd_pct, dd_log.name: dd_log} - df = DataFrame(data, index=close.index) - df.name = dd.name - df.category = dd.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/performance/log_return.py b/src/aiomql/ta_libs/pandas_ta/performance/log_return.py deleted file mode 100644 index b13514e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/performance/log_return.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from numpy import log, nan, roll -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_bool, v_offset, v_pos_default, v_series - - - -def log_return( - close: Series, length: Int = None, cumulative: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Log Return - - Calculates the logarithmic return. - - Sources: - * [stackoverflow](https://stackoverflow.com/questions/31287552/logarithmic-returns-in-pandas-dataframe) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - cumulative (bool): If True, returns the cumulative returns. - Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length + 1) - - if close is None: - return - - cumulative = v_bool(cumulative, False) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - if cumulative: - r = np_close / np_close[0] - else: - r = np_close / roll(np_close, length) - r[:length] = nan - log_return = Series(log(r), index=close.index) - - # Offset - if offset != 0: - log_return = log_return.shift(offset) - - # Fill - if "fillna" in kwargs: - log_return.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - log_return.name = f"{'CUM' if cumulative else ''}LOGRET_{length}" - log_return.category = "performance" - - return log_return diff --git a/src/aiomql/ta_libs/pandas_ta/performance/percent_return.py b/src/aiomql/ta_libs/pandas_ta/performance/percent_return.py deleted file mode 100644 index 1159639..0000000 --- a/src/aiomql/ta_libs/pandas_ta/performance/percent_return.py +++ /dev/null @@ -1,64 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan, roll -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_bool, v_offset, v_pos_default, v_series - - - -def percent_return( - close: Series, length: Int = None, cumulative: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Percent Return - - Calculates the percent return. - - Sources: - * [stackoverflow](https://stackoverflow.com/questions/31287552/logarithmic-returns-in-pandas-dataframe) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - cumulative (bool): If True, returns the cumulative returns. - Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length + 1) - - if close is None: - return - - cumulative = v_bool(cumulative, False) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - if cumulative: - pr = (np_close / np_close[0]) - 1 - else: - pr = (np_close / roll(np_close, length)) - 1 - pr[:length] = nan - pct_return = Series(pr, index=close.index) - - # Offset - if offset != 0: - pct_return = pct_return.shift(offset) - - # Fill - if "fillna" in kwargs: - pct_return.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pct_return.name = f"{'CUM' if cumulative else ''}PCTRET_{length}" - pct_return.category = "performance" - - return pct_return diff --git a/src/aiomql/ta_libs/pandas_ta/py.typed b/src/aiomql/ta_libs/pandas_ta/py.typed deleted file mode 100644 index e69de29..0000000 diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/__init__.py b/src/aiomql/ta_libs/pandas_ta/statistics/__init__.py deleted file mode 100644 index 594392b..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -from .entropy import entropy -from .kurtosis import kurtosis -from .mad import mad -from .median import median -from .quantile import quantile -from .skew import skew -from .stdev import stdev -from .tos_stdevall import tos_stdevall -from .variance import variance -from .zscore import zscore - -__all__ = [ - "entropy", - "kurtosis", - "mad", - "median", - "quantile", - "skew", - "stdev", - "tos_stdevall", - "variance", - "zscore", -] \ No newline at end of file diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/entropy.py b/src/aiomql/ta_libs/pandas_ta/statistics/entropy.py deleted file mode 100644 index 76607d8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/entropy.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import log -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def entropy( - close: Series, length: Int = None, base: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Entropy - - This indicator attempts to quantify the unpredictability of the data, - or equivalently, its average information. It is a rolling entropy - calculation. - - Sources: - * [wikipedia](https://en.wikipedia.org/wiki/Entropy_(information_theory)) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - base (float): Logarithmic Base. Default: ```2``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, 2 * length - 1) - - if close is None: - return - - base = v_pos_default(base, 2.0) - offset = v_offset(offset) - - # Calculate - p = close / close.rolling(length).sum() - entropy = (-p * log(p) / log(base)).rolling(length).sum() - - # Offset - if offset != 0: - entropy = entropy.shift(offset) - - # Fill - if "fillna" in kwargs: - entropy.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - entropy.name = f"ENTP_{length}" - entropy.category = "statistics" - - return entropy diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/kurtosis.py b/src/aiomql/ta_libs/pandas_ta/statistics/kurtosis.py deleted file mode 100644 index 71c612d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/kurtosis.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def kurtosis( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Kurtosis - - Calculates a rolling Kurtosis. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Danger: - Possible Data Leak - """ - # Validate - length = v_pos_default(length, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - kurtosis = close.rolling(length, min_periods=min_periods).kurt() - - # Offset - if offset != 0: - kurtosis = kurtosis.shift(offset) - - # Fill - if "fillna" in kwargs: - kurtosis.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - kurtosis.name = f"KURT_{length}" - kurtosis.category = "statistics" - - return kurtosis diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/mad.py b/src/aiomql/ta_libs/pandas_ta/statistics/mad.py deleted file mode 100644 index 3404d73..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/mad.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import fabs -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def mad_(series: Series): - """Mean Absolute Deviation""" - return fabs(series - series.mean()).mean() - - -def mad( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Mean Absolute Deviation - - Calculates a rolling Mean Absolute Deviation (MAD. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - mad = close.rolling(length, min_periods=min_periods).apply(mad_, raw=True) - - # Offset - if offset != 0: - mad = mad.shift(offset) - - # Fill - if "fillna" in kwargs: - mad.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - mad.name = f"MAD_{length}" - mad.category = "statistics" - - return mad diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/median.py b/src/aiomql/ta_libs/pandas_ta/statistics/median.py deleted file mode 100644 index edb1db2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/median.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def median( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Median - - Calculates a rolling Median. - - Sources: - * [incrediblecharts](https://www.incrediblecharts.com/indicators/median_price.php) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - median = close.rolling(length, min_periods=min_periods).median() - - # Offset - if offset != 0: - median = median.shift(offset) - - # Fill - if "fillna" in kwargs: - median.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - median.name = f"MEDIAN_{length}" - median.category = "statistics" - - return median diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/quantile.py b/src/aiomql/ta_libs/pandas_ta/statistics/quantile.py deleted file mode 100644 index 610d881..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/quantile.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def quantile( - close: Series, length: Int = None, q: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Quantile - - Calculates a rolling Quantile. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - q (float): The quantile. Default: ```0.5``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - q = float(q) if isinstance(q, float) and 0 < q < 1 else 0.5 - offset = v_offset(offset) - - # Calculate - quantile = close.rolling(length, min_periods=min_periods).quantile(q) - - # Offset - if offset != 0: - quantile = quantile.shift(offset) - - # Fill - if "fillna" in kwargs: - quantile.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - quantile.name = f"QTL_{length}_{q}" - quantile.category = "statistics" - - return quantile diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/skew.py b/src/aiomql/ta_libs/pandas_ta/statistics/skew.py deleted file mode 100644 index d61c10c..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/skew.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def skew( - close: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Skew - - Calculates a rolling Skew. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Danger: - Possible Data Leak - """ - # Validate - length = v_pos_default(length, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - skew = close.rolling(length, min_periods=min_periods).skew() - - # Offset - if offset != 0: - skew = skew.shift(offset) - - # Fill - if "fillna" in kwargs: - skew.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - skew.name = f"SKEW_{length}" - skew.category = "statistics" - - return skew diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/stdev.py b/src/aiomql/ta_libs/pandas_ta/statistics/stdev.py deleted file mode 100644 index e0f429d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/stdev.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import sqrt -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from .variance import variance - - - -def stdev( - close: Series, length: Int = None, - ddof: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Standard Deviation - - Calculates a rolling Standard Deviation. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - ddof (int): Delta Degrees of Freedom. Default: ```1``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * TA Lib does not have a ```ddof``` parameter. - * The divisor used in calculations is: ```N - ddof```, where ```N``` - is the number of elements. To use ```ddof```, set ```talib=False```. - """ - # Validate - length = v_pos_default(length, 30) - close = v_series(close, length) - - if close is None: - return - - ddof = int(ddof) if isinstance(ddof, int) and 0 <= ddof < length else 1 - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import STDDEV - stdev = STDDEV(close, length) - else: - stdev = variance( - close=close, length=length, ddof=ddof, talib=mode_tal - ).apply(sqrt) - - # Offset - if offset != 0: - stdev = stdev.shift(offset) - - # Fill - if "fillna" in kwargs: - stdev.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - stdev.name = f"STDEV_{length}" - stdev.category = "statistics" - - return stdev diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/tos_stdevall.py b/src/aiomql/ta_libs/pandas_ta/statistics/tos_stdevall.py deleted file mode 100644 index b807911..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/tos_stdevall.py +++ /dev/null @@ -1,96 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import arange, array, polyfit, std -from pandas import DataFrame, DatetimeIndex, Series -from pandas_ta._typing import DictLike, Int, List -from pandas_ta.utils import v_list, v_lowerbound, v_offset, v_series - - - -def tos_stdevall( - close: Series, length: Int = None, - stds: List = None, ddof: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """TD Ameritrade's Think or Swim Standard Deviation All - - This indicator returns the standard deviation(s) over all the bars or the - last ```n``` (length) bars. - - Sources: - * [thinkorswim](https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Statistical/StDevAll) - - Parameters: - close (pd.Series): ```close``` Series - length (int): Bars since current/last bar, Series[-1]. Default: ```None``` - stds (list): List of standard deviations in increasing order from the - central Linear Regression line. Default: ```[1,2,3]``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 7+ columns - - Note: - * TA Lib does not have a ```ddof``` parameter. - * The divisor used in calculations is: ```N - ddof```, where ```N``` - is the number of elements. To use ```ddof```, set ```talib=False```. - - Danger: - Possible Data Leak - """ - # Validate - _props = f"TOS_STDEVALL" - if length is None: - length = close.size - else: - length = v_lowerbound(length, 2, 30) - close = close.iloc[-length:] - _props = f"{_props}_{length}" - - close = v_series(close, 2) - - if close is None: - return - - stds = v_list(stds, [1, 2, 3]) - if min(stds) <= 0: - return - - if not all(i < j for i, j in zip(stds, stds[1:])): - stds = stds[::-1] - - ddof = int(ddof) if isinstance(ddof, int) and 0 <= ddof < length else 1 - offset = v_offset(offset) - - # Calculate - X = src_index = close.index - if isinstance(close.index, DatetimeIndex): - X = arange(length) - close = array(close) - - m, b = polyfit(X, close, 1) - lr = Series(m * X + b, index=src_index) - stdev = std(close, ddof=ddof) - - # Name and Category - df = DataFrame({f"{_props}_LR": lr}, index=src_index) - for i in stds: - df[f"{_props}_L_{i}"] = lr - i * stdev - df[f"{_props}_U_{i}"] = lr + i * stdev - df[f"{_props}_L_{i}"].name = df[f"{_props}_U_{i}"].name = f"{_props}" - df[f"{_props}_L_{i}"].category = df[f"{_props}_U_{i}"].category = "statistics" - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - df.name = f"{_props}" - df.category = "statistics" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/variance.py b/src/aiomql/ta_libs/pandas_ta/statistics/variance.py deleted file mode 100644 index 9719625..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/variance.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import v_lowerbound, v_offset, v_series, v_talib - - - -def variance( - close: Series, length: Int = None, - ddof: Int = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Variance - - Calculates a rolling Variance. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - ddof (int): Delta Degrees of Freedom. Default: ```1``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * TA Lib does not have a ```ddof``` parameter. - * The divisor used in calculations is: ```N - ddof```, where ```N``` - is the number of elements. To use ```ddof```, set ```talib=False```. - """ - # Validate - length = v_lowerbound(length, 1, 30) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - close = v_series(close, max(length, min_periods)) - - if close is None: - return - - ddof = int(ddof) if isinstance(ddof, int) and 0 <= ddof < length else 1 - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import VAR - variance = VAR(close, length) - else: - variance = close.rolling(length, min_periods=min_periods).var(ddof) - - # Offset - if offset != 0: - variance = variance.shift(offset) - - # Fill - if "fillna" in kwargs: - variance.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - variance.name = f"VAR_{length}" - variance.category = "statistics" - - return variance diff --git a/src/aiomql/ta_libs/pandas_ta/statistics/zscore.py b/src/aiomql/ta_libs/pandas_ta/statistics/zscore.py deleted file mode 100644 index 19e2689..0000000 --- a/src/aiomql/ta_libs/pandas_ta/statistics/zscore.py +++ /dev/null @@ -1,57 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import sma -from pandas_ta.statistics import stdev -from pandas_ta.utils import v_lowerbound, v_offset, v_series - - - -def zscore( - close: Series, length: Int = None, std: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Rolling Z Score - - Calculates a rolling Z Score. - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```30``` - std (float): Number of deviation standards. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_lowerbound(length, 1, 30) - close = v_series(close, length) - - if close is None: - return - - std = v_lowerbound(std, 1, 1.0) - offset = v_offset(offset) - - # Calculate - std *= stdev(close=close, length=length, **kwargs) - mean = sma(close=close, length=length, **kwargs) - zscore = (close - mean) / std - - # Offset - if offset != 0: - zscore = zscore.shift(offset) - - # Fill - if "fillna" in kwargs: - zscore.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - zscore.name = f"ZS_{length}" - zscore.category = "statistics" - - return zscore diff --git a/src/aiomql/ta_libs/pandas_ta/trend/__init__.py b/src/aiomql/ta_libs/pandas_ta/trend/__init__.py deleted file mode 100644 index afb75b3..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/__init__.py +++ /dev/null @@ -1,46 +0,0 @@ -# -*- coding: utf-8 -*- -from .adx import adx -from .alphatrend import alphatrend -from .amat import amat -from .aroon import aroon -from .chop import chop -from .cksp import cksp -from .decay import decay -from .decreasing import decreasing -from .dpo import dpo -from .ht_trendline import ht_trendline -from .increasing import increasing -from .long_run import long_run -from .psar import psar -from .qstick import qstick -from .rwi import rwi -from .short_run import short_run -from .trendflex import trendflex -from .ttm_trend import ttm_trend -from .vhf import vhf -from .vortex import vortex -from .zigzag import zigzag - -__all__ = [ - "adx", - "alphatrend", - "amat", - "aroon", - "chop", - "cksp", - "decay", - "decreasing", - "dpo", - "ht_trendline", - "increasing", - "long_run", - "psar", - "qstick", - "rwi", - "short_run", - "trendflex", - "ttm_trend", - "vhf", - "vortex", - "zigzag", -] diff --git a/src/aiomql/ta_libs/pandas_ta/trend/adx.py b/src/aiomql/ta_libs/pandas_ta/trend/adx.py deleted file mode 100644 index ba066d2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/adx.py +++ /dev/null @@ -1,168 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib, - zero -) -from pandas_ta.volatility import atr - - - -def adx( - high: Series, low: Series, close: Series, length: Int = None, - signal_length: Int = None, adxr_length: Int = None, scalar: IntFloat = None, - talib: bool = None, tvmode: bool = None, mamode: str = None, - drift: Int = None, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Average Directional Movement - - This indicator attempts to quantify trend strength by measuring the - amount of movement in a single direction. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/average-directional-movement-adx/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - signal_length (int): Signal period. Default: ```length``` - adxr_length (int): ADXR period. Default: ```2``` - scalar (float): Scalar. Default: ```100``` - talib (bool): If installed, use TA Lib. Default: ```True``` - tvmode (bool): Trading View. Default: ```False``` - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - - Note: - ```signal_length``` is like TradingView's default ADX. - """ - # Validate - length = v_pos_default(length, 14) - signal_length = v_pos_default(signal_length, length) - adxr_length = v_pos_default(adxr_length, 2) - _length = max(length, signal_length, adxr_length) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - mode_tv = v_bool(tvmode, False) - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - atr_ = atr( - high=high, low=low, close=close, - length=length, prenan=kwargs.pop("prenan", True) - ) - if atr_ is None or all(isnan(atr_)): - return - - k = scalar / atr_ - - up = high - high.shift(drift) # high.diff(drift) - dn = low.shift(drift) - low # low.diff(-drift).shift(drift) - - pos = ((up > dn) & (up > 0)) * up - neg = ((dn > up) & (dn > 0)) * dn - - # Issue #671 Solution - # not_close = ~isclose(up, dn) - # pos = ((up > dn) & (up > 0) * up & not_close) * up - # neg = ((dn > up) & (dn > 0) * dn & not_close) * dn - - pos = pos.apply(zero) - neg = neg.apply(zero) - - if not mode_tv and Imports["talib"] and mode_tal and length > 1: - from talib import ADX, MINUS_DM, PLUS_DM - adx = ADX(high, low, close, length) - dmp = PLUS_DM(high, low, length) - dmn = MINUS_DM(high, low, length) - - elif mode_tv: - # How to treat the initial value of RMA varies from one another. - # It follows the way TradingView does, setting it to the average of - # previous values. Since 'pandas' does not provide API to control - # the initial value, work around it by modifying input value to get - # desired output. - pos.iloc[length - 1] = pos[:length].sum() - pos[:length - 1] = 0 - neg.iloc[length - 1] = neg[:length].sum() - neg[:length - 1] = 0 - - alpha = 1 / length - dmp = k * pos.ewm(alpha=alpha, adjust=False, min_periods=length).mean() - dmn = k * neg.ewm(alpha=alpha, adjust=False, min_periods=length).mean() - - # The same goes with dx. - dx = scalar * (dmp - dmn).abs() / (dmp + dmn) - dx = dx.shift(-length) - dx.iloc[length - 1] = dx[:length].sum() - dx[:length - 1] = 0 - - adx = ma(mamode, dx, length=signal_length) - # Rollback shifted rows. - adx[:length - 1] = nan - adx = adx.shift(length) - else: - dmp = k * ma(mamode, pos, length=length) - dmn = k * ma(mamode, neg, length=length) - dx = scalar * (dmp - dmn).abs() / (dmp + dmn) - adx = ma(mamode, dx, length=signal_length) - - adxr = 0.5 * (adx + adx.shift(adxr_length)) - - # Offset - if offset != 0: - adx = adx.shift(offset) - adxr = adxr.shift(offset) - dmn = dmn.shift(offset) - dmp = dmp.shift(offset) - - # Fill - if "fillna" in kwargs: - adx.fillna(kwargs["fillna"], inplace=True) - adxr.fillna(kwargs["fillna"], inplace=True) - dmp.fillna(kwargs["fillna"], inplace=True) - dmn.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - adx.name = f"ADX_{signal_length}" - adxr.name = f"ADXR_{signal_length}_{adxr_length}" - dmp.name = f"DMP_{length}" - dmn.name = f"DMN_{length}" - adx.category = dmp.category = dmn.category = "trend" - - data = {adx.name: adx, adxr.name: adxr, dmp.name: dmp, dmn.name: dmn} - df = DataFrame(data, index=close.index) - df.name = f"ADX_{signal_length}" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/alphatrend.py b/src/aiomql/ta_libs/pandas_ta/trend/alphatrend.py deleted file mode 100644 index 26e3bef..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/alphatrend.py +++ /dev/null @@ -1,161 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan, zeros_like -from numba import njit -from pandas import DataFrame, Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.momentum import rsi -from pandas_ta.volatility import atr -from pandas_ta.volume.mfi import mfi -from pandas_ta.utils import ( - v_mamode, - v_offset, - v_pos_default, - v_series, - v_str, - v_talib -) - - - -@njit(cache=True) -def nb_alpha(low_atr, high_atr, momo_threshold): - m = momo_threshold.size - result = zeros_like(low_atr) - - for i in range(1, m): - if momo_threshold[i]: - if low_atr[i] < result[i - 1]: - result[i] = result[i - 1] - else: - result[i] = low_atr[i] - else: - if high_atr[i] > result[i - 1]: - result[i] = result[i - 1] - else: - result[i] = high_atr[i] - result[0] = nan - - return result - - -def alphatrend( - open_: Series, high: Series, low: Series, close: Series, - volume: Series = None, src: str = None, - length: int = None, multiplier: IntFloat = None, - threshold: IntFloat = None, lag: Int = None, - mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -): - """Alpha Trend - - This indicator attempts to filter sideways movement for accurate signals. - - Sources: - * [OnlyFibonacci](https://github.com/OnlyFibonacci/AlgoSeyri/blob/main/alphaTrendIndicator.py) - * [tradingview](https://www.tradingview.com/script/o50NYLAZ-AlphaTrend/) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series. Default: ```None``` - src (str): One of: "open", "high", "low" or "close". - Default: ```"close"``` - length (int): ATR, MFI, or RSI period. Default: ```14``` - multiplier (float): Trailing ATR multiple. Default: ```1``` - threshold (float): Momentum threshold. Default: ```50``` - lag (int): Lag period of main trend. Default: ```2``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - length = v_pos_default(length, 14) - open_ = v_series(open_, length) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if open_ is None or high is None or low is None or close is None: - return - - _src = {"open": open_, "high": high, "low": low, "close": close} - src = v_str(src, "close") - src = src if src in _src.keys() else "close" - - multiplier = v_pos_default(multiplier, 1) - threshold = v_pos_default(threshold, 50) - lag = v_pos_default(lag, 2) - - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - if volume is not None: - volume = v_series(volume) - if volume is None: - return - - # Calculate - atr_ = atr( - high=high, low=low, close=close, length=length, - mamode=mamode, talib=mode_tal - ) - - if atr_ is None or all(isnan(atr_)): - return - - lower_atr = low - atr_ * multiplier - upper_atr = high + atr_ * multiplier - - momo = None - if volume is None: - momo = rsi(close=_src[src], length=length, mamode=mamode, talib=mode_tal) - else: - momo = mfi( - high=high, low=low, close=close, volume=volume, - length=length, talib=mode_tal - ) - - if momo is None: - return - - np_upper_atr, np_lower_atr = upper_atr.to_numpy(), lower_atr.to_numpy() - - at = nb_alpha(np_lower_atr, np_upper_atr, momo.to_numpy() >= threshold) - at = Series(at, index=close.index) - - atl = at.shift(lag) - - if all(isnan(at)) or all(isnan(atl)): - return # Emergency Break - - # Offset - if offset != 0: - at = at.shift(offset) - atl = atl.shift(offset) - - # Fill - if "fillna" in kwargs: - at.fillna(kwargs["fillna"], inplace=True) - atl.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{multiplier}_{threshold}" - at.name = f"ALPHAT{_props}" - atl.name = f"ALPHATl{_props}_{lag}" - at.category = atl.category = "trend" - - data = {at.name: at, atl.name: atl} - df = DataFrame(data, index=close.index) - df.name = at.name - df.category = at.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/amat.py b/src/aiomql/ta_libs/pandas_ta/trend/amat.py deleted file mode 100644 index f29c5d1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/amat.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series -from .long_run import long_run -from .short_run import short_run - - - -def amat( - close: Series, fast: Int = None, slow: Int = None, - lookback: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Archer Moving Averages Trends - - This indicator, by Kevin Johnson, attempts to identify both long run - and short run trends. - - Sources: - * Kevin Johnson - * [tradingview](https://www.tradingview.com/script/Z2mq63fE-Trade-Archer-Moving-Averages-v1-4F/) - - Parameters: - close (pd.Series): ```close``` Series - fast (int): Fast MA period. Default: ```8``` - slow (int): Slow MA period. Default: ```21``` - lookback (int): Lookback period for ```long_run``` and ```short_run```. - Default: ```2``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - run_length (int): OBV trend period. Default: ```2``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - Both the long run and short run values are integers, where ```1``` - is a trend and ```0``` is not a trend. - """ - # Validate - fast = v_pos_default(fast, 8) - slow = v_pos_default(slow, 21) - lookback = v_pos_default(lookback, 2) - close = v_series(close, max(fast, slow, lookback)) - - if close is None: - return - - mamode = v_mamode(mamode, "ema") - offset = v_offset(offset) - if "length" in kwargs: - kwargs.pop("length") - - # Calculate - fast_ma = ma(mamode, close, length=fast, **kwargs) - slow_ma = ma(mamode, close, length=slow, **kwargs) - - mas_long = long_run(fast_ma, slow_ma, length=lookback) - mas_short = short_run(fast_ma, slow_ma, length=lookback) - - # Offset - if offset != 0: - mas_long = mas_long.shift(offset) - mas_short = mas_short.shift(offset) - - # Fill - if "fillna" in kwargs: - mas_long.fillna(kwargs["fillna"], inplace=True) - mas_short.fillna(kwargs["fillna"], inplace=True) - - _props = f"_{fast}_{slow}_{lookback}" - data = { - f"AMAT{mamode[0]}_LR{_props}": mas_long, - f"AMAT{mamode[0]}_SR{_props}": mas_short - } - df = DataFrame(data, index=close.index) - - # Name and Category - df.name = f"AMAT{mamode[0]}{_props}" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/aroon.py b/src/aiomql/ta_libs/pandas_ta/trend/aroon.py deleted file mode 100644 index a831bd7..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/aroon.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - recent_maximum_index, - recent_minimum_index, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) - - - -def aroon( - high: Series, low: Series, - length: Int = None, scalar: IntFloat = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Aroon & Aroon Oscillator - - This indicator attempts to identify trends and their magnitude. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/aroon-ar/) - * [tradingview](https://www.tradingview.com/wiki/Aroon) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - length (int): The period. Default: ```14``` - scalar (float): Scalar. Default: ```100``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - length = v_pos_default(length, 14) - high = v_series(high, length + 1) - low = v_series(low, length + 1) - - if high is None or low is None: - return - - scalar = v_scalar(scalar, 100) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import AROON, AROONOSC - aroon_down, aroon_up = AROON(high, low, length) - aroon_osc = AROONOSC(high, low, length) - else: - periods_from_hh = high.rolling(length + 1) \ - .apply(recent_maximum_index,raw=True) - periods_from_ll = low.rolling(length + 1) \ - .apply(recent_minimum_index,raw=True) - - aroon_up = aroon_down = scalar - aroon_up *= 1 - (periods_from_hh / length) - aroon_down *= 1 - (periods_from_ll / length) - aroon_osc = aroon_up - aroon_down - - # Offset - if offset != 0: - aroon_up = aroon_up.shift(offset) - aroon_down = aroon_down.shift(offset) - aroon_osc = aroon_osc.shift(offset) - - # Fill - if "fillna" in kwargs: - aroon_up.fillna(kwargs["fillna"], inplace=True) - aroon_down.fillna(kwargs["fillna"], inplace=True) - aroon_osc.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - aroon_up.name = f"AROONU_{length}" - aroon_down.name = f"AROOND_{length}" - aroon_osc.name = f"AROONOSC_{length}" - - aroon_down.category = aroon_up.category = aroon_osc.category = "trend" - - data = { - aroon_down.name: aroon_down, - aroon_up.name: aroon_up, - aroon_osc.name: aroon_osc - } - df = DataFrame(data, index=high.index) - df.name = f"AROON_{length}" - df.category = aroon_down.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/chop.py b/src/aiomql/ta_libs/pandas_ta/trend/chop.py deleted file mode 100644 index ff278d5..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/chop.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import log, log10 -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - v_bool, - v_drift, - v_offset, - v_pos_default, - v_scalar, - v_series -) -from pandas_ta.volatility import atr - - - -def chop( - high: Series, low: Series, close: Series, - length: Int = None, atr_length: Int = None, - ln: bool = None, scalar: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Choppiness Index - - This indicator, by E.W. Dreiss, attempts to determine choppiness. - - Sources: - * E.W. Dreiss an Australian Commodity Trader - * [motivewave](https://www.motivewave.com/studies/choppiness_index.htm) - * [tradingview](https://www.tradingview.com/scripts/choppinessindex/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - atr_length (int): ATR period. Default: ```1``` - ln (bool): Use ```ln``` instead of ```log10```. Default: ```False``` - scalar (float): Scalar. Default: ```100``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - * Choppy: ```~ 100``` - * Trending: ```~ 0``` - """ - # Validate - length = v_pos_default(length, 14) - high = v_series(high, length + 1) - low = v_series(low, length + 1) - close = v_series(close, length + 1) - - if high is None or low is None or close is None: - return - - atr_length = v_pos_default(atr_length, 1) - scalar = v_scalar(scalar, 100) - ln = v_bool(ln, False) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - diff = high.rolling(length).max() - low.rolling(length).min() - - atr_ = atr(high=high, low=low, close=close, length=atr_length) - atr_sum = atr_.rolling(length).sum() - - chop = scalar - if ln: - chop *= (log(atr_sum) - log(diff)) / log(length) - else: - chop *= (log10(atr_sum) - log10(diff)) / log10(length) - - # Offset - if offset != 0: - chop = chop.shift(offset) - - # Fill - if "fillna" in kwargs: - chop.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - chop.name = f"CHOP{'ln' if ln else ''}_{length}_{atr_length}_{scalar}" - chop.category = "trend" - - return chop diff --git a/src/aiomql/ta_libs/pandas_ta/trend/cksp.py b/src/aiomql/ta_libs/pandas_ta/trend/cksp.py deleted file mode 100644 index ada5e75..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/cksp.py +++ /dev/null @@ -1,101 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - v_mamode, - v_offset, - v_pos_default, - v_series, - v_tradingview -) -from pandas_ta.volatility import atr - - - -def cksp( - high: Series, low: Series, close: Series, - p: Int = None, x: IntFloat = None, q: Int = None, - tvmode: bool = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Chande Kroll Stop - - This indicator, by Tushar Chande and Stanley Kroll, attempts to identify - trends with long and short stops. - - Sources: - * "The New Technical Trader", Wiley 1st ed. ISBN 9780471597803, page 95 - * [multicharts](https://www.multicharts.com/discussion/viewtopic.php?t=48914) - - Parameters: - close (pd.Series): ```close``` Series - p (int): ATR and first stop period; see Note. - Default: ```10``` for both modes - x (float): ATR scalar; see Note. Default: ```1``` or ```3``` - q (int): Second stop period; see Note. Default: ```9``` or ```20``` - tvmode (bool): Trading View mode. Default: ```True``` - mamode (str): See ```help(ta.ma)```. Default: ```None``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: Book vs TradingView Defaults - * Book: ```p=10, x=3, q=20, ma="sma"``` - * Trading View: ```p=10, x=1, q=9, ma="rma"``` - """ - # Validate - mode_tv = v_tradingview(tvmode) - p = v_pos_default(p, 10) - # TODO: clean up x and q - x = float(x) if isinstance(x, float) and x > 0 else 1 if tvmode is True else 3 - q = int(q) if isinstance(q, float) and q > 0 else 9 if tvmode is True else 20 - _length = p + q - - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mamode = v_mamode(mamode, "rma") if mode_tv else v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - atr_ = atr(high=high, low=low, close=close, length=p, mamode=mamode) - if atr_ is None or all(isnan(atr_)): - return - - long_stop_ = high.rolling(p).max() - x * atr_ - long_stop = long_stop_.rolling(q).max() - - short_stop_ = low.rolling(p).min() + x * atr_ - short_stop = short_stop_.rolling(q).min() - - # Offset - if offset != 0: - long_stop = long_stop.shift(offset) - short_stop = short_stop.shift(offset) - - # Fill - if "fillna" in kwargs: - long_stop.fillna(kwargs["fillna"], inplace=True) - short_stop.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{p}_{x}_{q}" - long_stop.name = f"CKSPl{_props}" - short_stop.name = f"CKSPs{_props}" - long_stop.category = short_stop.category = "trend" - - data = {long_stop.name: long_stop, short_stop.name: short_stop} - df = DataFrame(data, index=close.index) - df.name = f"CKSP{_props}" - df.category = long_stop.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/decay.py b/src/aiomql/ta_libs/pandas_ta/trend/decay.py deleted file mode 100644 index c799b0a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/decay.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import float64, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_str - - - -# Exponential Decay - https://tulipindicators.org/edecay -@njit(cache=True) -def nb_exponential_decay(x, n): - m, rate = x.size, 1.0 - (1.0 / n) - - result = zeros_like(x, dtype=float64) - result[0] = x[0] - - for i in range(1, m): - result[i] = max(0, x[i], result[i - 1] * rate) - - return result - - -# Linear Decay - https://tulipindicators.org/decay -@njit(cache=True) -def nb_linear_decay(x, n): - m, rate = x.size, 1.0 / n - - result = zeros_like(x, dtype=float64) - result[0] = x[0] - - for i in range(1, m): - result[i] = max(0, x[i], result[i - 1] - rate) - - return result - - -def decay( - close: Series, length: Int = None, mode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Decay - - This function creates a decay moving forward from prior signals. - - Sources: - * [tulipindicators](https://tulipindicators.org/decay) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - mode (str): Either ```"linear"``` or ```"exp"``` (exponetional) - Default: ```"linear"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - close = v_series(close, length) - - if close is None: - return - - length = v_pos_default(length, 1) - mode = v_str(mode, "linear") - offset = v_offset(offset) - - # Calculate - _mode, np_close = "L", close.to_numpy() - - if mode in ["exp", "exponential"]: - _mode = "EXP" - result = nb_exponential_decay(np_close, length) - else: # "linear" - result = nb_linear_decay(np_close, length) - - result = Series(result, index=close.index) - - # Offset - if offset != 0: - result = result.shift(offset) - - # Fill - if "fillna" in kwargs: - result.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - result.name = f"{_mode}DECAY_{length}" - result.category = "trend" - - return result diff --git a/src/aiomql/ta_libs/pandas_ta/trend/decreasing.py b/src/aiomql/ta_libs/pandas_ta/trend/decreasing.py deleted file mode 100644 index a30ca01..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/decreasing.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - v_percent, - v_bool, - v_drift, - v_offset, - v_pos_default, - v_series -) - - - -def decreasing( - close: Series, length: Int = None, strict: bool = None, - asint: bool = None, percent: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Decreasing - - This indicator, by Kevin Johnson, attempts to identify decreasing periods. - - Sources: - * Kevin Johnson - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - strict (bool): Check if continuously increasing. Default: ```False``` - percent (float): Percent, i.e. ```5.0```. Default: ```None``` - asint (bool): Returns as ```Int```. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length) - - if close is None: - return - - strict = v_bool(strict, False) - asint = v_bool(asint, True) - percent = float(percent) if v_percent(percent) else False - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - close_ = (1 - 0.01 * percent) * close if percent else close - if strict: - # Returns value as float64? Have to cast to bool - decreasing = close < close_.shift(drift) - for x in range(3, length + 1): - decreasing &= (close.shift(x - (drift + 1)) < close_.shift(x - drift)) - - decreasing.fillna(0, inplace=True) - decreasing = decreasing.astype(bool) - else: - decreasing = close_.diff(length) < 0 - - if asint: - decreasing = decreasing.astype(int) - - # Offset - if offset != 0: - decreasing = decreasing.shift(offset) - - # Fill - if "fillna" in kwargs: - decreasing.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _percent = f"_{0.01 * percent}" if percent else '' - _props = f"{'S' if strict else ''}DEC{'p' if percent else ''}" - decreasing.name = f"{_props}_{length}{_percent}" - decreasing.category = "trend" - - return decreasing diff --git a/src/aiomql/ta_libs/pandas_ta/trend/dpo.py b/src/aiomql/ta_libs/pandas_ta/trend/dpo.py deleted file mode 100644 index d172da7..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/dpo.py +++ /dev/null @@ -1,69 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import sma -from pandas_ta.utils import v_bool, v_offset, v_pos_default, v_series - - - -def dpo( - close: Series, length: Int = None, centered: bool = True, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Detrend Price Oscillator - - This indicator attempts to detrend (remove the trend) and identify cycles. - - Sources: - * [fidelity](https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/dpo) - * [stockcharts](http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:detrended_price_osci) - * [tradingview](https://www.tradingview.com/scripts/detrendedpriceoscillator/) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - centered (bool): Shift the dpo back by ```int(0.5 * length) + 1```. - Set to ```False``` to remove data leakage. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Danger: Possible Data Leak - Set ```centered=False``` to remove data leakage. See [Issue #60]( https://github.com/twopirllc/pandas-ta/issues/60#). - """ - # Validate - length = v_pos_default(length, 20) - close = v_series(close, length + 1) - - if close is None: - return - - centered = v_bool(centered, True) - offset = v_offset(offset) - - # Calculate - t = int(0.5 * length) + 1 - ma = sma(close, length) - - if centered: - dpo = (close.shift(t) - ma).shift(-t) - else: - dpo = close - ma.shift(t) - - # Offset - if offset != 0: - dpo = dpo.shift(offset) - - # Fill - if "fillna" in kwargs: - dpo.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - dpo.name = f"DPO_{length}" - dpo.category = "trend" - - return dpo diff --git a/src/aiomql/ta_libs/pandas_ta/trend/ht_trendline.py b/src/aiomql/ta_libs/pandas_ta/trend/ht_trendline.py deleted file mode 100644 index 0f72671..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/ht_trendline.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import arctan, copy, isnan, nan, rad2deg, zeros_like, zeros -from numba import njit -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_bool, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -@njit(cache=True) -def nb_ht_trendline(x): - a, b, m = 0.0962, 0.5769, x.size - - wma4, dt = zeros_like(x), zeros_like(x) - q1, q2 = zeros_like(x), zeros_like(x) - ji, jq = zeros_like(x), zeros_like(x) - i1, i2 = zeros_like(x), zeros_like(x) - re, im = zeros_like(x), zeros_like(x) - period, smp = zeros_like(x), zeros_like(x) - i_trend = zeros_like(x) - - result = zeros_like(x) - result[:13] = x[:13] - - # Ehlers's starts from 6, TALib from 63 - for i in range(6, m): - adj_prev_period = 0.075 * period[i - 1] + 0.54 - - wma4[i] = 0.4 * x[i] + 0.3 * x[i - 1] + 0.2 * x[i - 2] + 0.1 * x[i - 3] - dt[i] = adj_prev_period * (a * wma4[i] + b * wma4[i - 2] - b * wma4[i - 4] - a * wma4[i - 6]) - - q1[i] = adj_prev_period * (a * dt[i] + b * dt[i - 2] - b * dt[i - 4] - a * dt[i - 6]) - i1[i] = dt[i - 3] - - ji[i] = adj_prev_period * (a * i1[i] + b * i1[i - 2] - b * i1[i - 4] - a * i1[i - 6]) - jq[i] = adj_prev_period * (a * q1[i] + b * q1[i - 2] - b * q1[i - 4] - a * q1[i - 6]) - - i2[i] = i1[i] - jq[i] - q2[i] = q1[i] + ji[i] - - i2[i] = 0.2 * i2[i] + 0.8 * i2[i - 1] - q2[i] = 0.2 * q2[i] + 0.8 * q2[i - 1] - - re[i] = i2[i] * i2[i - 1] + q2[i] * q2[i - 1] - im[i] = i2[i] * q2[i - 1] - q2[i] * i2[i - 1] - - re[i] = 0.2 * re[i] + 0.8 * re[i - 1] - im[i] = 0.2 * im[i] + 0.8 * im[i - 1] - - if re[i] != 0 and im[i] != 0: - period[i] = 360.0 / rad2deg(arctan(im[i] / re[i])) - if period[i] > 1.5 * period[i - 1]: - period[i] = 1.5 * period[i - 1] - if period[i] < 0.67 * period[i - 1]: - period[i] = 0.67 * period[i - 1] - if period[i] < 6.0: - period[i] = 6.0 - if period[i] > 50.0: - period[i] = 50.0 - period[i] = 0.2 * period[i] + 0.8 * period[i - 1] - smp[i] = 0.33 * period[i] + 0.67 * smp[i - 1] - - dc_period = int(smp[i] + 0.5) - dcp_avg = 0 - for k in range(dc_period): - dcp_avg += x[i - k] - - if dc_period > 0: - dcp_avg /= dc_period - - i_trend[i] = dcp_avg - - if i > 12: - result[i] = 0.4 * i_trend[i] + 0.3 * i_trend[i - 1] + 0.2 * i_trend[i - 2] + 0.1 * i_trend[i - 3] - - return result - - -def ht_trendline( - close: Series, talib: bool = None, - prenan: Int = None, offset: Int = None, - **kwargs: DictLike -) -> Series: - """Hilbert Transform TrendLine - - This indicator uses the Hilbert Transform to smooth values. - - Sources: - * John F Ehlers's "Rocket Science for Traders" Book - * [mql5](https://c.mql5.com/forextsd/forum/59/023inst.pdf) - * TA-Lib [ta_HT_TRENDLINE](https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_HT_TRENDLINE.c) - - Parameters: - close (pd.Series): ```close``` Series. - talib (bool): If installed, use TA Lib. Default: ```True``` - prenan (int): Prenans to apply. Ehlers's ```6``` or ```12```, - TALib ```63``` Default: ```63``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9979308363057683)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - prenan = v_pos_default(prenan, 63) - close = v_series(close, prenan) - - if close is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - if Imports["talib"] and mode_tal: - from talib import HT_TRENDLINE - tl = HT_TRENDLINE(close) - else: - np_close = close.to_numpy() - np_tl = nb_ht_trendline(np_close) - - if prenan > 0: - np_tl[:prenan] = nan - tl = Series(np_tl, index=close.index) - - if all(isnan(tl)): - return # Emergency Break - - # Offset - if offset != 0: - trend_line = tl.shift(offset) - - # Fill - if "fillna" in kwargs: - tl.fillna(kwargs["fillna"], inplace=True) - - tl.name = f"HT_TL" - tl.category = "trend" - - return tl diff --git a/src/aiomql/ta_libs/pandas_ta/trend/increasing.py b/src/aiomql/ta_libs/pandas_ta/trend/increasing.py deleted file mode 100644 index b298843..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/increasing.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - v_percent, - v_bool, - v_drift, - v_offset, - v_pos_default, - v_series -) - - - -def increasing( - close: Series, length: Int = None, strict: bool = None, - asint: bool = None, percent: IntFloat = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Increasing - - This indicator, by Kevin Johnson, attempts to identify increasing periods. - - Sources: - * Kevin Johnson - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```1``` - strict (bool): Check if continuously increasing. Default: ```False``` - percent (float): Percent, i.e. ```5.0```. Default: ```None``` - asint (bool): Returns as ```Int```. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length) - - if close is None: - return - - strict = v_bool(strict, False) - asint = v_bool(asint, True) - percent = float(percent) if v_percent(percent) else False - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - close_ = (1 + 0.01 * percent) * close if percent else close - if strict: - # Returns value as float64? Have to cast to bool - increasing = close > close_.shift(drift) - for x in range(3, length + 1): - increasing &= (close.shift(x - (drift + 1)) > close_.shift(x - drift)) - - increasing.fillna(0, inplace=True) - increasing = increasing.astype(bool) - else: - increasing = close_.diff(length) > 0 - - if asint: - increasing = increasing.astype(int) - - # Offset - if offset != 0: - increasing = increasing.shift(offset) - - # Fill - if "fillna" in kwargs: - increasing.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _percent = f"_{0.01 * percent}" if percent else '' - _props = f"{'S' if strict else ''}INC{'p' if percent else ''}" - increasing.name = f"{_props}_{length}{_percent}" - increasing.category = "trend" - - return increasing diff --git a/src/aiomql/ta_libs/pandas_ta/trend/long_run.py b/src/aiomql/ta_libs/pandas_ta/trend/long_run.py deleted file mode 100644 index 48662aa..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/long_run.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series -from .decreasing import decreasing -from .increasing import increasing - - - -def long_run( - fast: Series, slow: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Long Run - - This indicator, by Kevin Johnson, attempts to identify long runs. - - Sources: - * Kevin Johnson - * [tradingview](https://www.tradingview.com/script/Z2mq63fE-Trade-Archer-Moving-Averages-v1-4F/) - - Parameters: - fast (pd.Series): ```fast``` Series. - slow (pd.Series): ```slow``` Series. - length (int): The ```decreasing``` and ```increasing``` period. - Default: ```2``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 2) - fast = v_series(fast, length) - slow = v_series(slow, length) - - if fast is None or slow is None: - return - - offset = v_offset(offset) - - # Calculate - inc = increasing(fast, length) - - # potential bottom or bottom - pb = inc & decreasing(slow, length) - # fast and slow are increasing - bi = inc & increasing(slow, length) - long_run = pb | bi - - # Offset - if offset != 0: - long_run = long_run.shift(offset) - - # Fill - if "fillna" in kwargs: - long_run.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - long_run.name = f"LR_{length}" - long_run.category = "trend" - - return long_run diff --git a/src/aiomql/ta_libs/pandas_ta/trend/psar.py b/src/aiomql/ta_libs/pandas_ta/trend/psar.py deleted file mode 100644 index 8c8644e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/psar.py +++ /dev/null @@ -1,154 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import full, nan, zeros -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series, zero - - - -def psar( - high: Series, low: Series, close: Series = None, - af0: IntFloat = None, af: IntFloat = None, max_af: IntFloat = None, tv=False, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Parabolic Stop and Reverse - - This indicator, by J. Wells Wilder, attempts to identify trend direction - and potential reversals. - - Sources: - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=66&Name=Parabolic) - * [tradingview](https://www.tradingview.com/pine-script-reference/#fun_sar) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): Optional ```close``` Series - af0 (float): Initial Acceleration Factor. Default: ```0.02``` - af (float): Acceleration Factor. Default: ```0.02``` - max_af (float): Maximum Acceleration Factor. Default: ```0.2``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - - Warning: - TA-Lib Correlation: ```np.float64(0.9837617513753181)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - _length = 1 - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - orig_high = high.copy() - orig_low = low.copy() - # Numpy arrays offer some performance improvements - high, low = high.to_numpy(), low.to_numpy() - - paf = v_pos_default(af, 0.02) # paf is used to keep af from parameters - af0 = v_pos_default(af0, paf) - af = af0 - - max_af = v_pos_default(max_af, 0.2) - offset = v_offset(offset) - - # Set up - m = high.size - sar = zeros(m) - long = full(m, nan) - short = full(m, nan) - reversal = zeros(m, dtype=int) - _af = zeros(m) - _af[:2] = af0 - falling = _falling(orig_high.iloc[:2], orig_low.iloc[:2]) - ep = low[0] if falling else high[0] - if close is not None: - close = v_series(close) - sar[0] = close.iloc[0] - else: - sar[0] = high[0] if falling else low[0] - - # Calculate - for i in range(1, m): - sar[i] = sar[i - 1] + af * (ep - sar[i - 1]) - - if falling: - reverse = high[i] > sar[i] - if low[i] < ep: - ep = low[i] - af = min(af + af0, max_af) - sar[i] = max(high[i - 1], sar[i]) - else: - reverse = low[i] < sar[i] - if high[i] > ep: - ep = high[i] - af = min(af + af0, max_af) - sar[i] = min(low[i - 1], sar[i]) - - if reverse: - sar[i] = ep - af = af0 - falling = not falling - ep = low[i] if falling else high[i] - - # Separate long/short SAR based on falling - if falling: - short[i] = sar[i] - else: - long[i] = sar[i] - - _af[i] = af - reversal[i] = int(reverse) - - _af = Series(_af, index=orig_high.index) - long = Series(long, index=orig_high.index) - short = Series(short, index=orig_high.index) - reversal = Series(reversal, index=orig_high.index) - - # Offset - if offset != 0: - _af = _af.shift(offset) - long = long.shift(offset) - short = short.shift(offset) - reversal = reversal.shift(offset) - - # Fill - if "fillna" in kwargs: - _af.fillna(kwargs["fillna"], inplace=True) - long.fillna(kwargs["fillna"], inplace=True) - short.fillna(kwargs["fillna"], inplace=True) - reversal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _name = f"PSAR" - _props = f"_{af0}_{max_af}" - - data = { - f"{_name}l{_props}": long, - f"{_name}s{_props}": short, - f"{_name}af{_props}": _af, - f"{_name}r{_props}": reversal - } - df = DataFrame(data, index=orig_high.index) - df.name = f"{_name}{_props}" - df.category = long.category = short.category = "trend" - - return df - - -def _falling(high, low, drift: int = 1): - """Returns the last -DM value""" - # Not to be confused with ta.falling() - up = high - high.shift(drift) - dn = low.shift(drift) - low - _dmn = (((dn > up) & (dn > 0)) * dn).apply(zero).iloc[-1] - return _dmn > 0 diff --git a/src/aiomql/ta_libs/pandas_ta/trend/qstick.py b/src/aiomql/ta_libs/pandas_ta/trend/qstick.py deleted file mode 100644 index c8a13ed..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/qstick.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - non_zero_range, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def qstick( - open_: Series, close: Series, length: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Q Stick - - This indicator, by Tushar Chande, attempts to quantify and identify - trends. - - Sources: - * [tradingtechnologies](https://library.tradingtechnologies.com/trade/chrt-ti-qstick.html) - - Parameters: - open_ (pd.Series): ```open``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - open_ = v_series(open_, length) - close = v_series(close, length) - - if open_ is None or close is None: - return - - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - diff = non_zero_range(close, open_) - qstick = ma(mamode, diff, length=length, **kwargs) - - # Offset - if offset != 0: - qstick = qstick.shift(offset) - - # Fill - if "fillna" in kwargs: - qstick.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - qstick.name = f"QS_{length}" - qstick.category = "trend" - - return qstick diff --git a/src/aiomql/ta_libs/pandas_ta/trend/rwi.py b/src/aiomql/ta_libs/pandas_ta/trend/rwi.py deleted file mode 100644 index 45b3ae4..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/rwi.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.volatility import atr -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def rwi( - high: Series, low: Series, close: Series, - length: Int = None, mamode: str = None, talib: bool = None, - drift: Int = None, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Random Walk Index - - This indicator attempts to identify the difference between a trend and - a random walk. - - Sources: - * [technicalindicators](https://www.technicalindicators.net/indicators-technical-analysis/168-rwi-random-walk-index) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - length = v_pos_default(length, 14) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - atr_ = atr( - high=high, low=low, close=close, - length=length, mamode=mamode, talib=mode_tal - ) - if all(isnan(atr_)): - return # Emergency Break - - denom = atr_ * (length ** 0.5) - rwi_high = (high - low.shift(length)) / denom - rwi_low = (high.shift(length) - low) / denom - - # Offset - if offset != 0: - rwi_high = rwi_high.shift(offset) - rwi_low = rwi_low.shift(offset) - - # Fill - if "fillna" in kwargs: - rwi_high.fillna(kwargs["fillna"], inplace=True) - rwi_low.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rwi_high.name = f"RWIh_{length}" - rwi_low.name = f"RWIl_{length}" - rwi_high.category = rwi_low.category = "trend" - - # Prepare DataFrame to return - data = {rwi_high.name: rwi_high, rwi_low.name: rwi_low} - df = DataFrame(data, index=close.index) - df.name = f"RWI_{length}" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/short_run.py b/src/aiomql/ta_libs/pandas_ta/trend/short_run.py deleted file mode 100644 index 213b133..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/short_run.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series -from .decreasing import decreasing -from .increasing import increasing - - - -def short_run( - fast: Series, slow: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Short Run - - This indicator, by Kevin Johnson, attempts to identify short runs. - - Sources: - * Kevin Johnson - * [tradingview](https://www.tradingview.com/script/Z2mq63fE-Trade-Archer-Moving-Averages-v1-4F/) - - Parameters: - fast (pd.Series): ```fast``` Series. - slow (pd.Series): ```slow``` Series. - length (int): The ```decreasing``` and ```increasing``` period. - Default: ```2``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 2) - fast = v_series(fast, length) - slow = v_series(slow, length) - - if fast is None or slow is None: - return - - offset = v_offset(offset) - - # Calculate - dec = decreasing(fast, length) - - # potential top or top - pt = dec & increasing(slow, length) - # fast and slow are decreasing - bd = dec & decreasing(slow, length) - short_run = pt | bd - - # Offset - if offset != 0: - short_run = short_run.shift(offset) - - # Fill - if "fillna" in kwargs: - short_run.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - short_run.name = f"SR_{length}" - short_run.category = "trend" - - return short_run diff --git a/src/aiomql/ta_libs/pandas_ta/trend/trendflex.py b/src/aiomql/ta_libs/pandas_ta/trend/trendflex.py deleted file mode 100644 index 0e010ca..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/trendflex.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import cos, exp, nan, sqrt, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -# Ehlers's Trendflex -# http://traders.com/Documentation/FEEDbk_docs/2020/02/TradersTips.html -@njit(cache=True) -def nb_trendflex(x, n, k, alpha, pi, sqrt2): - m, ratio = x.size, 2 * sqrt2 / k - a = exp(-pi * ratio) - b = 2 * a * cos(180 * ratio) - c = a * a - b + 1 - - _f = zeros_like(x) - _ms = zeros_like(x) - result = zeros_like(x) - - for i in range(2, m): - _f[i] = 0.5 * c * (x[i] + x[i - 1]) + b * _f[i - 1] - a * a * _f[i - 2] - - for i in range(n, m): - _sum = 0 - for j in range(1, n): - _sum += _f[i] - _f[i - j] - _sum /= n - - _ms[i] = alpha * _sum * _sum + (1 - alpha) * _ms[i - 1] - if _ms[i] != 0.0: - result[i] = _sum / sqrt(_ms[i]) - - return result - - -def trendflex( - close: Series, length: Int = None, - smooth: Int = None, alpha: IntFloat = None, - pi: IntFloat = None, sqrt2: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Trendflex - - This trend indicator, by John F. Ehlers, complements the "reflex" - indicator. - - Sources: - * [rengel8](https://github.com/rengel8) (2021-08-11) based on the - implementation from "ProRealCode" (2021-08-11) - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/reflex-and-trendflex-indicators-john-f-ehlers/) - * [traders](http://traders.com/Documentation/FEEDbk_docs/2020/02/TradersTips.html) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - smooth (int): Super Smoother period. Default: ```20```` - alpha (float): Alpha weight. Default: ```0.04``` - pi (float): Ehlers's truncated value: ```3.14159```. - Default: ```3.14159``` - sqrt2 (float): Ehlers's truncated value: ```1.414```. - Default: ```1.414``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - John F. Ehlers introduced two indicators within the article - "Reflex: A New Zero-Lag Indicator” in February 2020, TASC magazine. - One of which is Reflex, a lag reduced cycle indicator. Both indicators - (Reflex/Trendflex) are oscillators that complement each other with the - focus for cycle and trend. - """ - # Validate - length = v_pos_default(length, 20) - smooth = v_pos_default(smooth, 20) - close = v_series(close, max(length, smooth) + 1) - - if close is None: - return - - alpha = v_pos_default(alpha, 0.04) - pi = v_pos_default(pi, 3.14159) - sqrt2 = v_pos_default(sqrt2, 1.414) - offset = v_offset(offset) - - # Calculate - np_close = close.to_numpy() - result = nb_trendflex(np_close, length, smooth, alpha, pi, sqrt2) - result[:length] = nan - result = Series(result, index=close.index) - - # Offset - if offset != 0: - result = result.shift(offset) - - # Fill - if "fillna" in kwargs: - result.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - result.name = f"TRENDFLEX_{length}_{smooth}_{alpha}" - result.category = "trend" - - return result diff --git a/src/aiomql/ta_libs/pandas_ta/trend/ttm_trend.py b/src/aiomql/ta_libs/pandas_ta/trend/ttm_trend.py deleted file mode 100644 index 4a8baee..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/ttm_trend.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import hl2 -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def ttm_trend( - high: Series, low: Series, close: Series, - length: Int = None, offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """TTM Trend - - This indicator, by John Carter, labels bars green, ```1```, or - red ```-1```, when above or below the average value. - - Sources: - * John Carter, book “Mastering the Trade” - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/ttm-trend-price/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```6``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 1 column - - Tip: - * Two bars of the opposite color is the signal to get in or out. - * Recommended to stay in trade if colors do not change. - """ - # Validate - length = v_pos_default(length, 6) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - trend_avg = hl2(high, low) - for i in range(1, length): - trend_avg = trend_avg + hl2(high.shift(i), low.shift(i)) - - trend_avg = trend_avg / length - - tm_trend = (close > trend_avg).astype(int) - tm_trend.replace(0, -1, inplace=True) - - # Offset - if offset != 0: - tm_trend = tm_trend.shift(offset) - - # Fill - if "fillna" in kwargs: - tm_trend.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - tm_trend.name = f"TTM_TRND_{length}" - tm_trend.category = "momentum" - - df = DataFrame({tm_trend.name: tm_trend}, index=close.index) - df.name = f"TTMTREND_{length}" - df.category = tm_trend.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/vhf.py b/src/aiomql/ta_libs/pandas_ta/trend/vhf.py deleted file mode 100644 index 23be42d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/vhf.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import inf, fabs, nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import ( - non_zero_range, - v_drift, - v_offset, - v_pos_default, - v_series -) - - - -def vhf( - close: Series, length: Int = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Vertical Horizontal Filter - - This indicator, by Adam White, attempts to identify trending and - ranging markets. - - Sources: - * [incrediblecharts](https://www.incrediblecharts.com/indicators/vertical_horizontal_filter.php) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```28``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 28) - close = v_series(close, length) - - if close is None: - return - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - hcp = close.rolling(length).max() - lcp = close.rolling(length).min() - diff = fabs(close.diff(drift)) - vhf = fabs(non_zero_range(hcp, lcp)) / diff.rolling(length).sum() - vhf.replace([inf, -inf], nan, inplace=True) - # np_vhf = where(np_vhf == inf, nan, np_vhf) - - # Offset - if offset != 0: - vhf = vhf.shift(offset) - - # Fill - if "fillna" in kwargs: - vhf.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - vhf.name = f"VHF_{length}" - vhf.category = "trend" - - return vhf diff --git a/src/aiomql/ta_libs/pandas_ta/trend/vortex.py b/src/aiomql/ta_libs/pandas_ta/trend/vortex.py deleted file mode 100644 index 14739de..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/vortex.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_drift, v_offset, v_pos_default, v_series -from pandas_ta.volatility import true_range - - - -def vortex( - high: Series, low: Series, close: Series, - length: Int = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Vortex - - This indicator attempts to capture positive and negative trend movement - using two oscillators. - - Sources: - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:vortex_indicator) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - length = v_pos_default(length, 14) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - _length = max(length, min_periods) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - tr = true_range(high=high, low=low, close=close) - tr_sum = tr.rolling(length, min_periods=min_periods).sum() - - vmp = (high - low.shift(drift)).abs() - vmm = (low - high.shift(drift)).abs() - - vip = vmp.rolling(length, min_periods=min_periods).sum() / tr_sum - vim = vmm.rolling(length, min_periods=min_periods).sum() / tr_sum - - # Offset - if offset != 0: - vip = vip.shift(offset) - vim = vim.shift(offset) - - # Fill - if "fillna" in kwargs: - vip.fillna(kwargs["fillna"], inplace=True) - vim.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - vip.name = f"VTXP_{length}" - vim.name = f"VTXM_{length}" - vip.category = vim.category = "trend" - - data = {vip.name: vip, vim.name: vim} - df = DataFrame(data, index=close.index) - df.name = f"VTX_{length}" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/trend/zigzag.py b/src/aiomql/ta_libs/pandas_ta/trend/zigzag.py deleted file mode 100644 index e4de67a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/trend/zigzag.py +++ /dev/null @@ -1,335 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import floor, isnan, nan, zeros, zeros_like, roll -from numba import njit -from pandas import Series, DataFrame -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import ( - v_bool, - v_offset, - v_pos_default, - v_series, -) - - -# Find high and low pivots using a centered rolling window. -@njit(cache=True) -def nb_rolling_hl(np_high, np_low, window_size): - idx = zeros_like(np_high) - swing = zeros_like(np_high) # where a high = 1 and low = -1 - value = zeros_like(np_high) - - extremes = 0 - left = int(floor(window_size / 2)) - right = left + 1 - # sample_array = [*[left-window], *[center], *[right-window]] - - m = np_high.size - for i in range(left, m - right): - low_center = np_low[i] - high_center = np_high[i] - low_window = np_low[i - left: i + right] - high_window = np_high[i - left: i + right] - - if (low_center <= low_window).all(): - idx[extremes] = i - swing[extremes] = -1 - value[extremes] = low_center - extremes += 1 - - if (high_center >= high_window).all(): - idx[extremes] = i - swing[extremes] = 1 - value[extremes] = high_center - extremes += 1 - - return idx[:extremes], swing[:extremes], value[:extremes] - - -# Calculate zigzag points using pre-calculated unfiltered pivots. -@njit(cache=True) -def nb_zz_backtest(idx, swing, value, deviation): - zz_idx = zeros_like(idx) - zz_swing = zeros_like(swing) - zz_value = zeros_like(value) - zz_dev = zeros_like(idx) - - zigzags = 0 - changes = 0 - zz_idx[zigzags] = idx[0] - zz_swing[zigzags] = swing[0] - zz_value[zigzags] = value[0] - zz_dev[zigzags] = 0 - - # print(f'Starting S: {zz_swing[0]}') - - m = idx.size - for i in range(1, m): - last_zz_value = zz_value[zigzags] - current_dev = (value[i] - last_zz_value) / last_zz_value - - # print(f'{i} | P {swing[i]:.0f} : {idx[i]:.0f} , {value[i]}') - # print(f'{len(str(i))*" "} | Last: {zz_swing[zigzags-changes]:.0f} , Dev: %{(current_dev*100):.1f}') - - # Last point in zigzag is bottom - if zz_swing[zigzags-changes] == -1: - if swing[i] == -1: - # If the current pivot is lower than the last ZZ bottom: - # create a new point and log it as a change - if value[i] < zz_value[zigzags]: - if zz_idx[zigzags - changes] == idx[i]: - continue - # print(f'{len(str(i))*" "} | Change -1 : {zz_value[zigzags]} to {value[i]}') - zigzags += 1 - changes += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags] = 100 * current_dev - else: - # If the deviation between pivot and the last ZZ bottom is - # great enough create new ZZ point. - if current_dev > 0.01 * deviation: - if zz_idx[zigzags - changes] == idx[i]: - continue - # print(f'{len(str(i))*" "} | new ZZ 1 {value[i]}') - zigzags += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags] = 100 * current_dev - changes = 0 - - # last point in zigzag is top - else: - if swing[i] == 1: - # If the current pivot is higher than the last ZZ top: - # create a new point and log it as a change - if value[i] > zz_value[zigzags]: - if zz_idx[zigzags - changes] == idx[i]: - continue - # print(f'{len(str(i))*" "} | Change 1 : {zz_value[zigzags]} to {value[i]}') - zigzags += 1 - changes += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags] = 100 * current_dev - else: - # If the deviation between pivot and the last ZZ top is great - # enough create new ZZ point. - if current_dev < -0.01 * deviation: - if zz_idx[zigzags - changes] == idx[i]: - continue - # print(f'{len(str(i))*" "} | new ZZ -1 {value[i]}') - zigzags += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags] = 100 * current_dev - changes = 0 - - _n = zigzags + 1 - return zz_idx[:_n], zz_swing[:_n], zz_value[:_n], zz_dev[:_n] - - -# Calculate zigzag points using pre-calculated unfiltered pivots. -@njit(cache=True) -def nb_find_zz(idx, swing, value, deviation): - zz_idx = zeros_like(idx) - zz_swing = zeros_like(swing) - zz_value = zeros_like(value) - zz_dev = zeros_like(idx) - - zigzags = 0 - zz_idx[zigzags] = idx[-1] - zz_swing[zigzags] = swing[-1] - zz_value[zigzags] = value[-1] - zz_dev[zigzags] = 0 - - m = idx.size - for i in range(m - 2, -1, -1): - # Next point in zigzag is bottom - if zz_swing[zigzags] == -1: - if swing[i] == -1: - # If the current pivot is lower than the next ZZ bottom in - # time, move it to the pivot. As this lower value invalidates - # the other one - if value[i] < zz_value[zigzags] and zigzags > 1: - current_dev = (zz_value[zigzags - 1] - value[i]) / value[i] - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags - 1] = 100 * current_dev - else: - # If the deviation between pivot and the next ZZ bottom is - # great enough create new ZZ point. - current_dev = (value[i] - zz_value[zigzags]) / value[i] - if current_dev > 0.01 * deviation: - if zz_idx[zigzags] == idx[i]: - continue - zigzags += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags - 1] = 100 * current_dev - - # Next point in zigzag is top - else: - if swing[i] == 1: - # If the current pivot is greater than the next ZZ top in time, - # move it to the pivot. - # As this higher value invalidates the other one - if value[i] > zz_value[zigzags] and zigzags > 1: - current_dev = (value[i] - zz_value[zigzags - 1]) / value[i] - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags - 1] = 100 * current_dev - else: - # If the deviation between pivot and the next ZZ top is great - # enough create new ZZ point. - current_dev = (zz_value[zigzags] - value[i]) / value[i] - if current_dev > 0.01 * deviation: - if zz_idx[zigzags] == idx[i]: - continue - zigzags += 1 - zz_idx[zigzags] = idx[i] - zz_swing[zigzags] = swing[i] - zz_value[zigzags] = value[i] - zz_dev[zigzags - 1] = 100 * current_dev - - _n = zigzags + 1 - return zz_idx[:_n], zz_swing[:_n], zz_value[:_n], zz_dev[:_n] - - - -# Maps nb_find_zz results back onto the original data indices. -@njit(cache=True) -def nb_map_zz(idx, swing, value, deviation, n): - swing_map = zeros(n) - value_map = zeros(n) - dev_map = zeros(n) - - for j, i in enumerate(idx): - i = int(i) - swing_map[i] = swing[j] - value_map[i] = value[j] - dev_map[i] = deviation[j] - - for i in range(n): - if swing_map[i] == 0: - swing_map[i] = nan - value_map[i] = nan - dev_map[i] = nan - - return swing_map, value_map, dev_map - - - -def zigzag( - high: Series, low: Series, close: Series = None, - legs: int = None, deviation: IntFloat = None, backtest: bool = None, - offset: Int = None, **kwargs: DictLike -): - """Zigzag - - This indicator attempts to filter out smaller movements while identifying - trend direction. It does not predict future trends, but it does identify - swing highs and lows. - - Sources: - * [stockcharts](https://school.stockcharts.com/doku.php?id=technical_indicators:zigzag) - * [tradingview](https://www.tradingview.com/support/solutions/43000591664-zig-zag/#:~:text=Definition,trader%20visual%20the%20price%20action.) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series. Default: ```None``` - legs (int): Number of legs (> 2). Default: ```10``` - deviation (float): Reversal deviation percentage. Default: ```5``` - backtest (bool): Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: Deviation - When ```deviation=10```, it shows movements greater than ```10%```. - - Note: Backtest Mode - Ensures the DataFrame is safe for backtesting. By default, swing - points are returned on the pivot index. Intermediate swings are - not returned at all. This mode swing detection is placed on the bar - that would have been detected. Furthermore, changes in swing levels - are also included instead of only the final value. - - * Use the following formula to get the true index of a pivot: - ```p_i = i - int(floor(legs / 2))``` - - Warning: - A Series reversal will create a new line. - """ - # Validate - legs = v_pos_default(legs, 10) - _length = legs + 1 - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - if close is not None: - close = v_series(close,_length) - np_close = close.values - if close is None: - return - - deviation = v_pos_default(deviation, 5.0) - offset = v_offset(offset) - backtest = v_bool(backtest, False) - - if backtest: - offset+=int(floor(legs/2)) - - # Calculation - np_high, np_low = high.to_numpy(), low.to_numpy() - hli, hls, hlv = nb_rolling_hl(np_high, np_low, legs) - - if backtest: - zzi, zzs, zzv, zzd = nb_zz_backtest(hli, hls, hlv, deviation) - else: - zzi, zzs, zzv, zzd = nb_find_zz(hli, hls, hlv, deviation) - - swing, value, dev = nb_map_zz(zzi, zzs, zzv, zzd, np_high.size) - - # Offset - if offset != 0: - swing = roll(swing, offset) - value = roll(value, offset) - dev = roll(dev, offset) - - swing[:offset] = nan - value[:offset] = nan - dev[:offset] = nan - - # Fill - if "fillna" in kwargs: - swing.fillna(kwargs["fillna"], inplace=True) - value.fillna(kwargs["fillna"], inplace=True) - dev.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{deviation}%_{legs}" - data = { - f"ZIGZAGs{_props}": swing, - f"ZIGZAGv{_props}": value, - f"ZIGZAGd{_props}": dev, - } - df = DataFrame(data, index=high.index) - df.name = f"ZIGZAG{_props}" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/utils/__init__.py b/src/aiomql/ta_libs/pandas_ta/utils/__init__.py deleted file mode 100644 index a27ff5c..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -from ._candles import * -from ._core import * -from ._math import * -from ._numba import * -from ._signals import * -from ._study import * -from ._time import * -from ._validate import * -from ._candles import __all__ as _candles_all -from ._core import __all__ as _core_all -from ._math import __all__ as _math_all -from ._numba import __all__ as _numba_all -from ._signals import __all__ as _signals_all -from ._study import __all__ as _study_all -from ._time import __all__ as _time_all -from ._validate import __all__ as _validate_all - -__all__ = ( - _candles_all - + _core_all - + _math_all - + _numba_all - + _signals_all - + _study_all - + _time_all - + _validate_all -) diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_candles.py b/src/aiomql/ta_libs/pandas_ta/utils/_candles.py deleted file mode 100644 index 84c07ed..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_candles.py +++ /dev/null @@ -1,54 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta.utils._core import non_zero_range - -__all__ = ["candle_color", "high_low_range", "real_body"] - - - -def candle_color(open_: Series, close: Series) -> Series: - """Candle Change - - Checks if ```close >= open_```, if so it returns ```1``` or ```-1```. - - Parameters: - open_ (pd.Series): ```open``` Series - close (pd.Series): ```close``` Series - - Returns: - (pd.Series): 1 column - """ - color = close.copy().astype(int) - color[close >= open_] = 1 - color[close < open_] = -1 - return color - - -def high_low_range(high: Series, low: Series) -> Series: - """High Low Range - - Calculates the difference between ```high`` and ```low```. - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - - Returns: - (pd.Series): 1 column - """ - return non_zero_range(high, low) - - -def real_body(open_: Series, close: Series) -> Series: - """Body Range - - Calculates the difference between ```close`` and ```open_```. - - Parameters: - open_ (pd.Series): ```open``` Series - close (pd.Series): ```close``` Series - - Returns: - (pd.Series): 1 column - """ - return non_zero_range(close, open_) diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_core.py b/src/aiomql/ta_libs/pandas_ta/utils/_core.py deleted file mode 100644 index c6eb396..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_core.py +++ /dev/null @@ -1,400 +0,0 @@ -# -*- coding: utf-8 -*- -import re as re_ -from contextlib import redirect_stdout -from io import StringIO -from sys import float_info as sflt -from webbrowser import open as webbrowser_open - -from numpy import argmax, argmin, float64 -from numba import njit -from pandas import DataFrame, Series - -from pandas_ta._typing import Array, Int, IntFloat, ListStr, TextIO, Union -import pandas_ta.custom as custom -from pandas_ta.utils._validate import v_bool, v_pos_default, v_series, v_str -from pandas_ta.maps import Category, Imports - -__all__ = [ - "camelCase2Title", - "category_files", - "help", - "ms2secs", - "non_zero_range", - "recent_maximum_index", - "recent_minimum_index", - "pd_rma", - "signed_series", - "simplify_columns", - "speed_test", - "tal_ma", - "unsigned_differences", -] - - - -def camelCase2Title(x: str) -> str | None: - """camelCase2Title - - Converts Camel Case to Title - - Parameters: - x (str): Input string. - - Sources: - * [stackoverflow](https://stackoverflow.com/questions/5020906/python-convert-camel-case-to-space-delimited-using-regex-and-taking-acronyms-in) - - Returns: - (str | None): Title Case string or None - """ - if isinstance(x, str) and len(x): - return re_.sub("([a-z])([A-Z])",r"\g<1> \g<2>", x).title() - return None - - -def category_files(category: str) -> list: - """Category Files - - Helper function to return all filenames in the category directory. - - Parameters: - category (str): String name of a Indicator Category - - Returns: - (list): List of filenames of Category - """ - files = [ - x.stem - for x in list(Path(f"pandas_ta/{category}/").glob("*.py")) - if x.stem != "__init__" - ] - return files - - -def help(s: str) -> None | TextIO: - s = v_str(s, "") - - _categories = list(Category.keys()) - _dataframes = ["pandas", "dataframe", "extension"] - _events = ["events", "signals"] - _features = ["bugs", "features", "contributing"] - _help = ["help", "support"] - _how2 = ["how2", "how to", "usage"] - _mp = ["custom", "multiprocessing"] - _studies = ["study", "studies"] - KEYWORDS = _dataframes + _events + _features + _help \ - + _how2 + _studies + _categories + _mp - - www = "https://www.pandas-ta.dev" - if s == "": - out = f'\nSearch words:\n\t{", ".join(sorted(KEYWORDS))}\n' - out += '\nExample: df.ta.help("usage")' - # print(f'\nSearch words:\n\t{", ".join(sorted(KEYWORDS))}\n\nExample: df.ta.help("usage")') - print(out) - elif s in _categories: - webbrowser_open(f"{www}/api/{s.lower()}", new=1) - elif s in _dataframes: - webbrowser_open(f"{www}/api/ta", new=1) - elif s in _events: - webbrowser_open(f"{www}/api/events", new=1) - elif s in _features: - webbrowser_open(f"{www}/support/bugs-and-features", new=1) - elif s in _help: - webbrowser_open(f"{www}/support", new=1) - elif s in _how2: - webbrowser_open(f"{www}/support/how-to", new=1) - elif s in _mp: - webbrowser_open(f"{www}/getting-started/usage", new=1) - elif s in _studies: - webbrowser_open(f"{www}/api/studies", new=1) - else: - webbrowser_open(f"{www}", new=1) - - -def ms2secs(ms, p: Int) -> IntFloat: - return round(0.001 * ms, p) - - -def non_zero_range(x: Series, y: Series) -> Series: - """Non-Zero Range - - Calculates the difference of two Series plus epsilon to any zero values. - - Parameters: - x (Series): Series of 'x's - y (Series): Series of 'y's - - Returns: - (Series): Value of ```x - y + epsilon``` per bar. - """ - diff = x - y - if diff.eq(0).any().any(): - diff += sflt.epsilon - return diff - - -def recent_maximum_index(x) -> Int: - """Recent Maximum Index - - Index of the largest value in ```x``` - - Paramters: - x (Series): ```x``` values - - Returns: - (int): Index of the largest value - """ - return int(argmax(x[::-1])) - - -def recent_minimum_index(x) -> Int: - """Recent Minimum Index - - Index of the smallest value in ```x``` - - Paramters: - x (Series): ```x``` values - - Returns: - (int): Index of the smallest value - """ - return int(argmin(x[::-1])) - - -def pd_rma(x: Series, n: Int) -> Series: - """RMA (Pandas) - - Pandas Implementation of RMA. - - Parameters: - x (Series): ```x``` Series - n (Int): Bars of lookback. Default: ```0.5``` - - Returns: - (Series): RMA - """ - x = v_series(x) - if x is None: - return - a = (1.0 / n) if n > 0 else 0.5 - return x.ewm(alpha=a, min_periods=n).mean() - - -def signed_series(x: Series, initial: Int, lag: Int = None) -> Series: - """Signed Series - - Returns a Signed Series with or without an initial value - - Parameters: - x (Series): Series of 'x's - initial (int): Set inital values of the signed Series. - lag (int): Difference between adjacent items. Default: ```1``` - - Return: - (Series): Signed Series - """ - initial = None - if initial is not None and not isinstance(lag, str): - initial = initial - x = v_series(x) - lag = v_pos_default(lag, 1) - sign = x.diff(lag) - sign[sign > 0] = 1 - sign[sign < 0] = -1 - sign.iloc[0] = initial # sign.iloc[:lag-1] - return sign - - -def simplify_columns(df: DataFrame, n: Int=3) -> ListStr: - """Simplify Columns - - Helper method for managing columns used by Squeeze and Squeeze Pro. - - Parameters: - df (DataFrame): DataFrame with the columns - n (int): Default: ```3``` - - Returns: - (ListStr): List of string column - """ - df.columns = df.columns.str.lower() - return [c.split("_")[0][n - 1:n] for c in df.columns] - - -def speed_test(df: DataFrame, - only: ListStr = None, excluded: ListStr = None, - top: Int = None, talib: bool = False, - ascending: bool = False, sortby: str = "secs", - gradient: bool = False, places: Int = 5, stats: bool = False, - verbose: bool = False, silent: bool = False - ) -> DataFrame: - """Speed Test - - Given a standard ohlcv DataFrame, the Speed Test calculates the - speed of each indicator of the DataFrame Extension: df.ta.(). - - Parameters: - df (pd.DataFrame): DataFrame with _ohlcv_ columns - only (list): List of indicators to run. Default: ```None``` - excluded (list): List of indicators to exclude. Default: ```None``` - top (Int): Return a DataFrame the 'top' values. Default: ```None``` - talib (bool): Enable TA Lib. Default: ```False``` - ascending (bool): Ascending Order. Default: ```False``` - sortby (str): Options: "ms", "secs". Default: ```"secs"``` - gradient (bool): Returns a DataFrame the 'top' values with gradient - styling. Default: ```False``` - places (Int): Decimal places. Default: ```5``` - stats (bool): Returns a Tuple of two DataFrames. The second tuple - contains Stats on the performance time. Default: ```False``` - verbose (bool): Display more info. Default: ```False``` - silent (bool): Display nothing. Default: ```False``` - - Returns: - (pd.DataFrame): if ```stats=False``` - (pd.DataFrame, pd.DataFrame): if ```stats=True``` - """ - if df.empty: - print(f"[X] No DataFrame") - return - talib = v_bool(talib, False) - top = int(top) if isinstance(top, int) and top > 0 else None - stats = v_bool(stats, False) - verbose = v_bool(verbose, False) - silent = v_bool(silent, False) - - _ichimoku = ["ichimoku"] - if excluded is None and isinstance(only, list) and len(only) > 0: - _indicators = only - elif only is None and isinstance(excluded, list) and len(excluded) > 0: - _indicators = df.ta.indicators(as_list=True, exclude=_ichimoku + excluded) - else: - _indicators = df.ta.indicators(as_list=True, exclude=_ichimoku) - - if len(_indicators) == 0: return None - - _iname = "Indicator" - if verbose: - print() - data = _speed_group(df.copy(), _indicators, talib, _iname, places) - else: - _this = StringIO() - with redirect_stdout(_this): - data = _speed_group(df.copy(), _indicators, talib, _iname, places) - _this.close() - - tdf = DataFrame.from_dict(data) - tdf.set_index(_iname, inplace=True) - tdf.sort_values(by=sortby, ascending=ascending, inplace=True) - - total_timedf = DataFrame( - tdf.describe().loc[['min', '50%', 'mean', 'max']]).T - total_timedf["total"] = tdf.sum(axis=0).T - total_timedf = total_timedf.T - - _div = "=" * 60 - _observations = f" Bars{'[talib]' if talib else ''}: {df.shape[0]}" - _quick_slow = "Quickest" if ascending else "Slowest" - _title = f" {_quick_slow} Indicators" - _perfstats = f"Time Stats:\n{total_timedf}" - if top: - _title = f" {_quick_slow} {top} Indicators [{tdf.shape[0]}]" - tdf = tdf.head(top) - - if not silent: - print(f"\n{_div}\n{_title}\n{_observations}\n{_div}\n{tdf}\n\n{_div}\n{_perfstats}\n\n{_div}\n") - - if isinstance(gradient, bool) and gradient: - return tdf.style.background_gradient("autumn_r"), total_timedf - - if stats: - return tdf, total_timedf - else: - return tdf - - -def tal_ma(name: str) -> Int: - """TA Lib MA - - Helper Function that returns the Enum value for TA Lib's MA Type - - Parameters: - name (str): Abbreivated Name of the Moving Average - - Returns: - (int): The equivalent TA Lib MA Enum value for ```name``` - """ - if Imports["talib"] and isinstance(name, str) and len(name) > 1: - from talib import MA_Type - name = name.lower() - if name == "sma": - return MA_Type.SMA # 0 - elif name == "ema": - return MA_Type.EMA # 1 - elif name == "wma": - return MA_Type.WMA # 2 - elif name == "dema": - return MA_Type.DEMA # 3 - elif name == "tema": - return MA_Type.TEMA # 4 - elif name == "trima": - return MA_Type.TRIMA # 5 - elif name == "kama": - return MA_Type.KAMA # 6 - elif name == "mama": - return MA_Type.MAMA # 7 - elif name == "t3": - return MA_Type.T3 # 8 - return 0 # Default: SMA -> 0 - - -def unsigned_differences( - x: Series, lag: Int = None, asint: bool = None -) -> Union[Series, Series]: - """Unsigned Differences - - Returns two Series, an unsigned positive and unsigned negative series based - on the differences of the original series. The positive series are only the - increases and the negative series are only the decreases. - - Parameters: - x (Series): Series of 'x's - lag (int): Difference between adjacent items. Default: ```1``` - asint (bool): Returns as ```Int```. Default: ```False``` - - Example: - ta.unsigned_differences(Series([3, 2, 2, 1, 1, 5, 6, 6, 7, 5, 3])) - - Returns: - (Union[Series, Series]): Positive Series, Negative Series - """ - asint = v_bool(asint, False) - lag = int(lag) if lag is not None else 1 - negative = x.diff(lag) - negative.fillna(0, inplace=True) - positive = negative.copy() - - positive[positive <= 0] = 0 - positive[positive > 0] = 1 - - negative[negative >= 0] = 0 - negative[negative < 0] = 1 - - if asint: - positive = positive.astype(int) - negative = negative.astype(int) - - return positive, negative - - -def _speed_group( - df: DataFrame, group: ListStr = [], talib: bool = False, - index_name: str = "Indicator", p: Int = 4 - ) -> ListStr: - result = [] - for i in group: - r = df.ta(i, talib=talib, timed=True) - if r is None: - print(f"[S] {i} skipped due to returning None") - continue # ta.pivots() sometimes returns None - ms = float(r.timed.split(" ")[0].split(" ")[0]) - result.append({index_name: i, "ms": ms, "secs": ms2secs(ms, p)}) - return result diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_math.py b/src/aiomql/ta_libs/pandas_ta/utils/_math.py deleted file mode 100644 index a39f467..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_math.py +++ /dev/null @@ -1,792 +0,0 @@ -# -*- coding: utf-8 -*- -from collections.abc import Callable -from functools import reduce -from math import floor as mfloor -from operator import mul -from sys import float_info as sflt - -from numpy import ( - all, append, array, broadcast_to, concatenate, corrcoef, diff, dot, exp, - fabs, float64, full, isnan, log, logical_and, nan, nanmean, - nansum, ndarray, newaxis, ones, pad, seterr, sign, sqrt, sum, triu, zeros -) -from numpy import max as np_max -from numpy import min as np_min -from numpy.lib.stride_tricks import sliding_window_view - -from pandas import DataFrame, Series -from numba import njit -from pandas_ta._typing import ( - Array, - DictLike, - Float, - Int, - IntFloat, - List, - Optional -) -from pandas_ta.maps import Imports -from pandas_ta.utils._validate import ( - v_float, - v_int, - v_lowerbound, - v_offset, - v_pos_default, - v_scalar, - v_series -) - -__all__ = [ - "combination", - "cube", - "consecutive_streak", - "df_error_analysis", - "erf", - "fibonacci", - "geometric_mean", - "hpoly", - "ifisher", - "log_geometric_mean", - "pascals_triangle", - "percent_rank", - "remap", - "strided_window", - "sum_signed_rolling_deltas", - "symmetric_triangle", - "weights", - "zero", -] - - - -def combination( - n: Int = 1, r: Int = 0, - repetition: bool = False, multichoose: bool = False -) -> Int: - """Combination - - Combination computation. - - Sources: - * [stackoverflow](https://stackoverflow.com/questions/4941753/is-there-a-math-ncr-function-in-python) - - Parameters: - n (Int): ```n``` - r (Int): ```r``` - repetition (bool): Apply repetition. - multichoose (bool): Apply multichoose. - - Returns: - (Int): Combination value - - Note: - ```n``` Choose ```r```: ```(n r)``` - """ - n, r = int(fabs(n)), int(fabs(r)) - - if repetition or multichoose: - n = n + r - 1 - - # if r < 0: return None - r = min(n, n - r) - if r == 0: - return 1 - - numerator = reduce(mul, range(n, n - r, -1), 1) - denominator = reduce(mul, range(1, r + 1), 1) - return numerator // denominator - - - -def consecutive_streak(x: Array) -> Array: - """Consecutive Streak - - Computes the streak of consecutive value increases or decreases. - - Parameters: - x (Array): Numpy array. - - Returns: - (Array): Streak array of element changes. - - Note: Logic - Yield an array where each value represents the streak value - for that bar. - - 1. Computes the difference between consecutive values. - 2. Assigns 1 for each positive change, -1 for each negative - change -1 and 0 for no change. - - Note: Streaks - * Positive: Consecutive bars of value increases - * Negative: Consecutive bars of value decreases - * Zero: When direction of the value change reverses - - Example: - ```py - prices = np.array([100, 101, 102, 100, 100, 101, 102, 103]) - result = consecutive_streak(prices) - expected_result = np.array([0, 1, 1, -1, 0, 1, 1, 1]) - np.array_equal(result, expected_result) - ``` - """ - return concatenate(([0], sign(diff(x)))) - - - -def cube( - src: Series, pwr: IntFloat = None, signal_offset: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Cube Transform - - This transform, by John Ehlers, is used to compress Svalues near zero for - a normalized oscillator like the Inverse Fisher Transform. - - In other words, a Power Transform/Function: ```result = src ^ pwr``` - - Sources: - * [rengel8](https://github.com/rengel8) based on Markus K. - (cryptocoinserver)'s source - * "Cycle Analytics for Traders", 2014, by John Ehlers, page 200 - - Parameters: - src (pd.Series): Source - pwr (float): The transform power. Default: ```3``` - signal_offset (int): Signal offset. Default: ```-1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - * Values near ```-1``` and ```1``` are nearly unchanged, whereas - values near zero are reduced. - * Input effects of spectral dilation should have been removed - (i.e. roofing filter). - - """ - # Validate - src = v_series(src) - pwr = v_lowerbound(pwr, 3.0, 3.0, strict=False) - signal_offset = v_int(signal_offset, -1, 0) - offset = v_offset(offset) - - # Calculate - result = src ** pwr - ct = Series(result, index=src.index) - ct_signal = Series(result, index=src.index) - - # Offset - if offset != 0: - ct = ct.shift(offset) - ct_signal = ct_signal.shift(offset) - if signal_offset != 0: - ct = ct.shift(signal_offset) - ct_signal = ct_signal.shift(signal_offset) - - if all(isnan(ct)) and all(isnan(ct_signal)): - return # Emergency Break - - # Fill - if "fillna" in kwargs: - ct.fillna(kwargs["fillna"], inplace=True) - ct_signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{pwr}_{signal_offset}" - ct.name = f"CUBE{_props}" - ct_signal.name = f"CUBEs{_props}" - ct.category = ct_signal.category = "transform" - - data = {ct.name: ct, ct_signal.name: ct_signal} - df = DataFrame(data, index=src.index) - df.name = f"CUBE{_props}" - df.category = ct.category - - return df - - - -def erf(x: IntFloat) -> Float: - """Error Function - - Computes the erf(x) - - Sources: - * Handbook of Mathematical Functions, formula 7.1.26. - * [stackoverflow](https://stackoverflow.com/questions/457408/is-there-an-easily-available-implementation-of-erf-for-python) - - Parameters: - x (IntFloat): ```x``` value. - - Returns: - (Float): Error value - """ - x_sign = sign(x) - x = abs(x) - - # constants - a1 = 0.254829592 - a2 = -0.284496736 - a3 = 1.421413741 - a4 = -1.453152027 - a5 = 1.061405429 - p = 0.3275911 - - # A&S formula 7.1.26 - t = 1.0 / (1.0 + p * x) - y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) - * t + a1) * t * exp(-x * x) - return x_sign * y # erf(-x) = -erf(x) - - - -@njit(cache=True) -def fibonacci(n: Int = 2, weighted: bool = False) -> Array: - """Fibonacci - - Computes Fibonacci values using it's closed form. - - Parameters: - n (Int): Number of terms (n >= 2) - weighted (bool): Return weighted version. - - Returns: - (Array): Numpy array results - """ - n = n if n > 1 else 2 - sqrt5 = sqrt(5.0) - phi, psi = 0.5 * (1.0 + sqrt5), 0.5 * (1.0 - sqrt5) - - result = zeros(n) - for i in range(0, n): - result[i] = float(phi ** (i + 1) - psi ** (i + 1)) / sqrt5 - - if weighted: - return result / result.sum() - return result - - - -def geometric_mean(x: Series) -> Float: - """Geometric Mean - - Computes the Geometric Mean of positive values. - - Parameters: - x (Series): Values - - Returns: - (Float): Geometric Mean - """ - n = x.size - if n < 1: - return x.iloc[0] - - has_zeros = 0 in x.to_numpy() - if has_zeros: - x = x.fillna(0) + 1 - if all(x > 0): - mean = x.prod() ** (1 / n) - return mean if not has_zeros else mean - 1 - return 0 - - - -def hpoly(x: Array, v: IntFloat) -> Float: - """Horner's Polynomial - - Evaluates a polynomial with an array of polynomial coefficients, ```x```, - and a value, ```v```, using Horner's Calculation for Polynomial - Evaluation. - - Parameters: - x (Array): Polynomial coefficients as ```np.array``` - v (IntFloat): Value - - Tip: Performance - Use a ```np.array``` for best performance. - - Example: - ```py - coeffs_0 = [4, -3, 0, 1] # 4x^3 - 3x^2 + 0x + 1 - coeffs_1 = np.array(coeffs_0) # Faster - coeffs_2 = pd.Series(coeffs_0).to_numpy() - x = -6.5 - - hpoly(coeffs_0, x) => -1224.25 - hpoly(coeffs_1, x) or hpoly(coeffs_2, x) => -1224.25 # Faster - ``` - """ - if not isinstance(x, ndarray): - x = array(x) - - m, y = x.size, x[0] - - for i in range(1, m): - y = x[i] + v * y - return y - - - -def ifisher( - x: Series, - amp: IntFloat = None, signal_offset: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Inverse Fisher Transform - - This transform function, by John Ehlers, attempts to create clearer - signals by changing the Probability Distribution Function (pdf) for the - results of known oscillator-indicators. - - Sources: - * [rengel8](https://github.com/rengel8) based on Markus K. - (cryptocoinserver)'s source - * "Cycle Analytics for Traders", 2014, by John Ehlers, page 198 - * [mesasoftware](https://www.mesasoftware.com/papers/TheInverseFisherTransform.pdf) - - Parameters: - x (pd.Series): Normalized to range ```[-1, 1]``` - amp (float): Amplifier. Default: ```1``` - signal_offset (int): Signal line offset. Default: ```-1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - * Normalized input, ```x```, with range ```[-1, 1]``` - * Data range of ```[-0.5, 0.5]``` would not have a significant impact - - Example: Preparation Examples - Or use _ta.remap()_ function to prep - - (RSI - 50) * 0.1 RSI [0 to 100] -> -5 to 5 - - (RSI - 50) * 0.02 RSI [0 to 100] -> -1 to 1 (use amp of 5 to match input of example above) - """ - # Validate - x = v_series(x) - amp = v_scalar(amp, 1.0) - signal_offset = v_int(signal_offset, -1, 0) - offset = v_offset(offset) - - # Calculate - np_x = x.to_numpy() - is_remapped = logical_and(np_x >= -1, np_x <= 1) - if not all(is_remapped): - _np_max, _np_min = np_max(np_x), np_min(np_x) - x_map = remap(x, - from_min=_np_min, from_max=_np_max, - to_min=-1, to_max=1 - ) - if x_map is None or all(isnan(x_map.to_numpy())): - return # Emergency Break - np_x = x_map.to_numpy() - - amped = exp(amp * np_x) - result = (amped - 1) / (amped + 1) - - inv_fisher = Series(result, index=x.index) - signal = Series(result, index=x.index) - - # Offset - if offset != 0: - inv_fisher = inv_fisher.shift(offset) - signal = signal.shift(offset) - - if signal_offset != 0: - inv_fisher = inv_fisher.shift(offset) - signal = signal.shift(offset) - - # Fill - if "fillna" in kwargs: - inv_fisher.fillna(kwargs["fillna"], inplace=True) - signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{amp}" - inv_fisher.name = f"INVFISHER{_props}" - signal.name = f"INVFISHERs{_props}" - - data = {inv_fisher.name: inv_fisher, signal.name: signal} - df = DataFrame(data, index=x.index) - df.name = f"INVFISHER{_props}" - - return df - - - -def log_geometric_mean(x: Series) -> Float: - """Logarithmic Geometric Mean - - Computes the Logarithmic Geometric Mean of positive values. - - Parameters: - x (Series): Values - - Returns: - (Float): LogGeometric Mean or zero - """ - n = x.size - if n > 1: - x = x.fillna(0) + 1 - if all(x > 0): - return exp(log(x).sum() / n) - 1 - return 0 - - - -def pascals_triangle( - n: Int = None, inverse: bool = False, weighted: bool = False -) -> Array: - """Pascal's Triangle - - The ```n```th row of Pascal's Triangle. - - Parameters: - n (Int): ```n^th``` row of Pascal' Triange - inverse (bool): Return Inverse weighted. - weighted (bool): Return weighted. - - Returns: - (Array): Classical, Weighted, or Inversely - - Example: - ```py - # Classical - pt4 = pascals_triangle(4) - # pt4 = [1, 4, 6, 4, 1] - - # Inverse - invpt4 = pascals_triangle(4, inverse=True) - # invpt4 = [0.9375, 0.75, 0.625, 0.75, 0.9375] - - # Weighted - wpt4 = pascals_triangle(4, weighted=True) - # wpt4 = [0.0625, 0.25, 0.375, 0.25, 0.0625] - ``` - """ - n = int(fabs(n)) if n is not None else 0 - - # Calculation - triangle = array([combination(n=n, r=i) for i in range(0, n + 1)]) - triangle_sum = sum(triangle) - triangle_weights = triangle / triangle_sum - inverse_weights = 1 - triangle_weights - - if weighted and inverse: - return inverse_weights - if weighted: - return triangle_weights - if inverse: - return None - - return triangle - - - -def percent_rank(x: Series, length: int) -> Series: - """Percent Rank - - Percent Rank of values over a specified length. - - Parameters: - x (Series): ```x``` values - length (int): The period. - - Returns: - (Series): Percent Rank values. - - Note: Logic - Yield a Series where the initial part (up to ```length - 1```) is - padded with NaNs, and the rest contains the Percent Rank values. - - 1. Computes the daily percentage returns. - 2. Creates a rolling window of these returns. - 3. Compares each value in the window to the current value (the - last value in each window). - 4. Percent Rank is calculated as the percentage of values in each - window that are less than the current value. - - Example: - ```py - x = Series([100, 80, 75, 123, 140, 80, 70, 40, 100, 120]).to_numpy() - result = percent_rank(x, 3) - expected_result = Series([np.nan, np.nan, np.nan, 66.666667, 66.666667, 0.0, 33.333333, 0.0, 100.0, 66.666667]) - np.allclose(result, expected_result, rtol=1e-6, equal_nan=True) - ``` - """ - np_pctchg = x.pct_change().to_numpy() - - rws = sliding_window_view(np_pctchg, window_shape=(length + 1,)) - comparison_matrix = rws[:, :-1] < rws[:, -1, newaxis] - - prs = 100 * nanmean(comparison_matrix, axis=1) - result = full(len(x), nan) - result[length:] = prs - - # return Series(padded_percent_ranks, index=x.index) - return result - - - -def remap( - x: Series, from_min: IntFloat = None, from_max: IntFloat = None, - to_min: IntFloat = None, to_max: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """remap - - The standard method of transforming from a source range to a target range - using Max-Min. Useful for bounded sources; not unbounded sources - like _ohlcv_ data. - - Sources: - * Linear (Max-Min) Normalization - - Parameters: - x (pd.Series): Series of 'x's - from_min (IntFloat): Input minimum. Default: ```0.0``` - from_max (IntFloat): Input maximum. Default: ```100.0``` - to_min (IntFloat): Output minimum. Default: ```0.0``` - to_max (IntFloat): Output maximum. Default: ```100.0``` - offset (Int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - x = v_series(x) - from_min = v_float(from_min, 0.0, 0.0) - from_max = v_float(from_max, 100.0, 0.0) - to_min = v_float(to_min, -1.0, 0.0) - to_max = v_float(to_max, 1.0, 0.0) - offset = v_offset(offset) - - # Calculate - frange, trange = from_max - from_min, to_max - to_min - if frange <= 0 or trange <= 0: - return - result = to_min + (trange / frange) * (x.to_numpy() - from_min) - result = Series(result, index=x.index) - - # Offset - if offset != 0: - result = result.shift(offset) - - # Fill - if "fillna" in kwargs: - result.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - result.name = f"REMAP_{from_min}_{from_max}_{to_min}_{to_max}" - # result.name = f"{x.name}_{from_min}_{from_max}_{to_min}_{to_max}" # OR - - return result - - - -def strided_window(x: Array, length: Int) -> Array: - """Strided Window - - Creates a strided window view. - - Source: - * [numpy](https://numpy.org/devdocs/reference/generated/numpy.lib.stride_tricks.as_strided.html) - * [Issue #285](https://github.com/twopirllc/pandas-ta/issues/285) - - Parameters: - x (Array): Source - length (Int): Window period. - - Returns: - (Array): Numpy Array of Strided Window Arrays - - Warning: - Use if necessary, otherwise avoid when possible! - """ - from numpy.lib.stride_tricks import as_strided - strides = x.strides + (x.strides[-1],) - shape = x.shape[:-1] + (x.shape[-1] - length + 1, length) - return as_strided(x, shape=shape, strides=strides, writeable=False) - - - -def sum_signed_rolling_deltas( - open_: Series, close: Series, length: Int, exclusive: bool = True -) -> Series: - """Sum of Signed Rolling Series Deltas - - Calculates the sum of signed differences between the current closing bar - and a rolling window of preceding opening bars. This sum is then padded - to match the original series length. - - Parameters: - open_ (pd.Series): ```open``` Series - close (pd.Series): ```close``` Series - length (Int): Window length. Default: ```4``` - exclusive (bool): Exclusive rolling window. Inclusive rolling window - when ```False```. Default: ```True``` - - Returns: - (pd.Series): 1 column - - Notes: Mode - **Exclusive**: Rolling window excludes the current bar in the - lookback period. - - **Inclusive**: Rolling window includes the current bar in the - lookback period. - - Example: - ```py - open_ = Series([95, 83, 71, 132, 129, 145, 133, 101, 68, 96]) - close = Series([100, 110, 140, 80, 90, 60, 50, 40, 90, 110]) - - result = sum_signed_rolling_deltas(close, open_, 4, exclusive=True) - expected_result = Series([np.nan, np.nan, np.nan, np.nan, 0.0, -4.0, -4.0, -4.0, -4.0, 0.0]) - np.allclose(result, expected_result, rtol=1e-6, equal_nan=True) - - result = sum_signed_rolling_deltas(close, open_, 4, exclusive=False) - expected_result = Series([np.nan, np.nan, np.nan, -1.0, 1.0, -3.0, -3.0, -3.0, -3.0, 1.0]) - np.allclose(result, expected_result, rtol=1e-6, equal_nan=True) - ``` - """ - length = v_pos_default(length, 4) - if not exclusive: - length -= 1 - - rolling_open = sliding_window_view(open_, window_shape=length)[:-1] - - close_broadcasted = broadcast_to( - close[length:].to_numpy()[:, newaxis], rolling_open.shape - ) - - signed_deltas = sign(close_broadcasted - rolling_open) - sum_signed_deltas = nansum(signed_deltas, axis=1).astype(float) - - return Series( - pad(sum_signed_deltas, (length, 0), mode="constant", constant_values=nan), - index=close.index, - ) - - -def symmetric_triangle( - n: Int = None, weighted: bool = False -) -> List[IntFloat]: - """Symmetric Triangle - - Symmetric Triangle creation - - Parameters: - n (Int): Array return size - weighted (bool): Return weighted. - - Returns: - (List[IntFloat]): List of Symmetric Triangle values. - - Example: - ```py - # Default - symt4 = ta.symmetric_triangle(4) - # symt4 = [1, 2, 2, 1] - - # Weighted - wsymt4 = ta.symmetric_triangle(4, weighted=True) - # wsymt4 = [0.16666667 0.33333333 0.33333333 0.16666667] - ``` - """ - n = int(fabs(n)) if n is not None else 2 - - triangle = None - if n == 2: - triangle = [1, 1] - - if n > 2: - if n % 2 == 0: - front = [i + 1 for i in range(0, mfloor(n / 2))] - triangle = front + front[::-1] - else: - front = [i + 1 for i in range(0, mfloor(0.5 * (n + 1)))] - triangle = front.copy() - front.pop() - triangle += front[::-1] - - if weighted and isinstance(triangle, list): - return triangle / sum(triangle) - - return triangle - - - -def weights(w: Array) -> Callable: - """Weights - - Prepares weights for the dot product - - Parameters: - w (Array): Input - - Returns: - (Callable): Weights function for dot product. - """ - def _dot(x): - return dot(w, x) - return _dot - - - -def zero(x: IntFloat) -> IntFloat: - """Zero - - Zeros inputs near zero. - - Parameters: - x (IntFloat): Value to attempt to zero - - Returns: - (IntFloat): ```0``` or ```x``` - """ - return 0 if abs(x) < sflt.epsilon else x - - - -# TESTING - - - -def df_error_analysis( - A: DataFrame, B: DataFrame, - plot: bool = False, triangular: bool = False, - method: str = "pearson", -) -> DataFrame: - """DataFrame Correlation Analysis""" - _r_method = ["pearson", "kendall", "spearman"] - corr_method = method if method in _r_method else _r_method[0] - - # Find their differences and correlation - diff = A - B - result = A.corr(B, method=corr_method) - - # For plotting - if plot: - diff.hist() - if diff[diff > 0].any(): - diff.plot(kind="kde") - - if triangular: - return result.where(triu(ones(result.shape)).astype(bool)) - - return result diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_numba.py b/src/aiomql/ta_libs/pandas_ta/utils/_numba.py deleted file mode 100644 index c68635a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_numba.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import ( - append, - arange, - array, - concatenate, - empty_like, - finfo, - float64, - int64, - isnan, - maximum, - nan, - roll, - where, - zeros_like -) -from numba import njit - -from pandas_ta._typing import Array, Int, IntFloat - -__all__ = [ - "nb_ffill", - "nb_idiff", - "nb_nonzero_range", - "nb_prenan", - "nb_prepend", - "nb_rolling", - "nb_shift", -] - - - -# Numba version of ffill() -@njit(cache=True) -def nb_ffill(x): - mask = isnan(x) - idx = zeros_like(mask, dtype=int64) - last_valid_idx = -1 - - m = mask.size - for i in range(m): - if not mask[i]: - last_valid_idx = i - idx[i] = last_valid_idx - return x[idx] - - -# Indexwise element difference by k indices of array x. -# Similar to Pandas Series/DataFrame diff() -@njit(cache=True) -def nb_idiff(x, k): - n, k = x.size, int(k) - result = zeros_like(x, dtype=float64) - - for i in range(k, n): - result[i] = x[i] - x[i - k] - result[:k] = nan - - return result - - -# Returns the difference of two series and adds epsilon to any zero values. -# This occurs commonly in crypto data when 'high' = 'low'.""" -@njit(cache=True) -def nb_nonzero_range(x, y): - diff = x - y - if diff.any() == 0: - diff += finfo(float64).eps - return diff - - -# Prepend n values, typically np.nan, to array x. -@njit(cache=True) -def nb_prenan(x, n, value = nan): - if n > 0: - x[:n - 1] = value - return x - return x - - -# Prepend n values, typically np.nan, to array x. -@njit(cache=True) -def nb_prepend(x, n, value = nan): - return append(array([value] * n), x) - -# Prepend n values, typically np.nan, to array x. -# @njit(cache=True) -# def nb_prepend2(x, n, value = nan): - # return concatenate(array([value] * n), x) - - -# Like Pandas Rolling Window. x.rolling(n).fn() -@njit(cache=True) -def nb_rolling(x, n, fn = None): - if fn is None: - return x - m = x.size - result = zeros_like(x, dtype=float) - if n <= 0: - return result # TODO: Handle negative rolling windows - - for i in range(0, m): - result[i] = fn(x[i:n + i]) - result = roll(result, n - 1) - result[:n - 1] = nan - return result - - -# np shift -# shift5 - preallocate empty array and assign slice by chrisaycock -# https://stackoverflow.com/questions/30399534/shift-elements-in-a-numpy-array -@njit(cache=True) -def nb_shift(x, n, value = nan): - result = empty_like(x) - if n > 0: - result[:n] = value - result[n:] = x[:-n] - elif n < 0: - result[n:] = value - result[:n] = x[-n:] - else: - result[:] = x - return result - - -# Uncategorized -# @njit(cache=True) -# def nb_roofing_filter(x: Array, n: Int, k: Int, pi: Float, sqrt2: Float): -# """Ehlers's Roofing Filter (INCOMPLETE) -# http://traders.com/documentation/feedbk_docs/2014/01/traderstips.html""" -# m, hp = x.size, np.copy(x) -# # a = exp(-pi * sqrt(2) / n) -# # b = 2 * a * cos(180 * sqrt(2) / n) -# rsqrt2 = 1 / np.sqrt2 -# a = (np.cos(rsqrt2 * 360 / n) + np.sin(rsqrt2 * 360 / n) - 1) -# a /= np.cos(rsqrt2 * 360 / n) -# b, c = 1 - a, (1 - a / 2) - -# for i in range(2, m): -# hp = c * c * (x[i] - 2 * x[i - 1] + x[i - 2]) \ -# + 2 * b * hp[i - 1] - b * b * hp[i - 2] - -# result = nb_ssf(hp, k, pi, rsqrt2) -# return result diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_signals.py b/src/aiomql/ta_libs/pandas_ta/utils/_signals.py deleted file mode 100644 index ef4eb95..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_signals.py +++ /dev/null @@ -1,623 +0,0 @@ -# -*- coding: utf-8 -*- -from functools import partial - -from numpy import nan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat, Union -from pandas_ta.utils._math import zero -from pandas_ta.utils._validate import ( - v_bool, - v_drift, - v_float, - v_int, - v_offset, - v_series -) - - - -__all__ = [ - "above", - "above_value", - "below", - "below_value", - "cross", - "cross_value", - "signals", - "tsignals", - "xsignals" -] - - - -def above( - x: Series, y: Series, asint: bool = True, offset: Int = None, **kwargs -) -> Series: - """Above - - Determines if each ```x``` value is above (or ```>=```) each ```y``` value. - - Parameters: - x (Series): ```x``` - y (Series): ```y``` - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): State where ```x >= y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - y = Series([1, 1, 1, 1, 1]) - - x_above_y = ta.above(x, y) - # x_above_y = Series([1, 1, 0, 0, 1]) - ``` - """ - return partial(_above_below, above=True)(x, y, asint=asint, offset=offset, **kwargs) - - -def above_value( - x: Series, value: IntFloat, asint: bool = True, - offset: Int = None, **kwargs -) -> Series: - """Above Value - - Determines if each ```x``` value is above (or ```>=```) a - constant ```value```. - - Parameters: - x (Series): ```x``` - value (IntFloat): Value to compare with ```x```. - asint (bool): Returns as ```Int```. - - Returns: - (Series): State where ```x >= y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - x_above_1 = ta.above_value(x, 1) - # x_above_1 = Series([1, 1, 0, 0, 1]) - ``` - """ - if not isinstance(value, (int, float)): - print("[X] value is not a number") - return - y = Series(value, index=x.index, name=f"{value}".replace(".", "_")) - return partial(_above_below, above=True)(x, y, asint=asint, offset=offset, **kwargs) - - -def below( - x: Series, y: Series, asint: bool = True, offset: Int = None, **kwargs -) -> Series: - """Below - - Determines if each ```x``` value is below (or ```<=```) each ```y``` value. - - Parameters: - x (Series): ```x``` - y (Series): ```y``` - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): State where ```x <= y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - y = Series([1, 1, 1, 1, 1]) - - x_below_y = ta.below(x, y) - # x_below_y = Series([0, 0, 1, 1, 1]) - ``` - """ - return partial(_above_below, above=False)(x, y, asint=asint, offset=offset, **kwargs) - - -def below_value( - x: Series, value: IntFloat, asint: bool = True, - offset: Int = None, **kwargs -) -> Series: - """Below Value - - Determines if each ```x``` value is below (or ```<=```) a - constant ```value```. - - Parameters: - x (Series): ```x``` - value (IntFloat): Value to compare with ```x```. - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): State where ```x <= y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - x_below_1 = ta.below_value(x, 1) - # x_below_1 = Series([0, 0, 1, 1, 1]) - ``` - """ - if not isinstance(value, (int, float)): - print("[X] value is not a number") - return - y = Series(value, index=x.index, name=f"{value}".replace(".", "_")) - return partial(_above_below, above=False)(x, y, asint=asint, offset=offset, **kwargs) - - -def cross( - x: Series, y: Series, - above: bool = True, equal: bool = True, - asint: bool = True, offset: Int = None, - **kwargs: DictLike -) -> Series: - """Cross - - Determines where ```x``` crosses ```y```, either _above_ or _below_, - strictly (_equal_) or not. - - Parameters: - x (Series): ```x``` - y (Series): ```y``` - above (bool): Check above. Check below, set ```above=False``` - equal (bool): At least/most, ```=```, check. - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): Values where ```x``` crosses ```y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - y = Series([1, 1, 1, 1, 1]) - - # Cross Above Examples - x_xae_y = ta.cross(x, y, above=True, equal=True) - # x_xae_y = Series([0, 0, 0, 0, 1]) - - x_xa_y = ta.cross(x, y, above=True, equal=False) - # x_xa_y = Series([0, 0, 0, 0, 0]) - - # Cross Below Examples - x_xbe_y = ta.cross(x, y, above=False, equal=True) - # x_xbe_y = Series([0, 0, 1, 0, 1]) - - x_xb_y = ta.cross(x, y, above=False, equal=False) - # x_xb_y = Series([0, 0, 1, 0, 0]) - ``` - """ - # Validate - x = v_series(x) - y = v_series(y) - offset = v_offset(offset) - - x.apply(zero) - y.apply(zero) - - # Calculate - if above: - current = x >= y if equal else x > y - previous = x.shift(1) < y.shift(1) - else: - current = x <= y if equal else x < y - previous = x.shift(1) > y.shift(1) - - cross = current & previous - # ensure there is no cross on the first entry - cross.iloc[0] = False - - if asint: - cross = cross.astype(int) - - # Offset - if offset != 0: - cross = cross.shift(offset) - - # Name and Category - cross.name = f"{x.name}_{'XA' if above else 'XB'}_{y.name}" - cross.category = "signal" - - return cross - - -def cross_value( - x: Series, value: IntFloat, - above: bool = True, equal: bool = True, - asint: bool = True, offset: Int = None, - **kwargs -) -> Series: - """Cross Value - - Determines where ```x``` crosses a constant ```value```, either _above_ - or _below_, strictly (_equal_) or not. - - Parameters: - x (Series): ```x``` - value (IntFloat): Value to compare with ```x```. - above (bool): Check above. Check below, set ```above=False``` - equal (bool): At least/most, ```=```, check. - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): Values where ```x``` crosses ```y```. - - Example: - ```py - x = Series([4, 2, 0, -1, 1]) - - # Cross Above Examples - x_xae_y = ta.cross_value(x, 1, above=True, equal=True) - # x_xae_y = Series([0, 0, 0, 0, 1]) - - x_xa_y = ta.cross_value(x, 1, above=True, equal=False) - # x_xa_y = Series([0, 0, 0, 0, 0]) - - # Cross Below Examples - x_xbe_y = ta.cross_value(x, 1, above=False, equal=True) - # x_xbe_y = Series([0, 0, 1, 0, 1]) - - x_xb_y = ta.cross_value(x, 1, above=False, equal=False) - # x_xb_y = Series([0, 0, 1, 0, 0]) - ``` - """ - y = Series(value, index=x.index, name=f"{value}".replace(".", "_")) - return cross(x, y, above, equal, asint, offset, **kwargs) - - - -def signals( - indicator: Series, xa: IntFloat = None, xb: IntFloat = None, - cross_values: bool = None, xseries: Series = None, - xseries_a: Series = None, xseries_b: Series = None, - cross_series: bool = None, offset: Int = None -) -> DataFrame: - """Signals - - Mulitfuncational signal checker that determines whether an - indicator crosses above/below value or Series. - - Parameters: - indicator (Series): Indicator to check for signal crossings. - cross_values (bool): Check if crossed value. - xseries (Series): Cross Series - xseries_a (Series): Cross Above Series - xseries_b (Series): Cross Below Series - cross_series (bool): Check if crossed ```xseries```. - - Other Parameters: - xa (IntFloat): Crossing above value. - xb (IntFloat): Crossing below value. - offset (Int): Post shift. Default: ```0``` - - Returns: - (DataFrame): 2 columns - - Note: - See sources of: ```er```, ```macd```, ```rsi```, and ```rsx``` - for examples of use. - """ - df = DataFrame() - - if xa is not None and isinstance(xa, (int, float)): - if cross_values: - xa_start = cross_value(indicator, xa, above=True, offset=offset) - xa_end = cross_value(indicator, xa, above=False, offset=offset) - - df[xa_start.name] = xa_start - df[xa_end.name] = xa_end - else: - xd_above = above_value(indicator, xa, offset=offset) - df[xd_above.name] = xd_above - - if xb is not None and isinstance(xb, (int, float)): - if cross_values: - xb_start = cross_value(indicator, xb, above=True, offset=offset) - xb_end = cross_value(indicator, xb, above=False, offset=offset) - - df[xb_start.name] = xb_start - df[xb_end.name] = xb_end - else: - xd_below = below_value(indicator, xb, offset=offset) - df[xd_below.name] = xd_below - - # xseries is the default value for both xseries_a and xseries_b - if xseries_a is None: - xseries_a = xseries - if xseries_b is None: - xseries_b = xseries - - if xseries_a is not None and v_series(xseries_a): - if cross_series: - xsa = cross(indicator, xseries_a, above=True, offset=offset) - else: - xsa = above(indicator, xseries_a, offset=offset) - - df[xsa.name] = xsa - - if xseries_b is not None and v_series(xseries_b): - if cross_series: - xsb = cross(indicator, xseries_b, above=False, offset=offset) - else: - xsb = below(indicator, xseries_b, offset=offset) - - df[xsb.name] = xsb - - return df - - -def _above_below( - x: Series, y: Series, - above: bool = True, asint: bool = True, - offset: Int = None, **kwargs -) -> Series: - """Above / Below - - Determines if ```x``` is above or below ```y```. - - Parameters: - x (Series): ```x``` - y (Series): ```y``` - above (bool): Above check. Below: ```above=False``` - equal (bool): At least/most, ```=```, check. - asint (bool): Returns as ```Int```. - offset (Int): Post shift. Default: ```0``` - - Returns: - (Series): Values where ```x``` values are above/below ```y``` values. - """ - # Verify - x = v_series(x) - y = v_series(y) - offset = v_offset(offset) - - x.apply(zero) - y.apply(zero) - - # Calculate - if above: - current = x >= y - else: - current = x <= y - - if asint: - current = current.astype(int) - - # Offset - if offset != 0: - current = current.shift(offset) - - # Name and Category - current.name = f"{x.name}_{'A' if above else 'B'}_{y.name}" - current.category = "signal" - - return current - - - -def tsignals( - trend: Series, asbool: bool = None, - trade_offset: Int = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Trend Signals - - This function creates Trend, Trades, Entries and Exit values per bar when - given a trend condition e.g. ```trend = close > sma(close, 50)```. - - Source: - * Kevin Johnson - - Parameters: - trend (pd.Series): ```trend``` Series. Boolean or integer values of - ```0``` and ```1``` - asbool (bool): Return booleans. Default: ```False``` - trade_offset (value): Shift trade entries/exits with live: ```0``` and - backesting: ```1```. Default: ```0``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - - Note: Column Detail - * Trends (trend: 1, no trend: 0) - * Trades (Enter: 1, Exit: -1, Otherwise: 0) - * Entries (entry: 1, nothing: 0) - * Exits (exit: 1, nothing: 0) - - Note: Details - A ```trend``` is a state or condition, that is as simple - as ```Close > MA``` or something more complex that has boolean - or integer (trend: 1, no trend: 0) values. - - Tip: VectorBT - * For backtesting, set ```trade_offset=1```. - * Setting ```asbool=True``` is useful for backtesting with vectorbt's - ```Portfolio.from_signal(close, entries, exits)``` method. - - Example: - These are two different outcomes for each (long/short) position and - depends on the source and it's behavior. - - Signals when ```Close > SMA50(Close)``` - - ta.tsignals(close > ta.sma(close, 50), asbool=False) - - Signals when ```EMA(Close, 8) > EMA(Close, 21)``` - - ta.tsignals(ta.ema(close, 8) > ta.ema(close, 21), asbool=True) - - Warning: - Check ALL outcomes BEFORE making an Issue - """ - # Validate - trend = v_series(trend) - if trend is None: - return - - asbool = v_bool(asbool, False) - trade_offset = v_int(trade_offset, 0) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - trends = trend.astype(int) - trades = trends.diff(drift).shift(trade_offset).fillna(0).astype(int) - entries = (trades > 0).astype(int) - exits = (trades < 0).abs().astype(int) - - if asbool: - trends = trends.astype(bool) - entries = entries.astype(bool) - exits = exits.astype(bool) - - data = { - f"TS_Trends": trends, - f"TS_Trades": trades, - f"TS_Entries": entries, - f"TS_Exits": exits, - } - df = DataFrame(data, index=trends.index) - - # Offset - if offset != 0: - df = df.shift(offset) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - df.name = f"TS" - df.category = "trend" - - return df - - - -def xsignals( - source: Series, - xa: Union[IntFloat, Series], - xb: Union[IntFloat, Series], - above: bool = True, long: bool = True, - asbool: bool = None, trade_offset: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Cross Signals - - This function creates Trend, Trades, Entries and Exits values per bar - for crossing events. - - Sources: - * Kevin Johnson - - Parameters: - source (pd.Series): ```source``` Signal - xa (pd.Series): Series the Signal crosses above if ```above=True``` - xb (pd.Series): Series the Signal crosses below if ```above=True``` - above (bool): The ```source``` crossing; below is ```False```. - Default: ```True``` - long (bool): The ```source``` position; short is ```False```. - Default: ```True``` - offset (int): Post shift. Default: ```0``` - asbool (bool): Return booleans. Default: ```False``` - trade_offset (value): Shift trade entries/exits with live: ```0``` and - backesting: ```1```. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - - Note: Column Detail - * Trends (trend: 1, no trend: 0) - * Trades (Enter: 1, Exit: -1, Otherwise: 0) - * Entries (entry: 1, nothing: 0) - * Exits (exit: 1, nothing: 0) - - Tip: VectorBT - * For backtesting, set ```trade_offset=1```. - * Setting ```asbool=True``` is useful for backtesting with vectorbt's - ```Portfolio.from_signal(close, entries, exits)``` method. - - Example: - These are two different outcomes for each (long/short) position and - depends on the source and it's behavior. - - rsi = df.ta.rsi() - - When RSI crosses above 20 and then below 80 in a long position: - - ta.xsignals(source=rsi, xa=20, xb=80, above=True, long=True) - # Simpler - # ta.xsignals(rsi, 20, 80, True, True) - - When RSI crosses below 20 and then above 80 in a long position: - - ta.xsignals(source=rsi, xa=20, xb=80, above=False, long=True) - # Simpler - # ta.xsignals(rsi, 20, 80, False, True) - - * Similarly, short positions (```long=False```) also differ depending - on ```above``` state. - - Warning: - Check ALL parameter combination outcomes BEFORE making an Issue. - """ - # Validate - source = v_series(source) - if source is None: - return - - offset = v_offset(offset) - - # Calculate - if above: - entries = cross_value(source, xa) - exits = -cross_value(source, xb, above=False) - else: - entries = cross_value(source, xa, above=False) - exits = -cross_value(source, xb) - trades = entries + exits - - # Modify trades to fill gaps for trends - trades.replace({0: nan}, inplace=True) - trades.ffill(limit_area="inside", inplace=True) # or trades.bfill(limit_area="inside", inplace=True) - trades.fillna(0, inplace=True) - - trends = (trades > 0).astype(int) - if not long: - trends = 1 - trends - - tskwargs = { - "asbool": asbool, - "trade_offset": trade_offset, - "offset": offset - } - df = tsignals(trends, **tskwargs) - - # Offset handled by tsignals - DataFrame({ - f"XS_LONG": df.TS_Trends, - f"XS_SHORT": 1 - df.TS_Trends - }) - - # Fill - if "fillna" in kwargs: - df.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - df.name = f"XS" - df.category = "trend" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_study.py b/src/aiomql/ta_libs/pandas_ta/utils/_study.py deleted file mode 100644 index dcdfb43..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_study.py +++ /dev/null @@ -1,145 +0,0 @@ -# -*- coding: utf-8 -*- -from multiprocessing import cpu_count -from dataclasses import dataclass, field - -from pandas_ta._typing import Int, List -from pandas_ta.utils._time import get_time - - -__all__ = [ - "Study", - "AllStudy", - "CommonStudy" -] - - - -# Study DataClass -@dataclass -class Study: - """Study DataClass - Class to name and group indicators for processing. - - Parameters: - name (str): Name. - ta (list of dicts): i.e [{"kind": "ema", "length", 50}] - cores (int): The number cores to use for multiprocessing. - Default: ```cpu_count()``` - description (str): Description of what the Study. Default: ```""``` - created (str): DateTime String at creation. - Default: Automatically generated. - - Returns: - (DataClass): The Study to be processed by ```df.ta.study()``` - - Example: All or Common Study - Run - ```py - # All - df.ta.study(ta.AllStudy, **kwargs) - - # Common - df.ta.study(ta.CommonStudy, **kwargs) - ``` - - Example: Custom Study - Create - ```py - DemoStudy = ta.Study( - name="Demo Study", - description="Example Study Group", - cores=0, # Usually faster than multiprocessing - ta = [ - {"kind": "sma", "length": 200}, - {"kind": "sma", "close": "volume", "length": 50}, - {"kind": "bbands", "length": 20}, - {"kind": "rsi"}, - {"kind": "macd", "fast": 8, "slow": 21}, - {"kind": "sma", "close": "volume", "length": 20, "prefix": "VOLUME"} - ] - ``` - - Run - ```py - df.ta.study(DemoStudy, **kwargs) - ``` - - Note: - * See [also](../getting-started/usage.md) the Pandas TA - "Study" Examples - * Case-insensitive "All" is reserved. - - Warning: Multiprocessing - **Not recommended** for: - - * Small sets of indicators - * Indicator chains - """ - name: str - ta: List = field(default_factory=list) - cores: Int = cpu_count() - description: str = "" - created: str = get_time(to_string=True) - - - def __post_init__(self): - if isinstance(self.cores, int) and self.cores >= 0 and self.cores <= cpu_count(): - self.cores = int(self.cores) - - req_args = ["[X] Study requires the following argument(s):"] - - if self._is_name(): - req_args.append( - ' - name. Must be a string. Example: "My TA". Note: "all" is reserved.') - - if self.ta is None: - self.ta = None - elif not self._is_ta(): - s = " - ta. Format is a list of dicts. Example: [{'kind': 'sma', 'length': 10}]" - s += "\n Check the indicator for the correct arguments if you receive this error." - req_args.append(s) - - if len(req_args) > 1: - [print(_) for _ in req_args] - return None - - - def _is_name(self): - return self.name is None or not isinstance(self.name, str) - - - def _is_ta(self): - if isinstance(self.ta, list) and self.total_ta() > 0: - # Check that all elements of the list are dicts. - # Does not check if the dicts values are valid indicator kwargs - # User must check indicator documentation for all indicators args. - return all([isinstance(_, dict) and len(_.keys()) > 0 for _ in self.ta]) - - return False - - - def total_ta(self): - return len(self.ta) if self.ta is not None else 0 - - - -# All Study -AllStudy = Study( - name="All", - description="All the indicators with their default settings. Pandas TA default.", - ta=None, -) - -# Default (Example) Study. -CommonStudy = Study( - name="Common Price and Volume SMAs", - description="Common Price SMAs: 10, 20, 50, 200 and Volume SMA: 20.", - cores=0, - ta=[ - {"kind": "sma", "length": 10}, - {"kind": "sma", "length": 20}, - {"kind": "sma", "length": 50}, - {"kind": "sma", "length": 200}, - {"kind": "sma", "close": "volume", "length": 20, "prefix": "VOL"} - ] -) diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_time.py b/src/aiomql/ta_libs/pandas_ta/utils/_time.py deleted file mode 100644 index 126d572..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_time.py +++ /dev/null @@ -1,152 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from time import localtime, perf_counter - -from pandas import DataFrame, Series, Timestamp, to_datetime -from pandas_ta._typing import Float, MaybeSeriesFrame, Optional, Tuple, Union -from pandas_ta.maps import EXCHANGE_TZ - -__all__ = [ - "df_dates", - "df_month_to_date", - "df_quarter_to_date", - "df_year_to_date", - "final_time", - "get_time", - "mtd", - "qtd", - "to_utc", - "total_time", - "unix_convert", - "ytd", -] - - - -def df_dates( - df: DataFrame, dates: Tuple[str, list] = None -) -> MaybeSeriesFrame: - """Yields the DataFrame with the given dates""" - if dates is None: - return None - if not isinstance(dates, list): - dates = [dates] - return df[df.index.isin(dates)] - - -def df_month_to_date(df: DataFrame) -> DataFrame: - """Yields the Month-to-Date (MTD) DataFrame""" - in_mtd = df.index >= Timestamp.now().strftime("%Y-%m-01") - if any(in_mtd): - return df[in_mtd] - return df - - -def df_quarter_to_date(df: DataFrame) -> DataFrame: - """Yields the Quarter-to-Date (QTD) DataFrame""" - now = Timestamp.now() - for m in [1, 4, 7, 10]: - if now.month <= m: - in_qtr = df.index >= datetime(now.year, m, 1).strftime("%Y-%m-01") - if any(in_qtr): - return df[in_qtr] - return df[df.index >= now.strftime("%Y-%m-01")] - - -def df_year_to_date(df: DataFrame) -> DataFrame: - """Yields the Year-to-Date (YTD) DataFrame""" - in_ytd = df.index >= Timestamp.now().strftime("%Y-01-01") - if any(in_ytd): - return df[in_ytd] - return df - - -def final_time(stime: Float) -> str: - """Human readable elapsed time. Calculates the final time elapsed since - stime and returns a string with microseconds and seconds.""" - time_diff = perf_counter() - stime - return f"{time_diff * 1000:2.4f} ms ({time_diff:2.4f} s)" - - -def get_time( - exchange: str = "NYSE", full: bool = True, to_string: bool = False -) -> Optional[str]: - """Returns Current Time, Day of the Year and Percentage, and the current - time of the selected Exchange.""" - tz = EXCHANGE_TZ["NYSE"] # Default is NYSE (Eastern Time Zone) - if isinstance(exchange, str): - exchange = exchange.upper() - tz = EXCHANGE_TZ[exchange] - - # today = Timestamp.utcnow() - today = Timestamp.now() - date = f"{today.day_name()} {today.month_name()} {today.day}, {today.year}" - - _today = today.timetuple() - exchange_time = f"{(_today.tm_hour + tz) % 24}:{_today.tm_min:02d}:{_today.tm_sec:02d}" - - if full: - lt = localtime() - local_ = f"Local: {lt.tm_hour}:{lt.tm_min:02d}:{lt.tm_sec:02d} {lt.tm_zone}" - doy = f"Day {today.dayofyear}/365 ({100 * round(today.dayofyear/365, 2):.2f}%)" - exchange_ = f"{exchange}: {exchange_time}" - - s = f"{date}, {exchange_}, {local_}, {doy}" - else: - s = f"{date}, {exchange}: {exchange_time}" - - return s if to_string else print(s) - - -def total_time(df: DataFrame, tf: str = "years") -> Float: - """Calculates the total time of a DataFrame. Difference of the Last and - First index. Options: 'months', 'weeks', 'days', 'hours', 'minutes' - and 'seconds'. Default: 'years'. - Useful for annualization.""" - time_diff = df.index[-1] - df.index[0] - TimeFrame = { - "years": time_diff.days / 365.242199074074074, # PR 602 - "months": time_diff.days / 30.417, - "weeks": time_diff.days / 7, - "days": time_diff.days, - "hours": time_diff.days * 24, - "minutes": time_diff.total_seconds() / 60, - "seconds": time_diff.total_seconds() - } - - if isinstance(tf, str) and tf in TimeFrame.keys(): - return TimeFrame[tf] - return TimeFrame["years"] - - -def to_utc(df: DataFrame) -> DataFrame: - """Either localizes the DataFrame Index to UTC or it applies tz_convert to - set the Index to UTC. - """ - if not df.empty: - try: - df.index = df.index.tz_localize("UTC") - except TypeError: - df.index = df.index.tz_convert("UTC") - return df - - -def unix_convert(s: Union[int, Series]) -> Union[datetime, str]: - """unix_convert - - Convert timestamps from Polygon to readable datetime strings. - - Parameters: - s (Union[int, Series]): The timestamp(s). An integer posix timestamp - or a Series of timestamps. - - Returns: - (Union[datetime, str]): Converted datetime - """ - return to_datetime(s, unit="ms") - - -# Aliases -mtd = df_month_to_date -qtd = df_quarter_to_date -ytd = df_year_to_date diff --git a/src/aiomql/ta_libs/pandas_ta/utils/_validate.py b/src/aiomql/ta_libs/pandas_ta/utils/_validate.py deleted file mode 100644 index 98f469e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/utils/_validate.py +++ /dev/null @@ -1,190 +0,0 @@ -# -*- coding: utf-8 -*- -from functools import partial -from pandas import DataFrame, Series, isnull -from pandas.api.types import is_datetime64_any_dtype -from pandas_ta._typing import ( - Float, - Int, - IntFloat, - List, - MaybeSeriesFrame, - Optional, - SeriesFrame, - np_floating, - np_integer -) - -__all__ = [ - "v_ascending", - "v_bool", - "v_dataframe", - "v_datetime_ordered", - "v_drift", - "v_float", - "v_int", - "v_list", - "v_lowerbound", - "v_mamode", - "v_null", - "v_offset", - "v_percent", - "v_pos_default", - "v_scalar", - "v_series", - "v_str", - "v_talib", - "v_tradingview", - "v_upperbound" -] - - - -def v_ascending(var: bool) -> bool: - """Returns True by default""" - return partial(v_bool, default=True)(var=var) - - -def v_bool(var: bool, default: bool = True) -> bool: - """Returns default=True if var is not a bool.""" - if isinstance(var, bool): - return bool(var) - return default - - -def v_dataframe(obj: MaybeSeriesFrame) -> None: - if not isinstance(obj, (DataFrame, Series)): - print("[X] Requires a Pandas Series or DataFrame.") - - -def v_datetime_ordered(df: SeriesFrame) -> bool: - if df.shape[0] < 2: - return False - if is_datetime64_any_dtype(df.index): - np_dt_index = df.index.to_numpy() - if np_dt_index[0] < np_dt_index[-1]: - return True - return False - - -def v_drift(var: Int) -> Int: - """Defaults to 1""" - return partial(v_int, default=1, ne=0)(var=var) - - -def v_float( - var: IntFloat, default: IntFloat, ne: Optional[IntFloat] = 0.0 -) -> Float: - """Returns the default if var is not equal to the ne value.""" - _types = (float, int, np_floating, np_integer) - if isinstance(ne, _types) and isinstance(var, _types): - if float(var) != float(ne): - return float(var) - return float(default) - - -def v_int(var: Int, default: Int, ne: Optional[Int] = 0) -> Int: - """Returns the default if var is not equal to the ne value.""" - if isinstance(var, int) and int(var) != int(ne): - return int(var) - if isinstance(var, np_integer) and var.item() != int(ne): - return var.item() - return int(default) - - -def v_list(var: List, default: List = []) -> List: - """Returns [] if not a valid list""" - if isinstance(var, list) and len(var) > 0: - return var - return default - - -def v_lowerbound( - var: IntFloat, bound: IntFloat = 0, - default: IntFloat = 0, strict: bool = True, complement: bool = False -) -> IntFloat: - """Returns the default if var(iable) not greater(equal) than bound.""" - var_type = None - if isinstance(var, (float, np_floating)): var_type = float - if isinstance(var, (int, np_integer)): var_type = int - - if var_type is None: - return default - - valid = False - if strict: - valid = var_type(var) > var_type(bound) - else: - valid = var_type(var) >= var_type(bound) - - if complement: valid = not valid - - if valid: - return var_type(var) - return default - - -def v_mamode(var: str, default: str) -> str: # Could be an alias. - return v_str(var, default) - - -def v_null(var: IntFloat, default: IntFloat) -> IntFloat: - """Returns the var if not null else returns the default""" - return default if isnull(var) else var - - -def v_offset(var: Int) -> Int: - """Defaults to 0""" - return partial(v_int, default=0, ne=0)(var=var) - - -def v_percent(x: IntFloat) -> bool: - if isinstance(x, (float, int, np_floating, np_integer)): - return x is not None and 0 <= x <= 100 - return False - - -def v_pos_default( - var: IntFloat, default: IntFloat = 0, strict: bool = True, complement: bool = False -) -> IntFloat: - return partial(v_lowerbound, bound=0) \ - (var=var, default=default, strict=strict, complement=complement) - - -def v_scalar(var: IntFloat, default: Optional[IntFloat] = 1) -> Float: - """Returns the default if var is not an IntFloat.""" - if isinstance(var, (float, int, np_floating, np_integer)): - return float(var) - return float(default) - - -def v_series(series: Series, length: Optional[IntFloat] = 0) -> Optional[Series]: - """Returns None if the series does not meet the required minimum length.""" - if series is not None and isinstance(series, Series): - if series.size >= v_pos_default(length, 0): - return series - return None - - -def v_str(var: str, default: str) -> str: - """"Returns the default value if var is not a empty str""" - if isinstance(var, str) and len(var) > 0: - return f"{var}" - return f"{default}" - - -def v_talib(var: bool) -> bool: - """Returns True by default""" - return partial(v_bool, default=True)(var=var) - - -def v_tradingview(var: bool) -> bool: - """Returns True by default""" - return partial(v_bool, default=True)(var=var) - - -def v_upperbound( - var: IntFloat, bound: IntFloat = 0, - default: IntFloat = 0, strict: bool = True -) -> IntFloat: - return partial(v_lowerbound, complement=True)\ - (var=var, bound=bound, default=default, strict=strict) diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/__init__.py b/src/aiomql/ta_libs/pandas_ta/volatility/__init__.py deleted file mode 100644 index 8f804ca..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/__init__.py +++ /dev/null @@ -1,36 +0,0 @@ -# -*- coding: utf-8 -*- -from .aberration import aberration -from .accbands import accbands -from .atr import atr -from .atrts import atrts -from .bbands import bbands -from .chandelier_exit import chandelier_exit -from .donchian import donchian -from .hwc import hwc -from .kc import kc -from .massi import massi -from .natr import natr -from .pdist import pdist -from .rvi import rvi -from .thermo import thermo -from .true_range import true_range -from .ui import ui - -__all__ = [ - "aberration", - "accbands", - "atr", - "atrts", - "bbands", - "chandelier_exit", - "donchian", - "hwc", - "kc", - "massi", - "natr", - "pdist", - "rvi", - "thermo", - "true_range", - "ui", -] diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/aberration.py b/src/aiomql/ta_libs/pandas_ta/volatility/aberration.py deleted file mode 100644 index 102e6d1..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/aberration.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import hlc3, sma -from pandas_ta.utils import v_offset, v_pos_default, v_series -from .atr import atr - - - -def aberration( - high: Series, low: Series, close: Series, - length: Int = None, atr_length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Aberration - - Similar to Keltner Channels. - - Sources: - * [Request #46](https://github.com/twopirllc/pandas-ta/issues/46) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```5``` - atr_length (int): ATR period. Default: ```15``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - """ - # Validate - length = v_pos_default(length, 5) - atr_length = v_pos_default(atr_length, 15) - _length = max(atr_length, length) + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - offset = v_offset(offset) - - # Calculate - atr_ = atr(high=high, low=low, close=close, length=atr_length) - jg = hlc3(high=high, low=low, close=close) - - zg = sma(jg, length) - sg = zg + atr_ - xg = zg - atr_ - - # Offset - if offset != 0: - zg = zg.shift(offset) - sg = sg.shift(offset) - xg = xg.shift(offset) - atr_ = atr_.shift(offset) - - # Fill - if "fillna" in kwargs: - zg.fillna(kwargs["fillna"], inplace=True) - sg.fillna(kwargs["fillna"], inplace=True) - xg.fillna(kwargs["fillna"], inplace=True) - atr_.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{atr_length}" - zg.name = f"ABER_ZG{_props}" - sg.name = f"ABER_SG{_props}" - xg.name = f"ABER_XG{_props}" - atr_.name = f"ABER_ATR{_props}" - zg.category = sg.category = "volatility" - xg.category = atr_.category = zg.category - - data = {zg.name: zg, sg.name: sg, xg.name: xg, atr_.name: atr_} - df = DataFrame(data, index=close.index) - df.name = f"ABER{_props}" - df.category = zg.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/accbands.py b/src/aiomql/ta_libs/pandas_ta/volatility/accbands.py deleted file mode 100644 index 10f504f..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/accbands.py +++ /dev/null @@ -1,93 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.utils import ( - non_zero_range, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def accbands( - high: Series, low: Series, close: Series, length: Int = None, - c: IntFloat = None, drift: Int = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Acceleration Bands - - This indicator, by Price Headley, creates lower and upper bands centered - around a moving average based on a ratio of it's High-Low range. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/acceleration-bands-abands/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```10``` - c (int): Multiplier. Default: ```4``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - length = v_pos_default(length, 20) - high = v_series(high, length) - low = v_series(low, length) - close = v_series(close, length) - - if high is None or low is None or close is None: - return - - c = v_pos_default(c, 4) - mamode = v_mamode(mamode, "sma") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - high_low_range = non_zero_range(high, low) - hl_ratio = high_low_range / (high + low) - hl_ratio *= c - _lower = low * (1 - hl_ratio) - _upper = high * (1 + hl_ratio) - - lower = ma(mamode, _lower, length=length) - mid = ma(mamode, close, length=length) - upper = ma(mamode, _upper, length=length) - - # Offset - if offset != 0: - lower = lower.shift(offset) - mid = mid.shift(offset) - upper = upper.shift(offset) - - # Fill - if "fillna" in kwargs: - lower.fillna(kwargs["fillna"], inplace=True) - mid.fillna(kwargs["fillna"], inplace=True) - upper.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - lower.name = f"ACCBL_{length}" - mid.name = f"ACCBM_{length}" - upper.name = f"ACCBU_{length}" - mid.category = upper.category = lower.category = "volatility" - - data = {lower.name: lower, mid.name: mid, upper.name: upper} - df = DataFrame(data, index=close.index) - df.name = f"ACCBANDS_{length}" - df.category = mid.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/atr.py b/src/aiomql/ta_libs/pandas_ta/volatility/atr.py deleted file mode 100644 index af8cff0..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/atr.py +++ /dev/null @@ -1,107 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) -from .true_range import true_range - - - -def atr( - high: Series, low: Series, close: Series, length: Int = None, - mamode: str = None, talib: bool = None, - prenan: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Average True Range - - This indicator attempts to quantify volatility with a focus on gaps or - limit moves. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Average_True_Range_(ATR)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - prenan (bool): Sets initial values to ```np.nan``` based - on ```drift```. Default: ```False``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - percent (bool): Return as percent. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - prenan = v_bool(prenan, False) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import ATR - atr = ATR(high, low, close, length) - else: - tr = true_range( - high=high, low=low, close=close, - talib=mode_tal, prenan=prenan, drift=drift - ) - if all(isnan(tr)): - return # Emergency Break - - presma = kwargs.pop("presma", True) - if presma: - sma_nth = tr[0:length].mean() - tr[:length - 1] = nan - tr.iloc[length - 1] = sma_nth - atr = ma(mamode, tr, length=length, talib=mode_tal) - - if all(isnan(atr)): - return # Emergency Break - - percent = kwargs.pop("percent", False) - if percent: - atr *= 100 / close - - # Offset - if offset != 0: - atr = atr.shift(offset) - - # Fill - if "fillna" in kwargs: - atr.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - atr.name = f"ATR{mamode[0]}{'p' if percent else ''}_{length}" - atr.category = "volatility" - - return atr diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/atrts.py b/src/aiomql/ta_libs/pandas_ta/volatility/atrts.py deleted file mode 100644 index 633d6bd..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/atrts.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan, uintc, zeros_like -from numba import njit -from pandas import Series -from pandas_ta._typing import Array, DictLike, Int, IntFloat -from pandas_ta.ma import ma as _ma -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) -from pandas_ta.volatility import atr - - - -@njit(cache=True) -def nb_atrts(x, ma, atr_, length, ma_length): - m = x.size - k = max(length, ma_length) - - result = x.copy() - up = zeros_like(x, dtype=uintc) - dn = zeros_like(x, dtype=uintc) - - expn = x > ma - up[expn], dn[~expn] = 1, 1 - up[:k], dn[:k] = 0, 0 - result[:k] = nan - - for i in range(k, m): - pr = result[i - 1] - if up[i]: - result[i] = x[i] - atr_[i] - if result[i] < pr: - result[i] = pr - if dn[i]: - result[i] = x[i] + atr_[i] - if result[i] > pr: - result[i] = pr - - long, short = result * up, result * dn - long[long == 0], short[short == 0] = nan, nan - - return result, long, short - - -def atrts( - high: Series, low: Series, close: Series, length: Int = None, - ma_length: Int = None, k: IntFloat = None, - mamode: str = None, talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """ATR Trailing Stop - - This indicator attempts to identify exits for long and short positions. - To determine trend, it uses a moving average with a scalable ATR. - - Sources: - * [motivewave](https://www.motivewave.com/studies/atr_trailing_stops.htm) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - ma_length (int): MA Length. Default: ```20``` - k (int): ATR multiplier. Default: ```3``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - percent (bool): Return as percent. Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - ma_length = v_pos_default(ma_length, 20) - _length = length + ma_length - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - k = v_pos_default(k, 3.0) - mamode = v_mamode(mamode, "ema") - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import ATR - atr_ = ATR(high, low, close, length) - else: - atr_ = atr( - high=high, low=low, close=close, length=length, - mamode=mamode, drift=drift, talib=mode_tal, - offset=offset, **kwargs - ) - - if all(isnan(atr_)): - return # Emergency Break - - atr_ *= k - ma_ = _ma(mamode, close, length=ma_length, talib=mode_tal) - - np_close, np_ma, np_atr = close.to_numpy(), ma_.to_numpy(), atr_.to_numpy() - np_atrts_, _, _ = nb_atrts(np_close, np_ma, np_atr, length, ma_length) - - percent = kwargs.pop("percent", False) - if percent: - np_atrts_ *= 100 / np_close - - atrts = Series(np_atrts_, index=close.index) - - # Offset - if offset != 0: - atrts = atrts.shift(offset) - - # Fill - if "fillna" in kwargs: - atrts.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"ATRTS{mamode[0]}{'p' if percent else ''}" - atrts.name = f"{_props}_{length}_{ma_length}_{k}" - atrts.category = "volatility" - - return atrts diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/bbands.py b/src/aiomql/ta_libs/pandas_ta/volatility/bbands.py deleted file mode 100644 index 5bb9590..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/bbands.py +++ /dev/null @@ -1,124 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.maps import Imports -from pandas_ta.statistics import stdev -from pandas_ta.utils import ( - non_zero_range, - tal_ma, - v_mamode, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def bbands( - close: Series, length: Int = None, - lower_std: IntFloat = None, upper_std: IntFloat = None, - ddof: Int = None, mamode: str = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Bollinger Bands - - This indicator, by John Bollinger, attempts to quantify volatility by - creating lower and upper bands centered around a moving average. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Bollinger_Bands_(BB)) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```5``` - lower_std (IntFloat): Lower standard deviation. Default: ```2.0``` - upper_std (IntFloat): Upper standard deviation. Default: ```2.0``` - ddof (int): Degrees of Freedom to use. Default: ```0``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - ddof (int): By default, uses Pandas ```ddof=1```. - For Numpy calculation, use ```0```. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 5 columns - - Note: - * TA Lib does not have a ```ddof``` parameter. - * The divisor used in calculations is: ```N - ddof```, where ```N``` - is the number of elements. To use ```ddof```, set ```talib=False```. - """ - # Validate - length = v_pos_default(length, 5) - close = v_series(close, length) - - if close is None: - return - - lower_std = v_pos_default(lower_std, 2.0) - upper_std = v_pos_default(upper_std, 2.0) - ddof = int(ddof) if isinstance(ddof, int) and 0 <= ddof < length else 1 - mamode = v_mamode(mamode, "sma") - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import BBANDS - upper, mid, lower = BBANDS(close, length, upper_std, lower_std, tal_ma(mamode)) - else: - std_dev = stdev(close=close, length=length, ddof=ddof, talib=mode_tal) - lower_deviations = lower_std * std_dev - upper_deviations = upper_std * std_dev - - mid = ma(mamode, close, length=length, talib=mode_tal, **kwargs) - lower = mid - lower_deviations - upper = mid + upper_deviations - - ulr = non_zero_range(upper, lower) - bandwidth = 100 * ulr / mid - percent = non_zero_range(close, lower) / ulr - - # Offset - if offset != 0: - lower = lower.shift(offset) - mid = mid.shift(offset) - upper = upper.shift(offset) - bandwidth = bandwidth.shift(offset) - percent = percent.shift(offset) - - # Fill - if "fillna" in kwargs: - lower.fillna(kwargs["fillna"], inplace=True) - mid.fillna(kwargs["fillna"], inplace=True) - upper.fillna(kwargs["fillna"], inplace=True) - bandwidth.fillna(kwargs["fillna"], inplace=True) - percent.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{lower_std}_{upper_std}" - lower.name = f"BBL{_props}" - mid.name = f"BBM{_props}" - upper.name = f"BBU{_props}" - bandwidth.name = f"BBB{_props}" - percent.name = f"BBP{_props}" - upper.category = lower.category = "volatility" - mid.category = bandwidth.category = upper.category - - data = { - lower.name: lower, - mid.name: mid, - upper.name: upper, - bandwidth.name: bandwidth, - percent.name: percent - } - df = DataFrame(data, index=close.index) - df.name = f"BBANDS{_props}" - df.category = mid.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/chandelier_exit.py b/src/aiomql/ta_libs/pandas_ta/volatility/chandelier_exit.py deleted file mode 100644 index dfef2f3..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/chandelier_exit.py +++ /dev/null @@ -1,127 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan -from pandas import Series, DataFrame -from pandas_ta.volatility import atr -from pandas_ta._typing import Int, IntFloat, DictLike -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_pos_default, - v_offset, - v_series, - v_talib -) - - - -def chandelier_exit( - high: Series, low: Series, close: Series, - high_length: Int = None, low_length: Int = None, - atr_length: Int = None, multiplier: IntFloat = None, - mamode: str = None, talib: bool = None, use_close: bool = None, - drift: Int = None, offset: Int = None, **kwargs: DictLike -): - """Chandelier Exit - - This indicator attempts to identify trailing stop-losses based on ATR. - - Sources: - * [stockcharts](https://school.stockcharts.com/doku.php?id=technical_indicators:chandelier_exit) - * [tradingview](https://in.tradingview.com/scripts/chandelier/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - high_length (int): Highest high period. Default: ```22``` - low_length (int): Lowest low period. Default: ```22``` - atr_length (int) : ATR length. Default: ```14``` - multiplier (float): Lower & Upper Bands scalar. Default: ```2.0``` - mamode (str): See ```help(ta.ma)```. Default: ```"rma"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - use_close (bool): Use ```max(high_length, low_length)``` for - the ```close```. Default: ```False``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - atr_length = v_pos_default(atr_length, 14) - high_length = v_pos_default(high_length, 22) - low_length = v_pos_default(low_length, 22) - roll_length = max(high_length, low_length) - _length = max(atr_length, roll_length) + 1 - - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - multiplier = v_pos_default(multiplier, 2.0) - mamode = v_mamode(mamode, "rma") - mode_tal = v_talib(talib) - use_close = v_bool(use_close, False) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - atr_ = atr( - high=high, low=low, close=close, length=atr_length, - mamode=mamode, talib=mode_tal, drift=drift, offset=offset - ) - if atr_ is None or all(isnan(atr_)): - return - - atr_mult = atr_ * multiplier - - if use_close: - long = close.rolling(roll_length, min_periods=1).max() - atr_mult - short = close.rolling(roll_length, min_periods=1).min() + atr_mult - else: - long = high.rolling(high_length, min_periods=1).max() - atr_mult - short = low.rolling(low_length, min_periods=1).min() + atr_mult - - uptrend = (close > long.shift(drift)).astype(int) - downtrend = -(close < short.shift(drift)).astype(int) - - direction = uptrend + downtrend - if direction.iloc[0] == 0: - direction.iloc[0] = 1 - direction = direction.replace(0, nan).ffill() - - # Offset - if offset != 0: - long = long.shift(offset) - short = short.shift(offset) - direction = direction.shift(offset) - - # Fill - if "fillna" in kwargs: - long.fillna(kwargs["fillna"], inplace=True) - short.fillna(kwargs["fillna"], inplace=True) - direction.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _name = "CHDLREXT" - _props = f"_{high_length}_{low_length}_{atr_length}_{multiplier}" - if use_close: - _props = f"_CLOSE_{_props}" - - data = { - f"{_name}l{_props}": long, - f"{_name}s{_props}": short, - f"{_name}d{_props}": direction - } - df = DataFrame(data, index=close.index) - df.name = f"{_name}{_props}" - df.category = "volatility" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/donchian.py b/src/aiomql/ta_libs/pandas_ta/volatility/donchian.py deleted file mode 100644 index 601c445..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/donchian.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def donchian( - high: Series, low: Series, - lower_length: Int = None, upper_length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Donchian Channels - - This indicator attempt to quantify volatility similarily to - Bollinger Bands and Keltner Channels. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Donchian_Channels_(DC)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - lower_length (int): Lower period. Default: ```20``` - upper_length (int): Upper period. Default: ```20``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - lower_length = v_pos_default(lower_length, 20) - upper_length = v_pos_default(upper_length, 20) - lmin_periods = int(kwargs.pop("lmin_periods", lower_length)) - umin_periods = int(kwargs.pop("umin_periods", upper_length)) - - _length = max(lower_length, lmin_periods, upper_length, umin_periods) - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - offset = v_offset(offset) - - # Calculate - lower = low.rolling(lower_length, min_periods=lmin_periods).min() - upper = high.rolling(upper_length, min_periods=umin_periods).max() - mid = 0.5 * (lower + upper) - - # Fill - if "fillna" in kwargs: - lower.fillna(kwargs["fillna"], inplace=True) - mid.fillna(kwargs["fillna"], inplace=True) - upper.fillna(kwargs["fillna"], inplace=True) - - # Offset - if offset != 0: - lower = lower.shift(offset) - mid = mid.shift(offset) - upper = upper.shift(offset) - - # Name and Category - lower.name = f"DCL_{lower_length}_{upper_length}" - mid.name = f"DCM_{lower_length}_{upper_length}" - upper.name = f"DCU_{lower_length}_{upper_length}" - mid.category = upper.category = lower.category = "volatility" - - data = {lower.name: lower, mid.name: mid, upper.name: upper} - df = DataFrame(data, index=high.index) - df.name = f"DC_{lower_length}_{upper_length}" - df.category = mid.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/hwc.py b/src/aiomql/ta_libs/pandas_ta/volatility/hwc.py deleted file mode 100644 index 49e6768..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/hwc.py +++ /dev/null @@ -1,142 +0,0 @@ -# -*- coding: utf-8 -*- -from sys import float_info as sflt -from numpy import sqrt -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.utils import v_bool, v_offset, v_pos_default, v_series - - - -def hwc( - close: Series, scalar: IntFloat = None, channels: bool = None, - na: IntFloat = None, nb: IntFloat = None, - nc: IntFloat = None, nd: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Holt-Winter Channel - - This indicator creates a three-parameter moving average using the - "Holt-Winters" method. - - Sources: - * [rengel8](https://github.com/rengel8) (2021-08-11) based on the - implementation from "MetaTrader 5" - * [mql5](https://www.mql5.com/en/code/20857) - - Parameters: - close (pd.Series): ```close``` Series - scalar (float): Channel scalar. Default: ```1``` - channels (bool): Return width and percentage columns. - Default: ```True``` - na (float): Smoothed series in range ```[0, 1]```. Default: ```0.2``` - nb (float): Trend value in range ```[0, 1]```. Default: ```0.1``` - nc (float): Seasonality value in range ```[0, 1]```. Default: ```0.1``` - nd (float): Channel value in range ```[0, 1]```. Default: ```0.1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - close = v_series(close, 1) - scalar = v_pos_default(scalar, 1) - channels = v_bool(channels, True) - na = v_pos_default(na, 0.2) - nb = v_pos_default(nb, 0.1) - nc = v_pos_default(nc, 0.1) - nd = v_pos_default(nd, 0.1) - offset = v_offset(offset) - - if close is None: - return - - # Calculate Result - last_a = last_v = last_var = 0 - last_f = last_price = last_result = close.iloc[0] - lower, result, upper = [], [], [] - chan_pct_width, chan_width = [], [] - - m = close.size - for i in range(m): - F = (1.0 - na) * (last_f + last_v + 0.5 * last_a) + na * close.iloc[i] - V = (1.0 - nb) * (last_v + last_a) + nb * (F - last_f) - A = (1.0 - nc) * last_a + nc * (V - last_v) - result.append((F + V + 0.5 * A)) - - var = (1.0 - nd) * last_var + \ - nd * (last_price - last_result) * (last_price - last_result) - stddev = sqrt(last_var) - upper.append(result[i] + scalar * stddev) - lower.append(result[i] - scalar * stddev) - - if channels: - # channel width - chan_width.append(upper[i] - lower[i]) - # channel percentage price position - chan_pct_width.append( - (close.iloc[i] - lower[i]) / (upper[i] - lower[i] + sflt.epsilon) - ) - - # update values - last_price = close.iloc[i] - last_a = A - last_f = F - last_v = V - last_var = var - last_result = result[i] - - # Aggregate - hwc = Series(result, index=close.index) - hwc_upper = Series(upper, index=close.index) - hwc_lower = Series(lower, index=close.index) - if channels: - hwc_width = Series(chan_width, index=close.index) - hwc_pctwidth = Series(chan_pct_width, index=close.index) - - # Offset - if offset != 0: - hwc = hwc.shift(offset) - hwc_upper = hwc_upper.shift(offset) - hwc_lower = hwc_lower.shift(offset) - if channels: - hwc_width = hwc_width.shift(offset) - hwc_pctwidth = hwc_pctwidth.shift(offset) - - # Fill - if "fillna" in kwargs: - hwc.fillna(kwargs["fillna"], inplace=True) - hwc_upper.fillna(kwargs["fillna"], inplace=True) - hwc_lower.fillna(kwargs["fillna"], inplace=True) - if channels: - hwc_width.fillna(kwargs["fillna"], inplace=True) - hwc_pctwidth.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{scalar}" - hwc.name = f"HWM{_props}" - hwc_upper.name = f"HWU{_props}" - hwc_lower.name = f"HWL{_props}" - hwc.category = hwc_upper.category = hwc_lower.category = "volatility" - - if channels: - data = { - hwc.name: hwc, - hwc_lower.name: hwc_lower, - hwc_upper.name: hwc_upper, - f"HWW{_props}": hwc_width, - f"HWPCT{_props}": hwc_pctwidth - } - else: - data = { - hwc.name: hwc, - hwc_lower.name: hwc_lower, - hwc_upper.name: hwc_upper - } - df = DataFrame(data, index=close.index) - df.name = f"HWC_{scalar}" - df.category = hwc.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/kc.py b/src/aiomql/ta_libs/pandas_ta/volatility/kc.py deleted file mode 100644 index 72196f3..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/kc.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.utils import ( - high_low_range, - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_series -) -from .true_range import true_range - - - -def kc( - high: Series, low: Series, close: Series, - length: Int = None, scalar: IntFloat = None, - tr: bool = None, mamode: str = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Keltner Channels - - This indicator attempts to identify volatility similarily to - Bollinger Bands and Donchian Channels. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Keltner_Channels_(KC)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - scalar (float): Band scalar. Default: ```2``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - tr (bool): Use True Range calculation. Otherwise use ```high - low``` - for range computation. Default: ```True``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - length = v_pos_default(length, 20) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - scalar = v_pos_default(scalar, 2) - tr = v_bool(tr, True) - mamode = v_mamode(mamode, "ema") - offset = v_offset(offset) - - # Calculate - range_ = true_range(high, low, close) if tr else high_low_range(high, low) - basis = ma(mamode, close, length=length) - band = ma(mamode, range_, length=length) - - lower = basis - scalar * band - upper = basis + scalar * band - - # Offset - if offset != 0: - lower = lower.shift(offset) - basis = basis.shift(offset) - upper = upper.shift(offset) - - # Fill - if "fillna" in kwargs: - lower.fillna(kwargs["fillna"], inplace=True) - basis.fillna(kwargs["fillna"], inplace=True) - upper.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"{mamode.lower()[0] if len(mamode) else ''}_{length}_{scalar}" - lower.name = f"KCL{_props}" - basis.name = f"KCB{_props}" - upper.name = f"KCU{_props}" - basis.category = upper.category = lower.category = "volatility" - - data = {lower.name: lower, basis.name: basis, upper.name: upper} - df = DataFrame(data, index=close.index) - df.name = f"KC{_props}" - df.category = basis.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/massi.py b/src/aiomql/ta_libs/pandas_ta/volatility/massi.py deleted file mode 100644 index 78e89d2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/massi.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import ema -from pandas_ta.utils import non_zero_range, v_offset, v_pos_default, v_series - - - -def massi( - high: Series, low: Series, fast: Int = None, slow: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Mass Index - - This indicator attempts to use a High-Low Range to identify trend - reversals based on range expansions. - - Sources: - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:mass_index) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - fast (int): Fast period. Default: ```9``` - slow (int): Slow period. Default: ```25``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - fast = v_pos_default(fast, 9) - slow = v_pos_default(slow, 25) - if slow < fast: - fast, slow = slow, fast - _length = 2 * max(fast, slow) - min(fast, slow) - high = v_series(high, _length) - low = v_series(low, _length) - - if high is None or low is None: - return - - offset = v_offset(offset) - if "length" in kwargs: - kwargs.pop("length") - - # Calculate - high_low_range = non_zero_range(high, low) - hl_ema1 = ema(close=high_low_range, length=fast, **kwargs) - if all(isnan(hl_ema1)): - return # Emergency Break - hl_ema2 = ema(close=hl_ema1, length=fast, **kwargs) - if all(isnan(hl_ema2)): - return # Emergency Break - - hl_ratio = hl_ema1 / hl_ema2 - massi = hl_ratio.rolling(slow, min_periods=slow).sum() - if all(isnan(massi)): - return # Emergency Break - - # Offset - if offset != 0: - massi = massi.shift(offset) - - # Fill - if "fillna" in kwargs: - massi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - massi.name = f"MASSI_{fast}_{slow}" - massi.category = "volatility" - - return massi diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/natr.py b/src/aiomql/ta_libs/pandas_ta/volatility/natr.py deleted file mode 100644 index 7f29f6e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/natr.py +++ /dev/null @@ -1,97 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_scalar, - v_series, - v_talib -) -from pandas_ta.volatility import atr - - - -def natr( - high: Series, low: Series, close: Series, - length: Int = None, scalar: IntFloat = None, mamode: str = None, - talib: bool = None, prenan: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Normalized Average True Range - - This indicator applies a normalizer to Average True Range. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/normalized-average-true-range-natr/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```20``` - scalar (float): Scalar. Default: ```100``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - talib (bool): If installed, use TA Lib. Default: ```True``` - prenan (bool): Sets initial values to ```np.nan``` based - on ```drift```. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9506743353852364)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 14) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - scalar = v_scalar(scalar, 100) - mamode = v_mamode(mamode, "ema") - mode_tal = v_talib(talib) - prenan = v_bool(prenan, False) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import NATR - natr = NATR(high, low, close, length) - else: - natr = (scalar / close) * \ - atr( - high=high, low=low, close=close, length=length, - mamode=mamode, drift=drift, talib=mode_tal, - prenan=prenan, offset=offset, **kwargs - ) - - # Offset - if offset != 0: - natr = natr.shift(offset) - - # Fill - if "fillna" in kwargs: - natr.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - natr.name = f"NATR_{length}" - natr.category = "volatility" - - return natr diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/pdist.py b/src/aiomql/ta_libs/pandas_ta/volatility/pdist.py deleted file mode 100644 index 0d31060..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/pdist.py +++ /dev/null @@ -1,67 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import non_zero_range, v_drift, v_offset, v_series - - - -def pdist( - open_: Series, high: Series, low: Series, close: Series, - drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Price Distance - - This indicator attempts to quantify the magnitude covered by - price movements. - - Sources: - * [prorealcode](https://www.prorealcode.com/prorealtime-indicators/pricedistance/) - - Parameters: - open_ (pd.Series): ```open``` Series - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - drift = v_drift(drift) - open_ = v_series(open_) - high = v_series(high) - low = v_series(low) - close = v_series(close) - offset = v_offset(offset) - - # Calculate - pdist = 2 * non_zero_range(high, low) - if all(isnan(pdist)): - return # Emergency Break - - pdist += non_zero_range(open_, close.shift(drift)).abs() - pdist -= non_zero_range(close, open_).abs() - - if all(isnan(pdist)): - return # Emergency Break - - # Offset - if offset != 0: - pdist = pdist.shift(offset) - - # Fill - if "fillna" in kwargs: - pdist.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pdist.name = "PDIST" - pdist.category = "volatility" - - return pdist diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/rvi.py b/src/aiomql/ta_libs/pandas_ta/volatility/rvi.py deleted file mode 100644 index ee5ac8c..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/rvi.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.ma import ma -from pandas_ta.statistics import stdev -from pandas_ta.utils import ( - unsigned_differences, - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def _rvi(source, length, scalar, mode, drift): - std = stdev(source, length) - pos, neg = unsigned_differences(source, drift) - - pos_std = pos * std - neg_std = neg * std - - pos_avg = ma(mode, pos_std, length=length) - neg_avg = ma(mode, neg_std, length=length) - - result = scalar * pos_avg / (pos_avg + neg_avg) - return result - - -def rvi( - close: Series, high: Series = None, low: Series = None, - length: Int = None, scalar: IntFloat = None, - refined: bool = None, thirds: bool = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Relative Volatility Index - - This indicator attempts to quantify volatility using standard deviation. - - Sources: - * [motivewave](https://www.motivewave.com/studies/relative_volatility_index.htm) - * [tradingview A](https://www.tradingview.com/script/mLZJqxKn-Relative-Volatility-Index/) - * [tradingview B](https://www.tradingview.com/support/solutions/43000594684-relative-volatility-index/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - scalar (float): Bands scalar. Default: ```100``` - refined (bool): Use 'refined' calculation which is the average of - RVI(high) and RVI(low) instead of RVI(close). Default: ```False``` - thirds (bool): Average of ```high```, ```low``` and ```close```. - Default: ```False``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - length = v_pos_default(length, 14) - close = v_series(close, length + 2) - - if close is None: - return - - scalar = v_pos_default(scalar, 100) - refined = v_bool(refined, False) - thirds = v_bool(thirds, False) - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - if refined or thirds: - high = v_series(high) - low = v_series(low) - - # Calculate - _mode = "" - if refined: - high_rvi = _rvi(high, length, scalar, mamode, drift) - low_rvi = _rvi(low, length, scalar, mamode, drift) - rvi = 0.5 * (high_rvi + low_rvi) - _mode = "r" - elif thirds: - high_rvi = _rvi(high, length, scalar, mamode, drift) - low_rvi = _rvi(low, length, scalar, mamode, drift) - close_rvi = _rvi(close, length, scalar, mamode, drift) - rvi = (high_rvi + low_rvi + close_rvi) / 3.0 - _mode = "t" - else: - rvi = _rvi(close, length, scalar, mamode, drift) - - if all(isnan(rvi)): - return # Emergency Break - - # Offset - if offset != 0: - rvi = rvi.shift(offset) - - # Fill - if "fillna" in kwargs: - rvi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - rvi.name = f"RVI{_mode}_{length}" - rvi.category = "volatility" - - return rvi diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/thermo.py b/src/aiomql/ta_libs/pandas_ta/volatility/thermo.py deleted file mode 100644 index e343a2e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/thermo.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_bool, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def thermo( - high: Series, low: Series, length: Int = None, - long: Int = None, short: Int = None, - mamode: str = None, asint: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Elders Thermometer - - This indicator, by Dr Alexander Elder, attempts to quantify volatility. - - Sources: - * [motivewave](https://www.motivewave.com/studies/elders_thermometer.htm) - * [tradingview](https://www.tradingview.com/script/HqvTuEMW-Elder-s-Market-Thermometer-LazyBear/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - length (int): The period. Default: ```20``` - long (int): Buy factor. Default: ```2``` - short (float): Sell factor. Default: ```0.5``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - asint (int): Returns as int. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 4 columns - """ - # Validate - length = v_pos_default(length, 20) - high = v_series(high, length + 1) - low = v_series(low, length + 1) - - if high is None or low is None: - return - - long = v_pos_default(long, 2) - short = v_pos_default(short, 0.5) - mamode = v_mamode(mamode, "ema") - asint = v_bool(asint, True) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - thermoL = (low.shift(drift) - low).abs() - thermoH = (high - high.shift(drift)).abs() - - thermo = thermoL - thermo = thermo.where(thermoH < thermoL, thermoH) - thermo.index = high.index - - thermo_ma = ma(mamode, thermo, length=length) - thermo_long = thermo < (thermo_ma * long) - thermo_short = thermo > (thermo_ma * short) - - if asint: - thermo_long = thermo_long.astype(int) - thermo_short = thermo_short.astype(int) - - # Offset - if offset != 0: - thermo = thermo.shift(offset) - thermo_ma = thermo_ma.shift(offset) - thermo_long = thermo_long.shift(offset) - thermo_short = thermo_short.shift(offset) - - # Fill - if "fillna" in kwargs: - thermo.fillna(kwargs["fillna"], inplace=True) - thermo_ma.fillna(kwargs["fillna"], inplace=True) - thermo_long.fillna(kwargs["fillna"], inplace=True) - thermo_short.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{long}_{short}" - thermo.name = f"THERMO{_props}" - thermo_ma.name = f"THERMOma{_props}" - thermo_long.name = f"THERMOl{_props}" - thermo_short.name = f"THERMOs{_props}" - thermo.category = thermo_ma.category = "volatility" - thermo_long.category = thermo_short.category = thermo.category - - data = { - thermo.name: thermo, - thermo_ma.name: thermo_ma, - thermo_long.name: thermo_long, - thermo_short.name: thermo_short - } - df = DataFrame(data, index=high.index) - df.name = f"THERMO{_props}" - df.category = thermo.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/true_range.py b/src/aiomql/ta_libs/pandas_ta/volatility/true_range.py deleted file mode 100644 index 417370f..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/true_range.py +++ /dev/null @@ -1,94 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan, nan -from pandas import concat, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import ( - non_zero_range, - v_bool, - v_drift, - v_offset, - v_series, - v_talib -) - - - -def true_range( - high: Series, low: Series, close: Series, - talib: bool = None, prenan: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """True Range - - This indicator attempts to quantify a High-Low range including potential - gap scenarios. - - Sources: - * [macroption](https://www.macroption.com/true-range/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - talib (bool): If installed, use TA Lib. Default: ```True``` - prenan (bool): Sets initial values to ```nan``` based - on ```drift```. Default: ```False``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9999999999999999)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - _length = 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - - if high is None or low is None or close is None: - return - - mode_tal = v_talib(talib) - prenan = v_bool(prenan, False) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import TRANGE - true_range = TRANGE(high, low, close) - else: - hl_range = non_zero_range(high, low) - pc = close.shift(drift) - ranges = [hl_range, high - pc, pc - low] - true_range = concat(ranges, axis=1) - true_range = true_range.abs().max(axis=1) - if prenan: - true_range.iloc[:drift] = nan - - if all(isnan(true_range)): - return # Emergency Break - - # Offset - if offset != 0: - true_range = true_range.shift(offset) - - # Fill - if "fillna" in kwargs: - true_range.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - true_range.name = f"TRUERANGE_{drift}" - true_range.category = "volatility" - - return true_range diff --git a/src/aiomql/ta_libs/pandas_ta/volatility/ui.py b/src/aiomql/ta_libs/pandas_ta/volatility/ui.py deleted file mode 100644 index 18fba8b..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volatility/ui.py +++ /dev/null @@ -1,73 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import sqrt -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import sma -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def ui( - close: Series, length: Int = None, scalar: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Ulcer Index - - This indicator, by Peter Martin, attempts to quantify downside volatility - with a Quadratic Mean. - - Sources: - * [tangotools](http://www.tangotools.com/ui/ui.htm) - * [tradingtechnologies](https://library.tradingtechnologies.com/trade/chrt-ti-ulcer-index.html) - * [wikipedia](https://en.wikipedia.org/wiki/Ulcer_index) - - Parameters: - close (pd.Series): ```close``` Series - length (int): The period. Default: ```14``` - scalar (float): Bands scalar. Default: ```100``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - everget (value): Use Evergets' TradingView SMA. - Default: ```False``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - scalar = v_pos_default(scalar, 100) - close = v_series(close, 2 * length - 1) - - if close is None: - return - - offset = v_offset(offset) - - # Calculate - highest_close = close.rolling(length).max() - downside = scalar * (close - highest_close) / highest_close - d2 = downside * downside - - everget = kwargs.pop("everget", False) - if everget: - # Everget uses SMA instead of SUM for calculation - _ui = sma(d2, length) - else: - _ui = d2.rolling(length).sum() - ui = sqrt(_ui / length) - - # Offset - if offset != 0: - ui = ui.shift(offset) - - # Fill - if "fillna" in kwargs: - ui.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ui.name = f"UI{'' if not everget else 'e'}_{length}" - ui.category = "volatility" - - return ui diff --git a/src/aiomql/ta_libs/pandas_ta/volume/__init__.py b/src/aiomql/ta_libs/pandas_ta/volume/__init__.py deleted file mode 100644 index 6f6575e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -from .ad import ad -from .adosc import adosc -from .aobv import aobv -from .cmf import cmf -from .efi import efi -from .eom import eom -from .kvo import kvo -from .mfi import mfi -from .nvi import nvi -from .obv import obv -from .pvi import pvi -from .pvo import pvo -from .pvol import pvol -from .pvr import pvr -from .pvt import pvt -from .tsv import tsv -from .vhm import vhm -from .vp import vp -from .vwap import vwap -from .vwma import vwma - -__all__ = [ - "ad", - "adosc", - "aobv", - "cmf", - "efi", - "eom", - "kvo", - "mfi", - "nvi", - "obv", - "pvi", - "pvo", - "pvol", - "pvr", - "pvt", - "tsv", - "vhm", - "vp", - "vwap", - "vwma", -] diff --git a/src/aiomql/ta_libs/pandas_ta/volume/ad.py b/src/aiomql/ta_libs/pandas_ta/volume/ad.py deleted file mode 100644 index af1cd0b..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/ad.py +++ /dev/null @@ -1,72 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import non_zero_range, v_offset, v_series, v_talib - - - -def ad( - high: Series, low: Series, close: Series, volume: Series, - open_: Series = None, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Accumulation/Distribution - - This indicator attempts to quantify accumulation/distribution from a - relative position within it's High-Low range and volume. - - Sources: - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/accumulationdistribution-ad/) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - open_ (pd.Series): Optional ```open``` Series - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - high = v_series(high) - low = v_series(low) - close = v_series(close) - volume = v_series(volume) - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal and volume.size: - from talib import AD - ad = AD(high, low, close, volume) - else: - if open_ is not None: - open_ = v_series(open_) - ad = non_zero_range(close, open_) # AD with Open - else: - ad = 2 * close - (high + low) # AD with High, Low, Close - - high_low_range = non_zero_range(high, low) - ad *= volume / high_low_range - ad = ad.cumsum() - - # Offset - if offset != 0: - ad = ad.shift(offset) - - # Fill - if "fillna" in kwargs: - ad.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - ad.name = "AD" if open_ is None else "ADo" - ad.category = "volume" - - return ad diff --git a/src/aiomql/ta_libs/pandas_ta/volume/adosc.py b/src/aiomql/ta_libs/pandas_ta/volume/adosc.py deleted file mode 100644 index 2037a84..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/adosc.py +++ /dev/null @@ -1,95 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.overlap import ema -from pandas_ta.utils import v_offset, v_pos_default, v_series, v_talib -from pandas_ta.volume import ad - - - -def adosc( - high: Series, low: Series, close: Series, volume: Series, - open_: Series = None, fast: Int = None, slow: Int = None, - talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Accumulation/Distribution Oscillator - - This indicator is an AD oscillator. It is interpreted similarly - to MACD and APO. - - Sources: - * [investopedia](https://www.investopedia.com/articles/active-trading/031914/understanding-chaikin-oscillator.asp) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - open_ (pd.Series): ```open``` Series - volume (pd.Series): ```volume``` Series - fast (int): Fast MA period. Default: ```12``` - slow (int): Slow MA period. Default: ```26``` - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Also known as Chaikin Oscillator - - Warning: - TA-Lib Correlation: ```np.float64(0.9989721423605135)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - fast = v_pos_default(fast, 3) - slow = v_pos_default(slow, 10) - _length = max(fast, slow) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import ADOSC - adosc = ADOSC(high, low, close, volume, fast, slow) - else: - # remove length so it doesn't override ema length - if "length" in kwargs: - kwargs.pop("length") - - ad_ = ad( - high=high, low=low, close=close, volume=volume, - open_=open_, talib=mode_tal - ) - fast_ad = ema(close=ad_, length=fast, **kwargs, talib=mode_tal) - slow_ad = ema(close=ad_, length=slow, **kwargs, talib=mode_tal) - adosc = fast_ad - slow_ad - - # Offset - if offset != 0: - adosc = adosc.shift(offset) - - # Fill - if "fillna" in kwargs: - adosc.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - adosc.name = f"ADOSC_{fast}_{slow}" - adosc.category = "volume" - - return adosc diff --git a/src/aiomql/ta_libs/pandas_ta/volume/aobv.py b/src/aiomql/ta_libs/pandas_ta/volume/aobv.py deleted file mode 100644 index 34847c8..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/aobv.py +++ /dev/null @@ -1,113 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.trend.long_run import long_run -from pandas_ta.trend.short_run import short_run -from pandas_ta.utils import v_mamode, v_offset, v_pos_default, v_series -from .obv import obv - - - -def aobv( - close: Series, volume: Series, fast: Int = None, slow: Int = None, - max_lookback: Int = None, min_lookback: Int = None, - mamode: str = None, run_length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Archer On Balance Volume - - This indicator, by Kevin Johnson, attempts to identify OBV trends using - two moving averages. It also attempts to identify if the moving averages - are in a long_run or short_run. Finally, it also calculates the rolling - maximum and minimum of OBV. - - Sources: - * Kevin Johnson - * [tradingview](https://www.tradingview.com/script/Co1ksara-Trade-Archer-On-balance-Volume-Moving-Averages-v1/) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - fast (int): Fast MA period. Default: ```4``` - slow (int): Slow MA period. Default: ```12``` - max_lookback (int): Maximum OBV period. Default: ```2``` - min_lookback (int): Minimum OBV period. Default: ```2``` - run_length (int): Long and short run period. Default: ```2``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 6 columns - - Note: - * [long_run](../api/trend.md/#src.pandas_ta.trend.long_run.long_run) - * [short_run](../api/trend.md/#src.pandas_ta.trend.short_run.short_run) - """ - # Validate - fast = v_pos_default(fast, 4) - slow = v_pos_default(slow, 12) - min_lookback = v_pos_default(min_lookback, 2) - max_lookback = v_pos_default(max_lookback, 2) - - if slow < fast: - fast, slow = slow, fast - _length = max(max_lookback, min_lookback) + slow - - close = v_series(close, _length) - volume = v_series(volume, _length) - - if close is None or volume is None: - return - - mamode = v_mamode(mamode, "ema") - run_length = v_pos_default(run_length, 2) - offset = v_offset(offset) - # remove length so it doesn't override ema length - if "length" in kwargs: - kwargs.pop("length") - - # Calculate - obv_ = obv(close=close, volume=volume, **kwargs) - maf = ma(mamode, obv_, length=fast, **kwargs) - mas = ma(mamode, obv_, length=slow, **kwargs) - - obv_long = long_run(maf, mas, length=run_length) - obv_short = short_run(maf, mas, length=run_length) - - # Offset - if offset != 0: - obv_ = obv_.shift(offset) - maf = maf.shift(offset) - mas = mas.shift(offset) - obv_long = obv_long.shift(offset) - obv_short = obv_short.shift(offset) - - # Fill - if "fillna" in kwargs: - obv_.fillna(kwargs["fillna"], inplace=True) - maf.fillna(kwargs["fillna"], inplace=True) - mas.fillna(kwargs["fillna"], inplace=True) - obv_long.fillna(kwargs["fillna"], inplace=True) - obv_short.fillna(kwargs["fillna"], inplace=True) - - _mode = mamode.lower()[0] if len(mamode) else "" - data = { - obv_.name: obv_, - f"OBV_min_{min_lookback}": obv_.rolling(min_lookback).min(), - f"OBV_max_{max_lookback}": obv_.rolling(max_lookback).max(), - f"OBV{_mode}_{fast}": maf, - f"OBV{_mode}_{slow}": mas, - f"AOBV_LR_{run_length}": obv_long, - f"AOBV_SR_{run_length}": obv_short - } - df = DataFrame(data, index=close.index) - - # Name and Category - df.name = f"AOBV{_mode}_{fast}_{slow}_{min_lookback}_{max_lookback}_{run_length}" - df.category = "volume" - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volume/cmf.py b/src/aiomql/ta_libs/pandas_ta/volume/cmf.py deleted file mode 100644 index c7142ea..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/cmf.py +++ /dev/null @@ -1,79 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import non_zero_range, v_offset, v_pos_default, v_series - - - -def cmf( - high: Series, low: Series, close: Series, volume: Series, - open_: Series = None, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Chaikin Money Flow - - This indicator attempts to quantify money flow. - - Sources: - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:chaikin_money_flow_cmf) - * [tradingview](https://www.tradingview.com/wiki/Chaikin_Money_Flow_(CMF)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```20``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - open_ (pd.Series): Optional ```open``` Series. Default: ```None``` - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Commonly used with Accumulation/Distribution [ad](volume.md/#src.pandas_ta.volume.ad.ad) - """ - # Validate - length = v_pos_default(length, 20) - if "min_periods" in kwargs and kwargs["min_periods"] is not None: - min_periods = int(kwargs["min_periods"]) - else: - min_periods = length - _length = max(length, min_periods) - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - offset = v_offset(offset) - - # Calculate - if open_ is not None: - open_ = v_series(open_) - ad = non_zero_range(close, open_) # AD with Open - else: - ad = 2 * close - (high + low) # AD with High, Low, Close - - ad *= volume / non_zero_range(high, low) - cmf = ad.rolling(length, min_periods=min_periods).sum() \ - / volume.rolling(length, min_periods=min_periods).sum() - - # Offset - if offset != 0: - cmf = cmf.shift(offset) - - # Fill - if "fillna" in kwargs: - cmf.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - cmf.name = f"CMF_{length}" - cmf.category = "volume" - - return cmf diff --git a/src/aiomql/ta_libs/pandas_ta/volume/efi.py b/src/aiomql/ta_libs/pandas_ta/volume/efi.py deleted file mode 100644 index 6959eb7..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/efi.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def efi( - close: Series, volume: Series, length: Int = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Elder's Force Index - - This indicator attempts to quantify movement magnitude as well as - potential reversals and price corrections. - - Sources: - * [motivewave](https://www.motivewave.com/studies/elders_force_index.htm) - * [tradingview](https://www.tradingview.com/wiki/Elder%27s_Force_Index_(EFI)) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```13``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 13) - close = v_series(close, length) - volume = v_series(volume, length) - - if close is None or volume is None: - return - - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - pv_diff = close.diff(drift) * volume - efi = ma(mamode, pv_diff, length=length) - - # Offset - if offset != 0: - efi = efi.shift(offset) - - # Fill - if "fillna" in kwargs: - efi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - efi.name = f"EFI_{length}" - efi.category = "volume" - - return efi diff --git a/src/aiomql/ta_libs/pandas_ta/volume/eom.py b/src/aiomql/ta_libs/pandas_ta/volume/eom.py deleted file mode 100644 index a489ca9..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/eom.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import hl2, sma -from pandas_ta.utils import ( - non_zero_range, - v_drift, - v_pos_default, - v_offset, - v_series -) - - - -def eom( - high: Series, low: Series, close: Series, volume: Series, - length: Int = None, divisor: IntFloat= None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Ease of Movement - - This indicator is an oscillator that attempts to quantify the relationship - with HLC and volume. - - Sources: - * [motivewave](https://www.motivewave.com/studies/ease_of_movement.htm) - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:ease_of_movement_emv) - * [tradingview](https://www.tradingview.com/wiki/Ease_of_Movement_(EOM)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```14``` - divisor (float): Divisor. Default: ```100_000_000``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 14) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - divisor = v_pos_default(divisor, 100_000_000) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - hl_range = non_zero_range(high, low) - distance = hl2(high=high, low=low) - distance -= hl2(high=high.shift(drift), low=low.shift(drift)) - box_ratio = volume / divisor - box_ratio /= hl_range - eom = distance / box_ratio - eom = sma(eom, length=length) - - # Offset - if offset != 0: - eom = eom.shift(offset) - - # Fill - if "fillna" in kwargs: - eom.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - eom.name = f"EOM_{length}_{divisor}" - eom.category = "volume" - - return eom diff --git a/src/aiomql/ta_libs/pandas_ta/volume/kvo.py b/src/aiomql/ta_libs/pandas_ta/volume/kvo.py deleted file mode 100644 index fcf3b66..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/kvo.py +++ /dev/null @@ -1,100 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.overlap import hlc3 -from pandas_ta.utils import ( - signed_series, - v_drift, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def kvo( - high: Series, low: Series, close: Series, volume: Series, - fast: Int = None, slow: Int = None, signal: Int = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Klinger Volume Oscillator - - This indicator, by Stephen J. Klinger., attempts to predict - price reversals. - - Sources: - * [daytrading](https://www.daytrading.com/klinger-volume-oscillator) - * [investopedia](https://www.investopedia.com/terms/k/klingeroscillator.asp) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - fast (int): Fast MA period. Default: ```34``` - slow (int): Slow MA period. Default: ```55``` - signal (int): Signal period. Default: ```13``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - """ - # Validate - fast = v_pos_default(fast, 34) - slow = v_pos_default(slow, 55) - signal = v_pos_default(signal, 13) - _length = max(fast, slow) + signal - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - mamode = v_mamode(mamode, "ema") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - signed_volume = volume * signed_series(hlc3(high, low, close), -1) - sv = signed_volume.loc[signed_volume.first_valid_index():, ] - - kvo = ma(mamode, sv, length=fast) - ma(mamode, sv, length=slow) - if kvo is None or all(isnan(kvo.to_numpy())): - return # Emergency Break - - kvo_signal = ma(mamode, kvo.loc[kvo.first_valid_index():, ], length=signal) - if kvo_signal is None or all(isnan(kvo_signal.to_numpy())): - return # Emergency Break - - # Offset - if offset != 0: - kvo = kvo.shift(offset) - kvo_signal = kvo_signal.shift(offset) - - # Fill - if "fillna" in kwargs: - kvo.fillna(kwargs["fillna"], inplace=True) - kvo_signal.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{fast}_{slow}_{signal}" - kvo.name = f"KVO{_props}" - kvo_signal.name = f"KVOs{_props}" - kvo.category = kvo_signal.category = "volume" - - data = {kvo.name: kvo, kvo_signal.name: kvo_signal} - df = DataFrame(data, index=close.index) - df.name = f"KVO{_props}" - df.category = kvo.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volume/mfi.py b/src/aiomql/ta_libs/pandas_ta/volume/mfi.py deleted file mode 100644 index 061d3b2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/mfi.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -from sys import float_info as sflt -from numpy import convolve, maximum, nan, ones, roll, where -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.overlap import hlc3 -from pandas_ta.utils import ( - nb_nonzero_range, - v_drift, - v_offset, - v_pos_default, - v_series, - v_talib -) - - - -def mfi( - high: Series, low: Series, close: Series, volume: Series, - length: Int = None, talib: bool = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Money Flow Index - - This indicator is an oscillator that attempts to quantify buying and - selling pressure. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Money_Flow_(MFI)) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```14``` - talib (bool): If installed, use TA Lib. Default: ```True``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Warning: - TA-Lib Correlation: ```np.float64(0.9959302104966524)``` - - Tip: - Corrective contributions welcome! - """ - # Validate - length = v_pos_default(length, 14) - _length = length + 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - mode_tal = v_talib(talib) - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import MFI - mfi = MFI(high, low, close, volume, length) - else: - m, _ones = close.size, ones(length) - - tp = (high.to_numpy() + low.to_numpy() + close.to_numpy()) / 3.0 - smf = tp * volume.to_numpy() * where(tp > roll(tp, shift=drift), 1, -1) - - pos, neg = maximum(smf, 0), maximum(-smf, 0) - avg_gain, avg_loss = convolve(pos, _ones)[:m], convolve(neg, _ones)[:m] - - _mfi = (100.0 * avg_gain) / (avg_gain + avg_loss + sflt.epsilon) - _mfi[:length] = nan - - mfi = Series(_mfi, index=close.index) - - # Offset - if offset != 0: - mfi = mfi.shift(offset) - - # Fill - if "fillna" in kwargs: - mfi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - mfi.name = f"MFI_{length}" - mfi.category = "volume" - - return mfi diff --git a/src/aiomql/ta_libs/pandas_ta/volume/nvi.py b/src/aiomql/ta_libs/pandas_ta/volume/nvi.py deleted file mode 100644 index 12427cb..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/nvi.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.momentum import roc -from pandas_ta.utils import signed_series, v_offset, v_pos_default, v_series - - - -def nvi( - close: Series, volume: Series, length: Int = None, initial: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Negative Volume Index - - This indicator attempts to identify where smart money is active. - - Sources: - * [motivewave](https://www.motivewave.com/studies/negative_volume_index.htm) - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:negative_volume_inde) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```13``` - initial (int): Initial value. Default: ```1000``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: - Commonly paired with [pvi](volume.md/#src.pandas_ta.volume.pvi.pvi) - """ - # Validate - length = v_pos_default(length, 1) - close = v_series(close, length + 1) - volume = v_series(volume, length + 1) - - if close is None or volume is None: - return - - initial = v_pos_default(initial, 1000) - offset = v_offset(offset) - - # Calculate - roc_ = roc(close=close, length=length) - signed_volume = signed_series(volume, 1) - nvi = signed_volume[signed_volume < 0].abs() * roc_ - nvi.fillna(0, inplace=True) - nvi.iloc[0] = initial - nvi = nvi.cumsum() - - # Offset - if offset != 0: - nvi = nvi.shift(offset) - - # Fill - if "fillna" in kwargs: - nvi.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - nvi.name = f"NVI_{length}" - nvi.category = "volume" - - return nvi diff --git a/src/aiomql/ta_libs/pandas_ta/volume/obv.py b/src/aiomql/ta_libs/pandas_ta/volume/obv.py deleted file mode 100644 index 5118581..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/obv.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.maps import Imports -from pandas_ta.utils import signed_series, v_offset, v_series, v_talib - - - -def obv( - close: Series, volume: Series, talib: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """On Balance Volume - - This indicator attempts to quantify buying and selling pressure. - - Sources: - * [motivewave](https://www.motivewave.com/studies/on_balance_volume.htm) - * [tradingtechnologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/on-balance-volume-obv/) - * [tradingview](https://www.tradingview.com/wiki/On_Balance_Volume_(OBV)) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - talib (bool): If installed, use TA Lib. Default: ```True``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - _length = 1 - close = v_series(close, _length) - volume = v_series(volume, _length) - - if close is None or volume is None: - return - - mode_tal = v_talib(talib) - offset = v_offset(offset) - - # Calculate - if Imports["talib"] and mode_tal: - from talib import OBV - obv = OBV(close, volume) - else: - sv = signed_series(close, initial=1) * volume - obv = sv.cumsum() - - # Offset - if offset != 0: - obv = obv.shift(offset) - - # Fill - if "fillna" in kwargs: - obv.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - obv.name = f"OBV" - obv.category = "volume" - - return obv diff --git a/src/aiomql/ta_libs/pandas_ta/volume/pvi.py b/src/aiomql/ta_libs/pandas_ta/volume/pvi.py deleted file mode 100644 index 31d639b..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/pvi.py +++ /dev/null @@ -1,111 +0,0 @@ -# -*- coding: utf-8 -*- -from numba import njit -from numpy import empty, float64, zeros_like -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_bool, - v_mamode, - v_offset, - v_pos_default, - v_series -) - - -@njit(cache=True) -def nb_pvi(np_close, np_volume, initial): - result = zeros_like(np_close, dtype=float64) - result[0] = initial - - m = np_close.size - for i in range(1, m): - if np_volume[i] > np_volume[i - 1]: - result[i] = result[i - i] * (np_close[i] / np_close[i - 1]) - else: - result[i] = result[i - i] - - return result - - - -def pvi( - close: Series, volume: Series, length: Int = None, initial: Int = None, - mamode: str = None, overlay: bool = None, offset: Int = None, - **kwargs: DictLike -) -> DataFrame: - """Positive Volume Index - - This indicator attempts to identify where smart money is active. - - Sources: - * [investopedia](https://www.investopedia.com/terms/p/pvi.asp) - * [sierrachart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=101) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```255``` - initial (int): Initial value. Default: ```100``` - mamode (str): See ```help(ta.ma)```. Default: ```"ema"``` - overlay (bool): Overlay ```initial```. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 2 columns - - Note: - Commonly paired with [nvi](volume.md/#src.pandas_ta.volume.nvi.nvi) - """ - # Validate - length = v_pos_default(length, 255) - close = v_series(close, length + 1) - volume = v_series(volume, length + 1) - - if close is None or volume is None: - return - - mamode = v_mamode(mamode, "ema") - overlay = v_bool(overlay, False) - if overlay: - initial = close.iloc[0] - initial = v_pos_default(initial, 100) - offset = v_offset(offset) - - # Calculate - np_close, np_volume = close.to_numpy(), volume.to_numpy() - _pvi = nb_pvi(np_close, np_volume, initial) - - pvi = Series(_pvi, index=close.index) - pvi_ma = ma(mamode, pvi, length=length) - - # Offset - if offset != 0: - pvi = pvi.shift(offset) - pvi_ma = pvi_ma.shift(offset) - - # Fill - if "fillna" in kwargs: - pvi.fillna(kwargs["fillna"], inplace=True) - pvi_ma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _mode = mamode.lower()[0] if len(mamode) else "" - _props = f"{_mode}_{length}" - pvi.name = f"PVI" - pvi_ma.name = f"PVI{_props}" - pvi.category = pvi_ma.category = "volume" - - data = { pvi.name: pvi} - if np_close.size > length + 1: - data[pvi_ma.name] = pvi_ma - df = DataFrame(data, index=close.index) - - # Name and Category - df.name = pvi.name - df.category = pvi.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volume/pvo.py b/src/aiomql/ta_libs/pandas_ta/volume/pvo.py deleted file mode 100644 index 61ef69a..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/pvo.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, IntFloat -from pandas_ta.overlap import ema -from pandas_ta.utils import v_offset, v_pos_default, v_scalar, v_series - - - -def pvo( - volume: Series, fast: Int = None, slow: Int = None, - signal: Int = None, scalar: IntFloat = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Percentage Volume Oscillator - - This indicator is a volume momentum oscillator. - - Sources: - * [fmlabs](https://www.fmlabs.com/reference/default.htm?url=PVO.htm) - - Parameters: - volume (pd.Series): ```volume``` Series - fast (int): Fast MA period. Default: ```12``` - slow (int): Slow MA period. Default: ```26``` - signal (int): Signal period. Default: ```9``` - scalar (float): Scalar. Default: ```100``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - """ - # Validate - fast = v_pos_default(fast, 12) - slow = v_pos_default(slow, 26) - signal = v_pos_default(signal, 9) - if slow < fast: - fast, slow = slow, fast - volume = v_series(volume, max(fast, slow, signal)) - - if volume is None: - return - - scalar = v_scalar(scalar, 100) - offset = v_offset(offset) - - # Calculate - fastma = ema(volume, length=fast) - slowma = ema(volume, length=slow) - pvo = scalar * (fastma - slowma) / slowma - - signalma = ema(pvo, length=signal) - histogram = pvo - signalma - - # Offset - if offset != 0: - pvo = pvo.shift(offset) - histogram = histogram.shift(offset) - signalma = signalma.shift(offset) - - # Fill - if "fillna" in kwargs: - pvo.fillna(kwargs["fillna"], inplace=True) - histogram.fillna(kwargs["fillna"], inplace=True) - signalma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{fast}_{slow}_{signal}" - pvo.name = f"PVO{_props}" - histogram.name = f"PVOh{_props}" - signalma.name = f"PVOs{_props}" - pvo.category = histogram.category = signalma.category = "momentum" - - data = {pvo.name: pvo, histogram.name: histogram, signalma.name: signalma} - df = DataFrame(data, index=volume.index) - df.name = pvo.name - df.category = pvo.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volume/pvol.py b/src/aiomql/ta_libs/pandas_ta/volume/pvol.py deleted file mode 100644 index 4d4a129..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/pvol.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import signed_series, v_bool, v_offset, v_series - - - -def pvol( - close: Series, volume: Series, signed: bool = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Price-Volume - - This indicator returns the product of Price & Volume (Price * Volume). - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - signed (bool): Return with signs. Default: ```False``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - close = v_series(close) - volume = v_series(volume) - signed = v_bool(signed, False) - offset = v_offset(offset) - - # Calculate - pvol = close * volume - if signed: - pvol *= signed_series(close, 1) - - # Offset - if offset != 0: - pvol = pvol.shift(offset) - - # Fill - if "fillna" in kwargs: - pvol.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pvol.name = f"PVOL" - pvol.category = "volume" - - return pvol diff --git a/src/aiomql/ta_libs/pandas_ta/volume/pvr.py b/src/aiomql/ta_libs/pandas_ta/volume/pvr.py deleted file mode 100644 index 3a7607e..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/pvr.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import nan -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import v_drift, v_series - - - -def pvr( - close: Series, volume: Series, - drift: Int = None, **kwargs: DictLike -) -> Series: - """Price Volume Rank - - This indicator, by Anthony J. Macek, is a simple rank computation with - close and volume values. - - Sources: - * Anthony J. Macek, June, 1994 issue of Technical Analysis of - Stocks & Commodities (TASC) Magazine - * [fmlabs](https://www.fmlabs.com/reference/default.htm?url=PVrank.htm) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - drift (int): Difference amount. Default: ```1``` - - Returns: - (pd.Series): 1 column - - Note: Signals - - Buy < 2.5 - - Sell > 2.5 - """ - # Validate - drift = v_drift(drift) - close = v_series(close, drift) - volume = v_series(volume, drift) - - if close is None or volume is None: - return - - # Calculate - close_diff = close.diff(drift).fillna(0) - volume_diff = volume.diff(drift).fillna(0) - - pvr = Series(nan, index=close.index) - - pvr.loc[(close_diff >= 0) & (volume_diff >= 0)] = 1 - pvr.loc[(close_diff >= 0) & (volume_diff < 0)] = 2 - pvr.loc[(close_diff < 0) & (volume_diff >= 0)] = 3 - pvr.loc[(close_diff < 0) & (volume_diff < 0)] = 4 - - # Name and Category - pvr.name = f"PVR" - pvr.category = "volume" - - return pvr diff --git a/src/aiomql/ta_libs/pandas_ta/volume/pvt.py b/src/aiomql/ta_libs/pandas_ta/volume/pvt.py deleted file mode 100644 index f6fe865..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/pvt.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.momentum import roc -from pandas_ta.utils import v_drift, v_offset, v_series - - - -def pvt( - close: Series, volume: Series, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Price-Volume Trend - - This indicator attempts to quantify money flow. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Price_Volume_Trend_(PVT)) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - drift = v_drift(drift) - _drift = drift + 1 - close = v_series(close, _drift) - volume = v_series(volume, _drift) - - if close is None or volume is None: - return - - offset = v_offset(offset) - - # Calculate - pv = roc(close=close, length=drift) * volume - pvt = pv.cumsum() - - # Offset - if offset != 0: - pvt = pvt.shift(offset) - - # Fill - if "fillna" in kwargs: - pvt.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - pvt.name = f"PVT" - pvt.category = "volume" - - return pvt diff --git a/src/aiomql/ta_libs/pandas_ta/volume/tsv.py b/src/aiomql/ta_libs/pandas_ta/volume/tsv.py deleted file mode 100644 index 1f9d945..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/tsv.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -from numpy import isnan -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - signed_series, - v_drift, - v_mamode, - v_pos_default, - v_offset, - v_series, - zero -) - - - -def tsv( - close: Series, volume: Series, - length: Int = None, signal: Int = None, - mamode: str = None, drift: Int = None, - offset: Int = None, **kwargs: DictLike -) -> DataFrame: - """Time Segmented Value - - This indicator, by Worden Brothers Inc., attempts to quantify the amount - of money flowing at various time segments of price and time; similar to - On Balance Volume. - - Sources: - * [tc2000](https://help.tc2000.com/m/69404/l/747088-time-segmented-volume) - * [tradingview](https://www.tradingview.com/script/6GR4ht9X-Time-Segmented-Volume/) - * [usethinkscript](https://usethinkscript.com/threads/time-segmented-volume-for-thinkorswim.519/) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```18``` - signal (int): Signal period. Default: ```10``` - mamode (str): See ```help(ta.ma)```. Default: ```"sma"``` - drift (int): Difference amount. Default: ```1``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 3 columns - - Note: - * The zero line is called the baseline. - * Entries and exits signals occur when crossing the baseline. - """ - # Validate - length = v_pos_default(length, 18) - signal = v_pos_default(signal, 10) - _length = max(length, signal) + 1 - close = v_series(close, _length) - - if close is None: - return - - mamode = v_mamode(mamode, "sma") - drift = v_drift(drift) - offset = v_offset(offset) - - # Calculate - signed_volume = volume * signed_series(close, 1) # > 0 - signed_volume[signed_volume < 0] = -signed_volume # < 0 - signed_volume.apply(zero) # ~ 0 - cvd = signed_volume * close.diff(drift) - - tsv = cvd.rolling(length).sum() - if all(isnan(tsv)): - return # Emergency Break - - signal_ = ma(mamode, tsv, length=signal) - ratio = tsv / signal_ - - # Offset - if offset != 0: - tsv = tsv.shift(offset) - signal_ = signal.shift(offset) - ratio = ratio.shift(offset) - - # Fill - if "fillna" in kwargs: - tsv.fillna(kwargs["fillna"], inplace=True) - signal_.fillna(kwargs["fillna"], inplace=True) - ratio.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"_{length}_{signal}" - tsv.name = f"TSV{_props}" - signal_.name = f"TSVs{_props}" - ratio.name = f"TSVr{_props}" - tsv.category = signal_.category = ratio.category = "volume" - - data = {tsv.name: tsv, signal_.name: signal_, ratio.name: ratio} - df = DataFrame(data, index=close.index) - df.name = f"TSV{_props}" - df.category = tsv.category - - return df diff --git a/src/aiomql/ta_libs/pandas_ta/volume/vhm.py b/src/aiomql/ta_libs/pandas_ta/volume/vhm.py deleted file mode 100644 index d8879d2..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/vhm.py +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: utf-8 -*- -from statistics import pstdev -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.ma import ma -from pandas_ta.utils import ( - v_mamode, - v_offset, - v_pos_default, - v_series -) - - - -def vhm( - volume: Series, length: Int = None, std_length = None, - mamode: str = None, offset: Int = None, **kwargs: DictLike - ) -> Series: - """Volume Heatmap - - This indicator attempts to quantify volume trend strength of - specified length. - - Sources: - * [tradingview](https://www.tradingview.com/script/unWex8N4-Heatmap-Volume-xdecow/) - - Parameters: - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```610``` - std_length (int): Standard devation. Default: ```610``` - mamode (str): Mean MA. See ```help(ta.ma)```. Default: ```"sma"``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - - Note: Signals - - Extremely Cold: ```vhm <= -0.5``` - - Cold: ```-0.5 < vhm <= 1.0``` - - Medium: ```1.0 < vhm <= 2.5``` - - Hot: ```2.5 < vhm <= 4.0``` - - Extremely Hot: ```vhm >= 4``` - """ - # Validate - length = v_pos_default(length, 610) - std_length = v_pos_default(std_length, length) - _length = max(length, std_length) - volume = v_series(volume, _length) - - if volume is None: - return - - mamode = v_mamode(mamode, "sma") - offset = v_offset(offset) - - # Calculate - mu = ma(mamode, volume, length=length) - vhm = (volume - mu) / pstdev(volume, std_length) - - # Offset - if offset != 0: - vhm = vhm.shift(offset) - - # Fill - if "fillna" in kwargs: - vhm.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - _props = f"VHM_{length}" - vhm.name = _props if length == std_length else f"{_props}_{std_length}" - vhm.category = "volume" - - return vhm diff --git a/src/aiomql/ta_libs/pandas_ta/volume/vp.py b/src/aiomql/ta_libs/pandas_ta/volume/vp.py deleted file mode 100644 index 989ac6d..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/vp.py +++ /dev/null @@ -1,129 +0,0 @@ -# -*- coding: utf-8 -*- -from warnings import simplefilter - -from numpy import array_split, mean, sum -from pandas import cut, concat, DataFrame, Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.utils import signed_series, v_bool, v_pos_default, v_series - - - -def vp( - close: Series, volume: Series, - width: Int = None, sort: bool = None, - **kwargs: DictLike -) -> DataFrame: - """Volume Profile - - This indicator attempts to quantify volume across binned price ranges of - certain width. - - Sources: - * [ranchodinero](http://www.ranchodinero.com/volume-tpo-essentials/) - * [stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:volume_by_price) - * [tradingtechnologies](https://www.tradingtechnologies.com/blog/2013/05/15/volume-at-price/) - * [tradingview](https://www.tradingview.com/wiki/Volume_Profile) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - width (int): Source distrubution count. Default: ```10``` - sort (value): Sort ```close``` before splitting into ranges. - Default: ```False``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.DataFrame): 5 columns - - Note: - * By default, sorts by date index or chronological. - * Value Area is not calculated. - - Warning: - **Volume Profile** not a Time ```Series```. It is a volume distribution - snapshot for an arbitrary ```DateTime``` Index and thus can not be - concatenated onto the existing ```DataFrame```. - - """ - # Validate - width = v_pos_default(width, 10) - close = v_series(close, width) - volume = v_series(volume, width) - - if close is None or volume is None: - return - - sort = v_bool(sort, False) - - # Calculate - signed_price = signed_series(close, 1) - pos_volume = volume * signed_price[signed_price > 0] - pos_volume.name = volume.name - neg_volume = -volume * signed_price[signed_price < 0] - neg_volume.name = volume.name - neut_volume = volume + signed_price[signed_price == 0] - neut_volume.name = volume.name - vp = concat([close, pos_volume, neg_volume, neut_volume], axis=1) - - close_col = f"{vp.columns[0]}" - high_price_col = f"high_{close_col}" - low_price_col = f"low_{close_col}" - mean_price_col = f"mean_{close_col}" - - volume_col = f"{vp.columns[1]}" - pos_volume_col = f"pos_{volume_col}" - neg_volume_col = f"neg_{volume_col}" - neut_volume_col = f"neut_{volume_col}" - total_volume_col = f"total_{volume_col}" - vp.columns = [close_col, pos_volume_col, neg_volume_col, neut_volume_col] - - simplefilter(action="ignore", category=FutureWarning) - # sort: Sort by close before splitting into ranges. Default: False - # If False, it sorts by date index or chronological versus by price - if sort: - vp[mean_price_col] = vp[close_col] - - vpdf = vp.groupby( - cut(vp[close_col], width, include_lowest=True, precision=2), - observed=False - ).agg({ - mean_price_col: mean, - pos_volume_col: sum, - neg_volume_col: sum, - neut_volume_col: sum - }) - - vpdf[low_price_col] = [x.left for x in vpdf.index] - vpdf[high_price_col] = [x.right for x in vpdf.index] - vpdf = vpdf.reset_index(drop=True) - - vpdf = vpdf[[ - low_price_col, mean_price_col, high_price_col, - pos_volume_col, neg_volume_col, neut_volume_col - ]] - else: - vp_ranges = array_split(vp, width) - result = list({ - low_price_col: r[close_col].min(), - mean_price_col: r[close_col].mean(), - high_price_col: r[close_col].max(), - pos_volume_col: r[pos_volume_col].sum(), - neg_volume_col: r[neg_volume_col].sum(), - neut_volume_col: r[neut_volume_col].sum(), - } for r in vp_ranges) - - vpdf = DataFrame(result) - - vpdf[total_volume_col] = vpdf[pos_volume_col] + vpdf[neg_volume_col] - - # Fill - if "fillna" in kwargs: - vpdf.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - vpdf.name = f"VP_{width}" - vpdf.category = "volume" - - return vpdf diff --git a/src/aiomql/ta_libs/pandas_ta/volume/vwap.py b/src/aiomql/ta_libs/pandas_ta/volume/vwap.py deleted file mode 100644 index c77b033..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/vwap.py +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: utf-8 -*- -from warnings import simplefilter -from pandas import DataFrame, Series -from pandas_ta._typing import DictLike, Int, List -from pandas_ta.overlap import hlc3 -from pandas_ta.utils import v_datetime_ordered, v_list, v_offset, v_series - - - -def vwap( - high: Series, low: Series, close: Series, volume: Series, - anchor: str = None, bands: List = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Volume Weighted Average Price - - This indicator computes the Volume Weighted Average Price. - - Sources: - * [tradingview](https://www.tradingview.com/wiki/Volume_Weighted_Average_Price_(VWAP)) - * [Trading Technologies](https://www.tradingtechnologies.com/help/x-study/technical-indicator-definitions/volume-weighted-average-price-vwap/) - * [Stockcharts](https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:vwap_intraday) - * [Sierra Chart](https://www.sierrachart.com/index.php?page=doc/StudiesReference.php&ID=108&Name=Volume_Weighted_Average_Price_-_VWAP_-_with_Standard_Deviation_Lines) - - Parameters: - high (pd.Series): ```high``` Series - low (pd.Series): ```low``` Series - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - anchor (str): VWAP Anchor. Default: ```"D"```. - bands (list): List of positive ```IntFloat``` deviations. - Default: ```[]``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series | pd.DataFrame): ```DataFrame``` when ```bands``` is set. - Default: ```Series``` - - Note: - * Commonly used with intraday charts to identify general direction. - * Depending on the index values, it will implement various - [Timeseries Offset Aliases](https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#timeseries-offset-aliases) - - Tip: - * Negative bands are computed automatically. - """ - # Validate - _length = 1 - high = v_series(high, _length) - low = v_series(low, _length) - close = v_series(close, _length) - volume = v_series(volume, _length) - - if high is None or low is None or close is None or volume is None: - return - - bands = v_list(bands) - offset = v_offset(offset) - - if anchor and isinstance(anchor, str) and len(anchor) >= 1: - anchor = anchor.upper() - else: - anchor = "D" - - typical_price = hlc3(high=high, low=low, close=close) - if not v_datetime_ordered(volume) or \ - not v_datetime_ordered(typical_price): - print("[!] VWAP requires an ordered DatetimeIndex.") - return - - # Calculate - _props = f"VWAP_{anchor}" - wp = typical_price * volume - simplefilter(action="ignore", category=UserWarning) - vwap = wp.groupby(wp.index.to_period(anchor)).cumsum() \ - / volume.groupby(volume.index.to_period(anchor)).cumsum() - - if bands and len(bands): - # Calculate vwap stdev bands - vwap_var = volume * (typical_price - vwap) ** 2 - vwap_var_sum = vwap_var \ - .groupby(vwap_var.index.to_period(anchor)).cumsum() - vwap_volume_sum = volume \ - .groupby(volume.index.to_period(anchor)).cumsum() - std_volume_weighted = (vwap_var_sum / vwap_volume_sum) ** 0.5 - - # Name and Category - vwap.name = _props - vwap.category = "overlap" - - if bands: - df = DataFrame({vwap.name: vwap}, index=close.index) - for i in bands: - df[f"{_props}_L_{i}"] = vwap - i * std_volume_weighted - df[f"{_props}_U_{i}"] = vwap + i * std_volume_weighted - df[f"{_props}_L_{i}"].name = df[f"{_props}_U_{i}"].name = _props - df[f"{_props}_L_{i}"].category = "overlap" - df[f"{_props}_U_{i}"].category = "overlap" - df.name = _props - df.category = "overlap" - - # Offset - if offset != 0: - if bands and not df.empty: - df = df.shift(offset) - vwap = vwap.shift(offset) - - # Fill - if "fillna" in kwargs: - if bands and not df.empty: - df.fillna(kwargs["fillna"], inplace=True) - else: - vwap.fillna(kwargs["fillna"], inplace=True) - - if bands and not df.empty: - return df - return vwap diff --git a/src/aiomql/ta_libs/pandas_ta/volume/vwma.py b/src/aiomql/ta_libs/pandas_ta/volume/vwma.py deleted file mode 100644 index 66d5311..0000000 --- a/src/aiomql/ta_libs/pandas_ta/volume/vwma.py +++ /dev/null @@ -1,58 +0,0 @@ -# -*- coding: utf-8 -*- -from pandas import Series -from pandas_ta._typing import DictLike, Int -from pandas_ta.overlap import sma -from pandas_ta.utils import v_offset, v_pos_default, v_series - - - -def vwma( - close: Series, volume: Series, length: Int = None, - offset: Int = None, **kwargs: DictLike -) -> Series: - """Volume Weighted Moving Average - - Computes a weighted average using price and volume. - - Sources: - * [motivewave](https://www.motivewave.com/studies/volume_weighted_moving_average.htm) - - Parameters: - close (pd.Series): ```close``` Series - volume (pd.Series): ```volume``` Series - length (int): The period. Default: ```10``` - offset (int): Post shift. Default: ```0``` - - Other Parameters: - fillna (value): ```pd.DataFrame.fillna(value)``` - - Returns: - (pd.Series): 1 column - """ - # Validate - length = v_pos_default(length, 10) - close = v_series(close, length) - volume = v_series(volume, length) - - if close is None or volume is None: - return - - offset = v_offset(offset) - - # Calculate - pv = close * volume - vwma = sma(close=pv, length=length) / sma(close=volume, length=length) - - # Offset - if offset != 0: - vwma = vwma.shift(offset) - - # Fill - if "fillna" in kwargs: - vwma.fillna(kwargs["fillna"], inplace=True) - - # Name and Category - vwma.name = f"VWMA_{length}" - vwma.category = "overlap" - - return vwma diff --git a/uv.lock b/uv.lock index 13786b5..0efeedf 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.11" resolution-markers = [ "python_full_version >= '3.14'", @@ -14,8 +14,8 @@ source = { editable = "." } dependencies = [ { name = "metatrader5" }, { name = "mplfinance" }, + { name = "numba" }, { name = "pandas" }, - { name = "pandas-stubs" }, { name = "tqdm" }, ] @@ -28,9 +28,9 @@ dev = [ [package.metadata] requires-dist = [ { name = "metatrader5", specifier = ">=5.0.5200" }, - { name = "mplfinance", specifier = ">=0.10.1" }, - { name = "pandas", specifier = ">=1.5.0" }, - { name = "pandas-stubs", specifier = "==2.3.0.250703" }, + { name = "mplfinance", specifier = ">=0.12.10b0" }, + { name = "numba", specifier = ">=0.61.2" }, + { name = "pandas", specifier = ">=2.0.0" }, { name = "tqdm", specifier = ">=4.67.1" }, ] @@ -49,18 +49,18 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload_time = "2025-08-04T08:54:26.451Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload_time = "2025-08-04T08:54:24.882Z" }, ] [[package]] name = "appnope" version = "0.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload-time = "2024-02-06T09:43:11.258Z" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170, upload_time = "2024-02-06T09:43:11.258Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload-time = "2024-02-06T09:43:09.663Z" }, + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321, upload_time = "2024-02-06T09:43:09.663Z" }, ] [[package]] @@ -71,9 +71,9 @@ dependencies = [ { name = "argon2-cffi-bindings", version = "21.2.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.14'" }, { name = "argon2-cffi-bindings", version = "25.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.14'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload_time = "2025-06-03T06:55:32.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload_time = "2025-06-03T06:55:30.804Z" }, ] [[package]] @@ -86,18 +86,18 @@ resolution-markers = [ dependencies = [ { name = "cffi", marker = "python_full_version >= '3.14'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911, upload-time = "2021-12-01T08:52:55.68Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911, upload_time = "2021-12-01T08:52:55.68Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658, upload-time = "2021-12-01T09:09:17.016Z" }, - { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583, upload-time = "2021-12-01T09:09:19.546Z" }, - { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168, upload-time = "2021-12-01T09:09:21.445Z" }, - { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709, upload-time = "2021-12-01T09:09:18.182Z" }, - { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613, upload-time = "2021-12-01T09:09:22.741Z" }, - { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583, upload-time = "2021-12-01T09:09:24.177Z" }, - { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475, upload-time = "2021-12-01T09:09:26.673Z" }, - { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698, upload-time = "2021-12-01T09:09:27.87Z" }, - { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817, upload-time = "2021-12-01T09:09:30.267Z" }, - { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104, upload-time = "2021-12-01T09:09:31.335Z" }, + { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658, upload_time = "2021-12-01T09:09:17.016Z" }, + { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583, upload_time = "2021-12-01T09:09:19.546Z" }, + { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168, upload_time = "2021-12-01T09:09:21.445Z" }, + { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709, upload_time = "2021-12-01T09:09:18.182Z" }, + { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613, upload_time = "2021-12-01T09:09:22.741Z" }, + { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583, upload_time = "2021-12-01T09:09:24.177Z" }, + { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475, upload_time = "2021-12-01T09:09:26.673Z" }, + { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698, upload_time = "2021-12-01T09:09:27.87Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817, upload_time = "2021-12-01T09:09:30.267Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104, upload_time = "2021-12-01T09:09:31.335Z" }, ] [[package]] @@ -111,28 +111,28 @@ resolution-markers = [ dependencies = [ { name = "cffi", marker = "python_full_version < '3.14'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload_time = "2025-07-30T10:02:05.147Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393, upload-time = "2025-07-30T10:01:40.97Z" }, - { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328, upload-time = "2025-07-30T10:01:41.916Z" }, - { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269, upload-time = "2025-07-30T10:01:42.716Z" }, - { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558, upload-time = "2025-07-30T10:01:43.943Z" }, - { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364, upload-time = "2025-07-30T10:01:44.887Z" }, - { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637, upload-time = "2025-07-30T10:01:46.225Z" }, - { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934, upload-time = "2025-07-30T10:01:47.203Z" }, - { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158, upload-time = "2025-07-30T10:01:48.341Z" }, - { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597, upload-time = "2025-07-30T10:01:49.112Z" }, - { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231, upload-time = "2025-07-30T10:01:49.92Z" }, - { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload-time = "2025-07-30T10:01:50.815Z" }, - { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload-time = "2025-07-30T10:01:51.681Z" }, - { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload-time = "2025-07-30T10:01:53.184Z" }, - { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, - { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, - { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, - { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, - { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload-time = "2025-07-30T10:01:57.759Z" }, - { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload-time = "2025-07-30T10:01:58.56Z" }, - { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload-time = "2025-07-30T10:01:59.329Z" }, + { url = "https://files.pythonhosted.org/packages/60/97/3c0a35f46e52108d4707c44b95cfe2afcafc50800b5450c197454569b776/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:3d3f05610594151994ca9ccb3c771115bdb4daef161976a266f0dd8aa9996b8f", size = 54393, upload_time = "2025-07-30T10:01:40.97Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f4/98bbd6ee89febd4f212696f13c03ca302b8552e7dbf9c8efa11ea4a388c3/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8b8efee945193e667a396cbc7b4fb7d357297d6234d30a489905d96caabde56b", size = 29328, upload_time = "2025-07-30T10:01:41.916Z" }, + { url = "https://files.pythonhosted.org/packages/43/24/90a01c0ef12ac91a6be05969f29944643bc1e5e461155ae6559befa8f00b/argon2_cffi_bindings-25.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3c6702abc36bf3ccba3f802b799505def420a1b7039862014a65db3205967f5a", size = 31269, upload_time = "2025-07-30T10:01:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558, upload_time = "2025-07-30T10:01:43.943Z" }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364, upload_time = "2025-07-30T10:01:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637, upload_time = "2025-07-30T10:01:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934, upload_time = "2025-07-30T10:01:47.203Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c7/f36bd08ef9bd9f0a9cff9428406651f5937ce27b6c5b07b92d41f91ae541/argon2_cffi_bindings-25.1.0-cp314-cp314t-win32.whl", hash = "sha256:84a461d4d84ae1295871329b346a97f68eade8c53b6ed9a7ca2d7467f3c8ff6f", size = 28158, upload_time = "2025-07-30T10:01:48.341Z" }, + { url = "https://files.pythonhosted.org/packages/b3/80/0106a7448abb24a2c467bf7d527fe5413b7fdfa4ad6d6a96a43a62ef3988/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b55aec3565b65f56455eebc9b9f34130440404f27fe21c3b375bf1ea4d8fbae6", size = 32597, upload_time = "2025-07-30T10:01:49.112Z" }, + { url = "https://files.pythonhosted.org/packages/05/b8/d663c9caea07e9180b2cb662772865230715cbd573ba3b5e81793d580316/argon2_cffi_bindings-25.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:87c33a52407e4c41f3b70a9c2d3f6056d88b10dad7695be708c5021673f55623", size = 28231, upload_time = "2025-07-30T10:01:49.92Z" }, + { url = "https://files.pythonhosted.org/packages/1d/57/96b8b9f93166147826da5f90376e784a10582dd39a393c99bb62cfcf52f0/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:aecba1723ae35330a008418a91ea6cfcedf6d31e5fbaa056a166462ff066d500", size = 54121, upload_time = "2025-07-30T10:01:50.815Z" }, + { url = "https://files.pythonhosted.org/packages/0a/08/a9bebdb2e0e602dde230bdde8021b29f71f7841bd54801bcfd514acb5dcf/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2630b6240b495dfab90aebe159ff784d08ea999aa4b0d17efa734055a07d2f44", size = 29177, upload_time = "2025-07-30T10:01:51.681Z" }, + { url = "https://files.pythonhosted.org/packages/b6/02/d297943bcacf05e4f2a94ab6f462831dc20158614e5d067c35d4e63b9acb/argon2_cffi_bindings-25.1.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:7aef0c91e2c0fbca6fc68e7555aa60ef7008a739cbe045541e438373bc54d2b0", size = 31090, upload_time = "2025-07-30T10:01:53.184Z" }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload_time = "2025-07-30T10:01:54.145Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload_time = "2025-07-30T10:01:55.074Z" }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload_time = "2025-07-30T10:01:56.007Z" }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload_time = "2025-07-30T10:01:56.943Z" }, + { url = "https://files.pythonhosted.org/packages/74/cd/15777dfde1c29d96de7f18edf4cc94c385646852e7c7b0320aa91ccca583/argon2_cffi_bindings-25.1.0-cp39-abi3-win32.whl", hash = "sha256:473bcb5f82924b1becbb637b63303ec8d10e84c8d241119419897a26116515d2", size = 27180, upload_time = "2025-07-30T10:01:57.759Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/a759ece8f1829d1f162261226fbfd2c6832b3ff7657384045286d2afa384/argon2_cffi_bindings-25.1.0-cp39-abi3-win_amd64.whl", hash = "sha256:a98cd7d17e9f7ce244c0803cad3c23a7d379c301ba618a5fa76a67d116618b98", size = 31715, upload_time = "2025-07-30T10:01:58.56Z" }, + { url = "https://files.pythonhosted.org/packages/42/b9/f8d6fa329ab25128b7e98fd83a3cb34d9db5b059a9847eddb840a0af45dd/argon2_cffi_bindings-25.1.0-cp39-abi3-win_arm64.whl", hash = "sha256:b0fdbcf513833809c882823f98dc2f931cf659d9a1429616ac3adebb49f5db94", size = 27149, upload_time = "2025-07-30T10:01:59.329Z" }, ] [[package]] @@ -143,45 +143,45 @@ dependencies = [ { name = "python-dateutil" }, { name = "types-python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload_time = "2023-09-30T22:11:18.25Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload_time = "2023-09-30T22:11:16.072Z" }, ] [[package]] name = "asttokens" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload-time = "2024-11-30T04:30:14.439Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978, upload_time = "2024-11-30T04:30:14.439Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload-time = "2024-11-30T04:30:10.946Z" }, + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918, upload_time = "2024-11-30T04:30:10.946Z" }, ] [[package]] name = "async-lru" version = "2.0.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/4d/71ec4d3939dc755264f680f6c2b4906423a304c3d18e96853f0a595dfe97/async_lru-2.0.5.tar.gz", hash = "sha256:481d52ccdd27275f42c43a928b4a50c3bfb2d67af4e78b170e3e0bb39c66e5bb", size = 10380, upload-time = "2025-03-16T17:25:36.919Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/4d/71ec4d3939dc755264f680f6c2b4906423a304c3d18e96853f0a595dfe97/async_lru-2.0.5.tar.gz", hash = "sha256:481d52ccdd27275f42c43a928b4a50c3bfb2d67af4e78b170e3e0bb39c66e5bb", size = 10380, upload_time = "2025-03-16T17:25:36.919Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl", hash = "sha256:ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943", size = 6069, upload-time = "2025-03-16T17:25:35.422Z" }, + { url = "https://files.pythonhosted.org/packages/03/49/d10027df9fce941cb8184e78a02857af36360d33e1721df81c5ed2179a1a/async_lru-2.0.5-py3-none-any.whl", hash = "sha256:ab95404d8d2605310d345932697371a5f40def0487c03d6d0ad9138de52c9943", size = 6069, upload_time = "2025-03-16T17:25:35.422Z" }, ] [[package]] name = "attrs" version = "25.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload_time = "2025-03-13T11:10:22.779Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload_time = "2025-03-13T11:10:21.14Z" }, ] [[package]] name = "babel" version = "2.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload_time = "2025-02-01T15:17:41.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload_time = "2025-02-01T15:17:37.39Z" }, ] [[package]] @@ -192,9 +192,9 @@ dependencies = [ { name = "soupsieve" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload_time = "2025-04-15T17:05:13.836Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload_time = "2025-04-15T17:05:12.221Z" }, ] [[package]] @@ -204,9 +204,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083, upload-time = "2024-10-29T18:30:40.477Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083, upload_time = "2024-10-29T18:30:40.477Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406, upload-time = "2024-10-29T18:30:38.186Z" }, + { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406, upload_time = "2024-10-29T18:30:38.186Z" }, ] [package.optional-dependencies] @@ -218,9 +218,9 @@ css = [ name = "certifi" version = "2025.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload_time = "2025-08-03T03:07:47.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload_time = "2025-08-03T03:07:45.777Z" }, ] [[package]] @@ -230,113 +230,113 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload_time = "2024-09-04T20:45:21.852Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload-time = "2024-09-04T20:43:51.124Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload-time = "2024-09-04T20:43:52.872Z" }, - { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, - { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, - { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, - { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, - { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, - { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, - { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, - { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload-time = "2024-09-04T20:44:09.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload-time = "2024-09-04T20:44:10.873Z" }, - { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload-time = "2024-09-04T20:44:12.232Z" }, - { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload-time = "2024-09-04T20:44:13.739Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, - { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, - { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, - { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, - { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload-time = "2024-09-04T20:44:26.208Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" }, - { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, - { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, - { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, - { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, - { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264, upload_time = "2024-09-04T20:43:51.124Z" }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651, upload_time = "2024-09-04T20:43:52.872Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload_time = "2024-09-04T20:43:56.123Z" }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload_time = "2024-09-04T20:43:57.891Z" }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload_time = "2024-09-04T20:44:00.18Z" }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload_time = "2024-09-04T20:44:01.585Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload_time = "2024-09-04T20:44:03.467Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload_time = "2024-09-04T20:44:05.023Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload_time = "2024-09-04T20:44:06.444Z" }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload_time = "2024-09-04T20:44:08.206Z" }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727, upload_time = "2024-09-04T20:44:09.481Z" }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400, upload_time = "2024-09-04T20:44:10.873Z" }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178, upload_time = "2024-09-04T20:44:12.232Z" }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840, upload_time = "2024-09-04T20:44:13.739Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload_time = "2024-09-04T20:44:15.231Z" }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload_time = "2024-09-04T20:44:17.188Z" }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload_time = "2024-09-04T20:44:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload_time = "2024-09-04T20:44:20.248Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload_time = "2024-09-04T20:44:21.673Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload_time = "2024-09-04T20:44:23.245Z" }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload_time = "2024-09-04T20:44:24.757Z" }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448, upload_time = "2024-09-04T20:44:26.208Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload_time = "2024-09-04T20:44:27.578Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload_time = "2024-09-04T20:44:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload_time = "2024-09-04T20:44:30.289Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload_time = "2024-09-04T20:44:32.01Z" }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload_time = "2024-09-04T20:44:33.606Z" }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload_time = "2024-09-04T20:44:35.191Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload_time = "2024-09-04T20:44:36.743Z" }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload_time = "2024-09-04T20:44:38.492Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload_time = "2024-09-04T20:44:40.046Z" }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload_time = "2024-09-04T20:44:41.616Z" }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload_time = "2024-09-04T20:44:43.733Z" }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload_time = "2024-09-04T20:44:45.309Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload_time = "2025-08-09T07:57:28.46Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, - { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, - { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, - { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, - { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, - { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, - { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, - { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, - { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, - { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, - { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, - { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, - { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, - { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, - { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, - { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, - { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, - { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, - { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload_time = "2025-08-09T07:55:53.12Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload_time = "2025-08-09T07:55:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload_time = "2025-08-09T07:55:56.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload_time = "2025-08-09T07:55:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload_time = "2025-08-09T07:55:59.147Z" }, + { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload_time = "2025-08-09T07:56:00.364Z" }, + { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload_time = "2025-08-09T07:56:01.678Z" }, + { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload_time = "2025-08-09T07:56:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload_time = "2025-08-09T07:56:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload_time = "2025-08-09T07:56:05.658Z" }, + { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload_time = "2025-08-09T07:56:07.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload_time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload_time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload_time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload_time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload_time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload_time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload_time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload_time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload_time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload_time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload_time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload_time = "2025-08-09T07:56:24.721Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload_time = "2025-08-09T07:56:26.004Z" }, + { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload_time = "2025-08-09T07:56:27.25Z" }, + { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload_time = "2025-08-09T07:56:28.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload_time = "2025-08-09T07:56:29.716Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload_time = "2025-08-09T07:56:30.984Z" }, + { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload_time = "2025-08-09T07:56:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload_time = "2025-08-09T07:56:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload_time = "2025-08-09T07:56:34.739Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload_time = "2025-08-09T07:56:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload_time = "2025-08-09T07:56:37.339Z" }, + { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload_time = "2025-08-09T07:56:38.687Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload_time = "2025-08-09T07:56:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload_time = "2025-08-09T07:56:41.311Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload_time = "2025-08-09T07:56:43.195Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload_time = "2025-08-09T07:56:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload_time = "2025-08-09T07:56:46.684Z" }, + { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload_time = "2025-08-09T07:56:47.941Z" }, + { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload_time = "2025-08-09T07:56:49.756Z" }, + { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload_time = "2025-08-09T07:56:51.369Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload_time = "2025-08-09T07:56:52.722Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload_time = "2025-08-09T07:56:55.172Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload_time = "2025-08-09T07:57:26.864Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload_time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload_time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "comm" version = "0.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload_time = "2025-07-25T14:02:04.452Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload_time = "2025-07-25T14:02:02.896Z" }, ] [[package]] @@ -346,196 +346,196 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload_time = "2025-07-26T12:03:12.549Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload-time = "2025-07-26T12:01:02.277Z" }, - { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload-time = "2025-07-26T12:01:04.072Z" }, - { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload-time = "2025-07-26T12:01:05.688Z" }, - { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload-time = "2025-07-26T12:01:07.054Z" }, - { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload-time = "2025-07-26T12:01:08.801Z" }, - { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload-time = "2025-07-26T12:01:10.319Z" }, - { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload-time = "2025-07-26T12:01:12.659Z" }, - { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload-time = "2025-07-26T12:01:15.533Z" }, - { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload-time = "2025-07-26T12:01:17.088Z" }, - { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload-time = "2025-07-26T12:01:18.256Z" }, - { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload-time = "2025-07-26T12:01:19.848Z" }, - { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload-time = "2025-07-26T12:01:21.16Z" }, - { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload-time = "2025-07-26T12:01:22.448Z" }, - { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, - { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, - { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, - { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, - { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, - { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, - { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload-time = "2025-07-26T12:01:35.64Z" }, - { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload-time = "2025-07-26T12:01:36.804Z" }, - { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload-time = "2025-07-26T12:01:37.999Z" }, - { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload-time = "2025-07-26T12:01:39.367Z" }, - { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload-time = "2025-07-26T12:01:40.645Z" }, - { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, - { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, - { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, - { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, - { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, - { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, - { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload-time = "2025-07-26T12:01:53.245Z" }, - { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload-time = "2025-07-26T12:01:54.422Z" }, - { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload-time = "2025-07-26T12:01:55.73Z" }, - { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload-time = "2025-07-26T12:01:57.051Z" }, - { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload-time = "2025-07-26T12:01:58.663Z" }, - { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, - { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, - { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, - { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, - { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, - { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload-time = "2025-07-26T12:02:11.488Z" }, - { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload-time = "2025-07-26T12:02:12.754Z" }, - { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload-time = "2025-07-26T12:02:14.4Z" }, - { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload-time = "2025-07-26T12:02:16.095Z" }, - { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload-time = "2025-07-26T12:02:17.524Z" }, - { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, - { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, - { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, - { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, - { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, - { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload-time = "2025-07-26T12:02:30.128Z" }, - { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload-time = "2025-07-26T12:02:31.395Z" }, - { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload-time = "2025-07-26T12:02:32.956Z" }, - { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload-time = "2025-07-26T12:02:34.2Z" }, - { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload-time = "2025-07-26T12:02:35.807Z" }, - { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, - { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, - { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, - { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, - { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, - { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, - { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload-time = "2025-07-26T12:02:48.691Z" }, - { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload-time = "2025-07-26T12:02:50.137Z" }, - { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload-time = "2025-07-26T12:02:51.449Z" }, - { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload-time = "2025-07-26T12:02:52.74Z" }, - { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload-time = "2025-07-26T12:02:54.037Z" }, - { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload-time = "2025-07-26T12:02:55.947Z" }, - { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload-time = "2025-07-26T12:02:57.468Z" }, - { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload-time = "2025-07-26T12:02:58.801Z" }, + { url = "https://files.pythonhosted.org/packages/91/2e/c4390a31919d8a78b90e8ecf87cd4b4c4f05a5b48d05ec17db8e5404c6f4/contourpy-1.3.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:709a48ef9a690e1343202916450bc48b9e51c049b089c7f79a267b46cffcdaa1", size = 288773, upload_time = "2025-07-26T12:01:02.277Z" }, + { url = "https://files.pythonhosted.org/packages/0d/44/c4b0b6095fef4dc9c420e041799591e3b63e9619e3044f7f4f6c21c0ab24/contourpy-1.3.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:23416f38bfd74d5d28ab8429cc4d63fa67d5068bd711a85edb1c3fb0c3e2f381", size = 270149, upload_time = "2025-07-26T12:01:04.072Z" }, + { url = "https://files.pythonhosted.org/packages/30/2e/dd4ced42fefac8470661d7cb7e264808425e6c5d56d175291e93890cce09/contourpy-1.3.3-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:929ddf8c4c7f348e4c0a5a3a714b5c8542ffaa8c22954862a46ca1813b667ee7", size = 329222, upload_time = "2025-07-26T12:01:05.688Z" }, + { url = "https://files.pythonhosted.org/packages/f2/74/cc6ec2548e3d276c71389ea4802a774b7aa3558223b7bade3f25787fafc2/contourpy-1.3.3-cp311-cp311-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9e999574eddae35f1312c2b4b717b7885d4edd6cb46700e04f7f02db454e67c1", size = 377234, upload_time = "2025-07-26T12:01:07.054Z" }, + { url = "https://files.pythonhosted.org/packages/03/b3/64ef723029f917410f75c09da54254c5f9ea90ef89b143ccadb09df14c15/contourpy-1.3.3-cp311-cp311-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0bf67e0e3f482cb69779dd3061b534eb35ac9b17f163d851e2a547d56dba0a3a", size = 380555, upload_time = "2025-07-26T12:01:08.801Z" }, + { url = "https://files.pythonhosted.org/packages/5f/4b/6157f24ca425b89fe2eb7e7be642375711ab671135be21e6faa100f7448c/contourpy-1.3.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51e79c1f7470158e838808d4a996fa9bac72c498e93d8ebe5119bc1e6becb0db", size = 355238, upload_time = "2025-07-26T12:01:10.319Z" }, + { url = "https://files.pythonhosted.org/packages/98/56/f914f0dd678480708a04cfd2206e7c382533249bc5001eb9f58aa693e200/contourpy-1.3.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:598c3aaece21c503615fd59c92a3598b428b2f01bfb4b8ca9c4edeecc2438620", size = 1326218, upload_time = "2025-07-26T12:01:12.659Z" }, + { url = "https://files.pythonhosted.org/packages/fb/d7/4a972334a0c971acd5172389671113ae82aa7527073980c38d5868ff1161/contourpy-1.3.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:322ab1c99b008dad206d406bb61d014cf0174df491ae9d9d0fac6a6fda4f977f", size = 1392867, upload_time = "2025-07-26T12:01:15.533Z" }, + { url = "https://files.pythonhosted.org/packages/75/3e/f2cc6cd56dc8cff46b1a56232eabc6feea52720083ea71ab15523daab796/contourpy-1.3.3-cp311-cp311-win32.whl", hash = "sha256:fd907ae12cd483cd83e414b12941c632a969171bf90fc937d0c9f268a31cafff", size = 183677, upload_time = "2025-07-26T12:01:17.088Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/9bd370b004b5c9d8045c6c33cf65bae018b27aca550a3f657cdc99acdbd8/contourpy-1.3.3-cp311-cp311-win_amd64.whl", hash = "sha256:3519428f6be58431c56581f1694ba8e50626f2dd550af225f82fb5f5814d2a42", size = 225234, upload_time = "2025-07-26T12:01:18.256Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b6/71771e02c2e004450c12b1120a5f488cad2e4d5b590b1af8bad060360fe4/contourpy-1.3.3-cp311-cp311-win_arm64.whl", hash = "sha256:15ff10bfada4bf92ec8b31c62bf7c1834c244019b4a33095a68000d7075df470", size = 193123, upload_time = "2025-07-26T12:01:19.848Z" }, + { url = "https://files.pythonhosted.org/packages/be/45/adfee365d9ea3d853550b2e735f9d66366701c65db7855cd07621732ccfc/contourpy-1.3.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b08a32ea2f8e42cf1d4be3169a98dd4be32bafe4f22b6c4cb4ba810fa9e5d2cb", size = 293419, upload_time = "2025-07-26T12:01:21.16Z" }, + { url = "https://files.pythonhosted.org/packages/53/3e/405b59cfa13021a56bba395a6b3aca8cec012b45bf177b0eaf7a202cde2c/contourpy-1.3.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:556dba8fb6f5d8742f2923fe9457dbdd51e1049c4a43fd3986a0b14a1d815fc6", size = 273979, upload_time = "2025-07-26T12:01:22.448Z" }, + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload_time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload_time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload_time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload_time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload_time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload_time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8f/5847f44a7fddf859704217a99a23a4f6417b10e5ab1256a179264561540e/contourpy-1.3.3-cp312-cp312-win32.whl", hash = "sha256:023b44101dfe49d7d53932be418477dba359649246075c996866106da069af69", size = 185018, upload_time = "2025-07-26T12:01:35.64Z" }, + { url = "https://files.pythonhosted.org/packages/19/e8/6026ed58a64563186a9ee3f29f41261fd1828f527dd93d33b60feca63352/contourpy-1.3.3-cp312-cp312-win_amd64.whl", hash = "sha256:8153b8bfc11e1e4d75bcb0bff1db232f9e10b274e0929de9d608027e0d34ff8b", size = 226567, upload_time = "2025-07-26T12:01:36.804Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e2/f05240d2c39a1ed228d8328a78b6f44cd695f7ef47beb3e684cf93604f86/contourpy-1.3.3-cp312-cp312-win_arm64.whl", hash = "sha256:07ce5ed73ecdc4a03ffe3e1b3e3c1166db35ae7584be76f65dbbe28a7791b0cc", size = 193655, upload_time = "2025-07-26T12:01:37.999Z" }, + { url = "https://files.pythonhosted.org/packages/68/35/0167aad910bbdb9599272bd96d01a9ec6852f36b9455cf2ca67bd4cc2d23/contourpy-1.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:177fb367556747a686509d6fef71d221a4b198a3905fe824430e5ea0fda54eb5", size = 293257, upload_time = "2025-07-26T12:01:39.367Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/7adcd9c8362745b2210728f209bfbcf7d91ba868a2c5f40d8b58f54c509b/contourpy-1.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d002b6f00d73d69333dac9d0b8d5e84d9724ff9ef044fd63c5986e62b7c9e1b1", size = 274034, upload_time = "2025-07-26T12:01:40.645Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload_time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload_time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload_time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload_time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload_time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload_time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/a6/2e/adc197a37443f934594112222ac1aa7dc9a98faf9c3842884df9a9d8751d/contourpy-1.3.3-cp313-cp313-win32.whl", hash = "sha256:b20c7c9a3bf701366556e1b1984ed2d0cedf999903c51311417cf5f591d8c78d", size = 185024, upload_time = "2025-07-26T12:01:53.245Z" }, + { url = "https://files.pythonhosted.org/packages/18/0b/0098c214843213759692cc638fce7de5c289200a830e5035d1791d7a2338/contourpy-1.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:1cadd8b8969f060ba45ed7c1b714fe69185812ab43bd6b86a9123fe8f99c3263", size = 226578, upload_time = "2025-07-26T12:01:54.422Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9a/2f6024a0c5995243cd63afdeb3651c984f0d2bc727fd98066d40e141ad73/contourpy-1.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:fd914713266421b7536de2bfa8181aa8c699432b6763a0ea64195ebe28bff6a9", size = 193524, upload_time = "2025-07-26T12:01:55.73Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/f8a1a86bd3298513f500e5b1f5fd92b69896449f6cab6a146a5d52715479/contourpy-1.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:88df9880d507169449d434c293467418b9f6cbe82edd19284aa0409e7fdb933d", size = 306730, upload_time = "2025-07-26T12:01:57.051Z" }, + { url = "https://files.pythonhosted.org/packages/3f/11/4780db94ae62fc0c2053909b65dc3246bd7cecfc4f8a20d957ad43aa4ad8/contourpy-1.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d06bb1f751ba5d417047db62bca3c8fde202b8c11fb50742ab3ab962c81e8216", size = 287897, upload_time = "2025-07-26T12:01:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload_time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload_time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload_time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload_time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload_time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload_time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b9/70/f308384a3ae9cd2209e0849f33c913f658d3326900d0ff5d378d6a1422d2/contourpy-1.3.3-cp313-cp313t-win32.whl", hash = "sha256:283edd842a01e3dcd435b1c5116798d661378d83d36d337b8dde1d16a5fc9ba3", size = 196157, upload_time = "2025-07-26T12:02:11.488Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dd/880f890a6663b84d9e34a6f88cded89d78f0091e0045a284427cb6b18521/contourpy-1.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:87acf5963fc2b34825e5b6b048f40e3635dd547f590b04d2ab317c2619ef7ae8", size = 240570, upload_time = "2025-07-26T12:02:12.754Z" }, + { url = "https://files.pythonhosted.org/packages/80/99/2adc7d8ffead633234817ef8e9a87115c8a11927a94478f6bb3d3f4d4f7d/contourpy-1.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:3c30273eb2a55024ff31ba7d052dde990d7d8e5450f4bbb6e913558b3d6c2301", size = 199713, upload_time = "2025-07-26T12:02:14.4Z" }, + { url = "https://files.pythonhosted.org/packages/72/8b/4546f3ab60f78c514ffb7d01a0bd743f90de36f0019d1be84d0a708a580a/contourpy-1.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:fde6c716d51c04b1c25d0b90364d0be954624a0ee9d60e23e850e8d48353d07a", size = 292189, upload_time = "2025-07-26T12:02:16.095Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e1/3542a9cb596cadd76fcef413f19c79216e002623158befe6daa03dbfa88c/contourpy-1.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cbedb772ed74ff5be440fa8eee9bd49f64f6e3fc09436d9c7d8f1c287b121d77", size = 273251, upload_time = "2025-07-26T12:02:17.524Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload_time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload_time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload_time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload_time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload_time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload_time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e2/366af18a6d386f41132a48f033cbd2102e9b0cf6345d35ff0826cd984566/contourpy-1.3.3-cp314-cp314-win32.whl", hash = "sha256:66c8a43a4f7b8df8b71ee1840e4211a3c8d93b214b213f590e18a1beca458f7d", size = 189692, upload_time = "2025-07-26T12:02:30.128Z" }, + { url = "https://files.pythonhosted.org/packages/7d/c2/57f54b03d0f22d4044b8afb9ca0e184f8b1afd57b4f735c2fa70883dc601/contourpy-1.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:cf9022ef053f2694e31d630feaacb21ea24224be1c3ad0520b13d844274614fd", size = 232424, upload_time = "2025-07-26T12:02:31.395Z" }, + { url = "https://files.pythonhosted.org/packages/18/79/a9416650df9b525737ab521aa181ccc42d56016d2123ddcb7b58e926a42c/contourpy-1.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:95b181891b4c71de4bb404c6621e7e2390745f887f2a026b2d99e92c17892339", size = 198300, upload_time = "2025-07-26T12:02:32.956Z" }, + { url = "https://files.pythonhosted.org/packages/1f/42/38c159a7d0f2b7b9c04c64ab317042bb6952b713ba875c1681529a2932fe/contourpy-1.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:33c82d0138c0a062380332c861387650c82e4cf1747aaa6938b9b6516762e772", size = 306769, upload_time = "2025-07-26T12:02:34.2Z" }, + { url = "https://files.pythonhosted.org/packages/c3/6c/26a8205f24bca10974e77460de68d3d7c63e282e23782f1239f226fcae6f/contourpy-1.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ea37e7b45949df430fe649e5de8351c423430046a2af20b1c1961cae3afcda77", size = 287892, upload_time = "2025-07-26T12:02:35.807Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload_time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload_time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload_time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload_time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload_time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload_time = "2025-07-26T12:02:47.09Z" }, + { url = "https://files.pythonhosted.org/packages/93/8a/68a4ec5c55a2971213d29a9374913f7e9f18581945a7a31d1a39b5d2dfe5/contourpy-1.3.3-cp314-cp314t-win32.whl", hash = "sha256:e74a9a0f5e3fff48fb5a7f2fd2b9b70a3fe014a67522f79b7cca4c0c7e43c9ae", size = 202428, upload_time = "2025-07-26T12:02:48.691Z" }, + { url = "https://files.pythonhosted.org/packages/fa/96/fd9f641ffedc4fa3ace923af73b9d07e869496c9cc7a459103e6e978992f/contourpy-1.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:13b68d6a62db8eafaebb8039218921399baf6e47bf85006fd8529f2a08ef33fc", size = 250331, upload_time = "2025-07-26T12:02:50.137Z" }, + { url = "https://files.pythonhosted.org/packages/ae/8c/469afb6465b853afff216f9528ffda78a915ff880ed58813ba4faf4ba0b6/contourpy-1.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b7448cb5a725bb1e35ce88771b86fba35ef418952474492cf7c764059933ff8b", size = 203831, upload_time = "2025-07-26T12:02:51.449Z" }, + { url = "https://files.pythonhosted.org/packages/a5/29/8dcfe16f0107943fa92388c23f6e05cff0ba58058c4c95b00280d4c75a14/contourpy-1.3.3-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cd5dfcaeb10f7b7f9dc8941717c6c2ade08f587be2226222c12b25f0483ed497", size = 278809, upload_time = "2025-07-26T12:02:52.74Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/8b37ef4f7dafeb335daee3c8254645ef5725be4d9c6aa70b50ec46ef2f7e/contourpy-1.3.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c1fc238306b35f246d61a1d416a627348b5cf0648648a031e14bb8705fcdfe8", size = 261593, upload_time = "2025-07-26T12:02:54.037Z" }, + { url = "https://files.pythonhosted.org/packages/0a/59/ebfb8c677c75605cc27f7122c90313fd2f375ff3c8d19a1694bda74aaa63/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70f9aad7de812d6541d29d2bbf8feb22ff7e1c299523db288004e3157ff4674e", size = 302202, upload_time = "2025-07-26T12:02:55.947Z" }, + { url = "https://files.pythonhosted.org/packages/3c/37/21972a15834d90bfbfb009b9d004779bd5a07a0ec0234e5ba8f64d5736f4/contourpy-1.3.3-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ed3657edf08512fc3fe81b510e35c2012fbd3081d2e26160f27ca28affec989", size = 329207, upload_time = "2025-07-26T12:02:57.468Z" }, + { url = "https://files.pythonhosted.org/packages/0c/58/bd257695f39d05594ca4ad60df5bcb7e32247f9951fd09a9b8edb82d1daa/contourpy-1.3.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:3d1a3799d62d45c18bafd41c5fa05120b96a28079f2393af559b843d1a966a77", size = 225315, upload_time = "2025-07-26T12:02:58.801Z" }, ] [[package]] name = "cycler" version = "0.12.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload_time = "2023-10-07T05:32:18.335Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload_time = "2023-10-07T05:32:16.783Z" }, ] [[package]] name = "debugpy" version = "1.8.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/d4/722d0bcc7986172ac2ef3c979ad56a1030e3afd44ced136d45f8142b1f4a/debugpy-1.8.16.tar.gz", hash = "sha256:31e69a1feb1cf6b51efbed3f6c9b0ef03bc46ff050679c4be7ea6d2e23540870", size = 1643809, upload-time = "2025-08-06T18:00:02.647Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/d4/722d0bcc7986172ac2ef3c979ad56a1030e3afd44ced136d45f8142b1f4a/debugpy-1.8.16.tar.gz", hash = "sha256:31e69a1feb1cf6b51efbed3f6c9b0ef03bc46ff050679c4be7ea6d2e23540870", size = 1643809, upload_time = "2025-08-06T18:00:02.647Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/d6/ad70ba8b49b23fa286fb21081cf732232cc19374af362051da9c7537ae52/debugpy-1.8.16-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:67371b28b79a6a12bcc027d94a06158f2fde223e35b5c4e0783b6f9d3b39274a", size = 2184063, upload-time = "2025-08-06T18:00:11.885Z" }, - { url = "https://files.pythonhosted.org/packages/aa/49/7b03e88dea9759a4c7910143f87f92beb494daaae25560184ff4ae883f9e/debugpy-1.8.16-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2abae6dd02523bec2dee16bd6b0781cccb53fd4995e5c71cc659b5f45581898", size = 3134837, upload-time = "2025-08-06T18:00:13.782Z" }, - { url = "https://files.pythonhosted.org/packages/5d/52/b348930316921de7565fbe37a487d15409041713004f3d74d03eb077dbd4/debugpy-1.8.16-cp311-cp311-win32.whl", hash = "sha256:f8340a3ac2ed4f5da59e064aa92e39edd52729a88fbde7bbaa54e08249a04493", size = 5159142, upload-time = "2025-08-06T18:00:15.391Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ef/9aa9549ce1e10cea696d980292e71672a91ee4a6a691ce5f8629e8f48c49/debugpy-1.8.16-cp311-cp311-win_amd64.whl", hash = "sha256:70f5fcd6d4d0c150a878d2aa37391c52de788c3dc680b97bdb5e529cb80df87a", size = 5183117, upload-time = "2025-08-06T18:00:17.251Z" }, - { url = "https://files.pythonhosted.org/packages/61/fb/0387c0e108d842c902801bc65ccc53e5b91d8c169702a9bbf4f7efcedf0c/debugpy-1.8.16-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:b202e2843e32e80b3b584bcebfe0e65e0392920dc70df11b2bfe1afcb7a085e4", size = 2511822, upload-time = "2025-08-06T18:00:18.526Z" }, - { url = "https://files.pythonhosted.org/packages/37/44/19e02745cae22bf96440141f94e15a69a1afaa3a64ddfc38004668fcdebf/debugpy-1.8.16-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64473c4a306ba11a99fe0bb14622ba4fbd943eb004847d9b69b107bde45aa9ea", size = 4230135, upload-time = "2025-08-06T18:00:19.997Z" }, - { url = "https://files.pythonhosted.org/packages/f3/0b/19b1ba5ee4412f303475a2c7ad5858efb99c90eae5ec627aa6275c439957/debugpy-1.8.16-cp312-cp312-win32.whl", hash = "sha256:833a61ed446426e38b0dd8be3e9d45ae285d424f5bf6cd5b2b559c8f12305508", size = 5281271, upload-time = "2025-08-06T18:00:21.281Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e0/bc62e2dc141de53bd03e2c7cb9d7011de2e65e8bdcdaa26703e4d28656ba/debugpy-1.8.16-cp312-cp312-win_amd64.whl", hash = "sha256:75f204684581e9ef3dc2f67687c3c8c183fde2d6675ab131d94084baf8084121", size = 5323149, upload-time = "2025-08-06T18:00:23.033Z" }, - { url = "https://files.pythonhosted.org/packages/62/66/607ab45cc79e60624df386e233ab64a6d8d39ea02e7f80e19c1d451345bb/debugpy-1.8.16-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:85df3adb1de5258dca910ae0bb185e48c98801ec15018a263a92bb06be1c8787", size = 2496157, upload-time = "2025-08-06T18:00:24.361Z" }, - { url = "https://files.pythonhosted.org/packages/4d/a0/c95baae08a75bceabb79868d663a0736655e427ab9c81fb848da29edaeac/debugpy-1.8.16-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee89e948bc236a5c43c4214ac62d28b29388453f5fd328d739035e205365f0b", size = 4222491, upload-time = "2025-08-06T18:00:25.806Z" }, - { url = "https://files.pythonhosted.org/packages/5b/2f/1c8db6ddd8a257c3cd2c46413b267f1d5fa3df910401c899513ce30392d6/debugpy-1.8.16-cp313-cp313-win32.whl", hash = "sha256:cf358066650439847ec5ff3dae1da98b5461ea5da0173d93d5e10f477c94609a", size = 5281126, upload-time = "2025-08-06T18:00:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ba/c3e154ab307366d6c5a9c1b68de04914e2ce7fa2f50d578311d8cc5074b2/debugpy-1.8.16-cp313-cp313-win_amd64.whl", hash = "sha256:b5aea1083f6f50023e8509399d7dc6535a351cc9f2e8827d1e093175e4d9fa4c", size = 5323094, upload-time = "2025-08-06T18:00:29.03Z" }, - { url = "https://files.pythonhosted.org/packages/52/57/ecc9ae29fa5b2d90107cd1d9bf8ed19aacb74b2264d986ae9d44fe9bdf87/debugpy-1.8.16-py2.py3-none-any.whl", hash = "sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e", size = 5287700, upload-time = "2025-08-06T18:00:42.333Z" }, + { url = "https://files.pythonhosted.org/packages/63/d6/ad70ba8b49b23fa286fb21081cf732232cc19374af362051da9c7537ae52/debugpy-1.8.16-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:67371b28b79a6a12bcc027d94a06158f2fde223e35b5c4e0783b6f9d3b39274a", size = 2184063, upload_time = "2025-08-06T18:00:11.885Z" }, + { url = "https://files.pythonhosted.org/packages/aa/49/7b03e88dea9759a4c7910143f87f92beb494daaae25560184ff4ae883f9e/debugpy-1.8.16-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2abae6dd02523bec2dee16bd6b0781cccb53fd4995e5c71cc659b5f45581898", size = 3134837, upload_time = "2025-08-06T18:00:13.782Z" }, + { url = "https://files.pythonhosted.org/packages/5d/52/b348930316921de7565fbe37a487d15409041713004f3d74d03eb077dbd4/debugpy-1.8.16-cp311-cp311-win32.whl", hash = "sha256:f8340a3ac2ed4f5da59e064aa92e39edd52729a88fbde7bbaa54e08249a04493", size = 5159142, upload_time = "2025-08-06T18:00:15.391Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ef/9aa9549ce1e10cea696d980292e71672a91ee4a6a691ce5f8629e8f48c49/debugpy-1.8.16-cp311-cp311-win_amd64.whl", hash = "sha256:70f5fcd6d4d0c150a878d2aa37391c52de788c3dc680b97bdb5e529cb80df87a", size = 5183117, upload_time = "2025-08-06T18:00:17.251Z" }, + { url = "https://files.pythonhosted.org/packages/61/fb/0387c0e108d842c902801bc65ccc53e5b91d8c169702a9bbf4f7efcedf0c/debugpy-1.8.16-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:b202e2843e32e80b3b584bcebfe0e65e0392920dc70df11b2bfe1afcb7a085e4", size = 2511822, upload_time = "2025-08-06T18:00:18.526Z" }, + { url = "https://files.pythonhosted.org/packages/37/44/19e02745cae22bf96440141f94e15a69a1afaa3a64ddfc38004668fcdebf/debugpy-1.8.16-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64473c4a306ba11a99fe0bb14622ba4fbd943eb004847d9b69b107bde45aa9ea", size = 4230135, upload_time = "2025-08-06T18:00:19.997Z" }, + { url = "https://files.pythonhosted.org/packages/f3/0b/19b1ba5ee4412f303475a2c7ad5858efb99c90eae5ec627aa6275c439957/debugpy-1.8.16-cp312-cp312-win32.whl", hash = "sha256:833a61ed446426e38b0dd8be3e9d45ae285d424f5bf6cd5b2b559c8f12305508", size = 5281271, upload_time = "2025-08-06T18:00:21.281Z" }, + { url = "https://files.pythonhosted.org/packages/b1/e0/bc62e2dc141de53bd03e2c7cb9d7011de2e65e8bdcdaa26703e4d28656ba/debugpy-1.8.16-cp312-cp312-win_amd64.whl", hash = "sha256:75f204684581e9ef3dc2f67687c3c8c183fde2d6675ab131d94084baf8084121", size = 5323149, upload_time = "2025-08-06T18:00:23.033Z" }, + { url = "https://files.pythonhosted.org/packages/62/66/607ab45cc79e60624df386e233ab64a6d8d39ea02e7f80e19c1d451345bb/debugpy-1.8.16-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:85df3adb1de5258dca910ae0bb185e48c98801ec15018a263a92bb06be1c8787", size = 2496157, upload_time = "2025-08-06T18:00:24.361Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a0/c95baae08a75bceabb79868d663a0736655e427ab9c81fb848da29edaeac/debugpy-1.8.16-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bee89e948bc236a5c43c4214ac62d28b29388453f5fd328d739035e205365f0b", size = 4222491, upload_time = "2025-08-06T18:00:25.806Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2f/1c8db6ddd8a257c3cd2c46413b267f1d5fa3df910401c899513ce30392d6/debugpy-1.8.16-cp313-cp313-win32.whl", hash = "sha256:cf358066650439847ec5ff3dae1da98b5461ea5da0173d93d5e10f477c94609a", size = 5281126, upload_time = "2025-08-06T18:00:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ba/c3e154ab307366d6c5a9c1b68de04914e2ce7fa2f50d578311d8cc5074b2/debugpy-1.8.16-cp313-cp313-win_amd64.whl", hash = "sha256:b5aea1083f6f50023e8509399d7dc6535a351cc9f2e8827d1e093175e4d9fa4c", size = 5323094, upload_time = "2025-08-06T18:00:29.03Z" }, + { url = "https://files.pythonhosted.org/packages/52/57/ecc9ae29fa5b2d90107cd1d9bf8ed19aacb74b2264d986ae9d44fe9bdf87/debugpy-1.8.16-py2.py3-none-any.whl", hash = "sha256:19c9521962475b87da6f673514f7fd610328757ec993bf7ec0d8c96f9a325f9e", size = 5287700, upload_time = "2025-08-06T18:00:42.333Z" }, ] [[package]] name = "decorator" version = "5.2.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload-time = "2025-02-24T04:41:34.073Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/fa/6d96a0978d19e17b68d634497769987b16c8f4cd0a7a05048bec693caa6b/decorator-5.2.1.tar.gz", hash = "sha256:65f266143752f734b0a7cc83c46f4618af75b8c5911b00ccb61d0ac9b6da0360", size = 56711, upload_time = "2025-02-24T04:41:34.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload-time = "2025-02-24T04:41:32.565Z" }, + { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190, upload_time = "2025-02-24T04:41:32.565Z" }, ] [[package]] name = "defusedxml" version = "0.7.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload_time = "2021-03-08T10:59:26.269Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload_time = "2021-03-08T10:59:24.45Z" }, ] [[package]] name = "executing" version = "2.2.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload-time = "2025-01-22T15:41:29.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693, upload_time = "2025-01-22T15:41:29.403Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload-time = "2025-01-22T15:41:25.929Z" }, + { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702, upload_time = "2025-01-22T15:41:25.929Z" }, ] [[package]] name = "fastjsonschema" version = "2.21.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939, upload-time = "2024-12-02T10:55:15.133Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939, upload_time = "2024-12-02T10:55:15.133Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924, upload-time = "2024-12-02T10:55:07.599Z" }, + { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924, upload_time = "2024-12-02T10:55:07.599Z" }, ] [[package]] name = "fonttools" version = "4.59.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8a/27/ec3c723bfdf86f34c5c82bf6305df3e0f0d8ea798d2d3a7cb0c0a866d286/fonttools-4.59.0.tar.gz", hash = "sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14", size = 3532521, upload-time = "2025-07-16T12:04:54.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/27/ec3c723bfdf86f34c5c82bf6305df3e0f0d8ea798d2d3a7cb0c0a866d286/fonttools-4.59.0.tar.gz", hash = "sha256:be392ec3529e2f57faa28709d60723a763904f71a2b63aabe14fee6648fe3b14", size = 3532521, upload_time = "2025-07-16T12:04:54.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/96/520733d9602fa1bf6592e5354c6721ac6fc9ea72bc98d112d0c38b967199/fonttools-4.59.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c", size = 2782387, upload-time = "2025-07-16T12:03:51.424Z" }, - { url = "https://files.pythonhosted.org/packages/87/6a/170fce30b9bce69077d8eec9bea2cfd9f7995e8911c71be905e2eba6368b/fonttools-4.59.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5", size = 2342194, upload-time = "2025-07-16T12:03:53.295Z" }, - { url = "https://files.pythonhosted.org/packages/b0/b6/7c8166c0066856f1408092f7968ac744060cf72ca53aec9036106f57eeca/fonttools-4.59.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705", size = 5032333, upload-time = "2025-07-16T12:03:55.177Z" }, - { url = "https://files.pythonhosted.org/packages/eb/0c/707c5a19598eafcafd489b73c4cb1c142102d6197e872f531512d084aa76/fonttools-4.59.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464", size = 4974422, upload-time = "2025-07-16T12:03:57.406Z" }, - { url = "https://files.pythonhosted.org/packages/f6/e7/6d33737d9fe632a0f59289b6f9743a86d2a9d0673de2a0c38c0f54729822/fonttools-4.59.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38", size = 5010631, upload-time = "2025-07-16T12:03:59.449Z" }, - { url = "https://files.pythonhosted.org/packages/63/e1/a4c3d089ab034a578820c8f2dff21ef60daf9668034a1e4fb38bb1cc3398/fonttools-4.59.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6", size = 5122198, upload-time = "2025-07-16T12:04:01.542Z" }, - { url = "https://files.pythonhosted.org/packages/09/77/ca82b9c12fa4de3c520b7760ee61787640cf3fde55ef1b0bfe1de38c8153/fonttools-4.59.0-cp311-cp311-win32.whl", hash = "sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757", size = 2214216, upload-time = "2025-07-16T12:04:03.515Z" }, - { url = "https://files.pythonhosted.org/packages/ab/25/5aa7ca24b560b2f00f260acf32c4cf29d7aaf8656e159a336111c18bc345/fonttools-4.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0", size = 2261879, upload-time = "2025-07-16T12:04:05.015Z" }, - { url = "https://files.pythonhosted.org/packages/e2/77/b1c8af22f4265e951cd2e5535dbef8859efcef4fb8dee742d368c967cddb/fonttools-4.59.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b", size = 2767562, upload-time = "2025-07-16T12:04:06.895Z" }, - { url = "https://files.pythonhosted.org/packages/ff/5a/aeb975699588176bb357e8b398dfd27e5d3a2230d92b81ab8cbb6187358d/fonttools-4.59.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2", size = 2335168, upload-time = "2025-07-16T12:04:08.695Z" }, - { url = "https://files.pythonhosted.org/packages/54/97/c6101a7e60ae138c4ef75b22434373a0da50a707dad523dd19a4889315bf/fonttools-4.59.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b", size = 4909850, upload-time = "2025-07-16T12:04:10.761Z" }, - { url = "https://files.pythonhosted.org/packages/bd/6c/fa4d18d641054f7bff878cbea14aa9433f292b9057cb1700d8e91a4d5f4f/fonttools-4.59.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1", size = 4955131, upload-time = "2025-07-16T12:04:12.846Z" }, - { url = "https://files.pythonhosted.org/packages/20/5c/331947fc1377deb928a69bde49f9003364f5115e5cbe351eea99e39412a2/fonttools-4.59.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e", size = 4899667, upload-time = "2025-07-16T12:04:14.558Z" }, - { url = "https://files.pythonhosted.org/packages/8a/46/b66469dfa26b8ff0baa7654b2cc7851206c6d57fe3abdabbaab22079a119/fonttools-4.59.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e", size = 5051349, upload-time = "2025-07-16T12:04:16.388Z" }, - { url = "https://files.pythonhosted.org/packages/2e/05/ebfb6b1f3a4328ab69787d106a7d92ccde77ce66e98659df0f9e3f28d93d/fonttools-4.59.0-cp312-cp312-win32.whl", hash = "sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b", size = 2201315, upload-time = "2025-07-16T12:04:18.557Z" }, - { url = "https://files.pythonhosted.org/packages/09/45/d2bdc9ea20bbadec1016fd0db45696d573d7a26d95ab5174ffcb6d74340b/fonttools-4.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01", size = 2249408, upload-time = "2025-07-16T12:04:20.489Z" }, - { url = "https://files.pythonhosted.org/packages/f3/bb/390990e7c457d377b00890d9f96a3ca13ae2517efafb6609c1756e213ba4/fonttools-4.59.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2", size = 2758704, upload-time = "2025-07-16T12:04:22.217Z" }, - { url = "https://files.pythonhosted.org/packages/df/6f/d730d9fcc9b410a11597092bd2eb9ca53e5438c6cb90e4b3047ce1b723e9/fonttools-4.59.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2", size = 2330764, upload-time = "2025-07-16T12:04:23.985Z" }, - { url = "https://files.pythonhosted.org/packages/75/b4/b96bb66f6f8cc4669de44a158099b249c8159231d254ab6b092909388be5/fonttools-4.59.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4", size = 4890699, upload-time = "2025-07-16T12:04:25.664Z" }, - { url = "https://files.pythonhosted.org/packages/b5/57/7969af50b26408be12baa317c6147588db5b38af2759e6df94554dbc5fdb/fonttools-4.59.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97", size = 4952934, upload-time = "2025-07-16T12:04:27.733Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e2/dd968053b6cf1f46c904f5bd409b22341477c017d8201619a265e50762d3/fonttools-4.59.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c", size = 4892319, upload-time = "2025-07-16T12:04:30.074Z" }, - { url = "https://files.pythonhosted.org/packages/6b/95/a59810d8eda09129f83467a4e58f84205dc6994ebaeb9815406363e07250/fonttools-4.59.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c", size = 5034753, upload-time = "2025-07-16T12:04:32.292Z" }, - { url = "https://files.pythonhosted.org/packages/a5/84/51a69ee89ff8d1fea0c6997e946657e25a3f08513de8435fe124929f3eef/fonttools-4.59.0-cp313-cp313-win32.whl", hash = "sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3", size = 2199688, upload-time = "2025-07-16T12:04:34.444Z" }, - { url = "https://files.pythonhosted.org/packages/a0/ee/f626cd372932d828508137a79b85167fdcf3adab2e3bed433f295c596c6a/fonttools-4.59.0-cp313-cp313-win_amd64.whl", hash = "sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe", size = 2248560, upload-time = "2025-07-16T12:04:36.034Z" }, - { url = "https://files.pythonhosted.org/packages/d0/9c/df0ef2c51845a13043e5088f7bb988ca6cd5bb82d5d4203d6a158aa58cf2/fonttools-4.59.0-py3-none-any.whl", hash = "sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d", size = 1128050, upload-time = "2025-07-16T12:04:52.687Z" }, + { url = "https://files.pythonhosted.org/packages/06/96/520733d9602fa1bf6592e5354c6721ac6fc9ea72bc98d112d0c38b967199/fonttools-4.59.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:841b2186adce48903c0fef235421ae21549020eca942c1da773ac380b056ab3c", size = 2782387, upload_time = "2025-07-16T12:03:51.424Z" }, + { url = "https://files.pythonhosted.org/packages/87/6a/170fce30b9bce69077d8eec9bea2cfd9f7995e8911c71be905e2eba6368b/fonttools-4.59.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9bcc1e77fbd1609198966ded6b2a9897bd6c6bcbd2287a2fc7d75f1a254179c5", size = 2342194, upload_time = "2025-07-16T12:03:53.295Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b6/7c8166c0066856f1408092f7968ac744060cf72ca53aec9036106f57eeca/fonttools-4.59.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37c377f7cb2ab2eca8a0b319c68146d34a339792f9420fca6cd49cf28d370705", size = 5032333, upload_time = "2025-07-16T12:03:55.177Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0c/707c5a19598eafcafd489b73c4cb1c142102d6197e872f531512d084aa76/fonttools-4.59.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fa39475eaccb98f9199eccfda4298abaf35ae0caec676ffc25b3a5e224044464", size = 4974422, upload_time = "2025-07-16T12:03:57.406Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e7/6d33737d9fe632a0f59289b6f9743a86d2a9d0673de2a0c38c0f54729822/fonttools-4.59.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d3972b13148c1d1fbc092b27678a33b3080d1ac0ca305742b0119b75f9e87e38", size = 5010631, upload_time = "2025-07-16T12:03:59.449Z" }, + { url = "https://files.pythonhosted.org/packages/63/e1/a4c3d089ab034a578820c8f2dff21ef60daf9668034a1e4fb38bb1cc3398/fonttools-4.59.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a408c3c51358c89b29cfa5317cf11518b7ce5de1717abb55c5ae2d2921027de6", size = 5122198, upload_time = "2025-07-16T12:04:01.542Z" }, + { url = "https://files.pythonhosted.org/packages/09/77/ca82b9c12fa4de3c520b7760ee61787640cf3fde55ef1b0bfe1de38c8153/fonttools-4.59.0-cp311-cp311-win32.whl", hash = "sha256:6770d7da00f358183d8fd5c4615436189e4f683bdb6affb02cad3d221d7bb757", size = 2214216, upload_time = "2025-07-16T12:04:03.515Z" }, + { url = "https://files.pythonhosted.org/packages/ab/25/5aa7ca24b560b2f00f260acf32c4cf29d7aaf8656e159a336111c18bc345/fonttools-4.59.0-cp311-cp311-win_amd64.whl", hash = "sha256:84fc186980231a287b28560d3123bd255d3c6b6659828c642b4cf961e2b923d0", size = 2261879, upload_time = "2025-07-16T12:04:05.015Z" }, + { url = "https://files.pythonhosted.org/packages/e2/77/b1c8af22f4265e951cd2e5535dbef8859efcef4fb8dee742d368c967cddb/fonttools-4.59.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f9b3a78f69dcbd803cf2fb3f972779875b244c1115481dfbdd567b2c22b31f6b", size = 2767562, upload_time = "2025-07-16T12:04:06.895Z" }, + { url = "https://files.pythonhosted.org/packages/ff/5a/aeb975699588176bb357e8b398dfd27e5d3a2230d92b81ab8cbb6187358d/fonttools-4.59.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:57bb7e26928573ee7c6504f54c05860d867fd35e675769f3ce01b52af38d48e2", size = 2335168, upload_time = "2025-07-16T12:04:08.695Z" }, + { url = "https://files.pythonhosted.org/packages/54/97/c6101a7e60ae138c4ef75b22434373a0da50a707dad523dd19a4889315bf/fonttools-4.59.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4536f2695fe5c1ffb528d84a35a7d3967e5558d2af58b4775e7ab1449d65767b", size = 4909850, upload_time = "2025-07-16T12:04:10.761Z" }, + { url = "https://files.pythonhosted.org/packages/bd/6c/fa4d18d641054f7bff878cbea14aa9433f292b9057cb1700d8e91a4d5f4f/fonttools-4.59.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:885bde7d26e5b40e15c47bd5def48b38cbd50830a65f98122a8fb90962af7cd1", size = 4955131, upload_time = "2025-07-16T12:04:12.846Z" }, + { url = "https://files.pythonhosted.org/packages/20/5c/331947fc1377deb928a69bde49f9003364f5115e5cbe351eea99e39412a2/fonttools-4.59.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6801aeddb6acb2c42eafa45bc1cb98ba236871ae6f33f31e984670b749a8e58e", size = 4899667, upload_time = "2025-07-16T12:04:14.558Z" }, + { url = "https://files.pythonhosted.org/packages/8a/46/b66469dfa26b8ff0baa7654b2cc7851206c6d57fe3abdabbaab22079a119/fonttools-4.59.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:31003b6a10f70742a63126b80863ab48175fb8272a18ca0846c0482968f0588e", size = 5051349, upload_time = "2025-07-16T12:04:16.388Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ebfb6b1f3a4328ab69787d106a7d92ccde77ce66e98659df0f9e3f28d93d/fonttools-4.59.0-cp312-cp312-win32.whl", hash = "sha256:fbce6dae41b692a5973d0f2158f782b9ad05babc2c2019a970a1094a23909b1b", size = 2201315, upload_time = "2025-07-16T12:04:18.557Z" }, + { url = "https://files.pythonhosted.org/packages/09/45/d2bdc9ea20bbadec1016fd0db45696d573d7a26d95ab5174ffcb6d74340b/fonttools-4.59.0-cp312-cp312-win_amd64.whl", hash = "sha256:332bfe685d1ac58ca8d62b8d6c71c2e52a6c64bc218dc8f7825c9ea51385aa01", size = 2249408, upload_time = "2025-07-16T12:04:20.489Z" }, + { url = "https://files.pythonhosted.org/packages/f3/bb/390990e7c457d377b00890d9f96a3ca13ae2517efafb6609c1756e213ba4/fonttools-4.59.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:78813b49d749e1bb4db1c57f2d4d7e6db22c253cb0a86ad819f5dc197710d4b2", size = 2758704, upload_time = "2025-07-16T12:04:22.217Z" }, + { url = "https://files.pythonhosted.org/packages/df/6f/d730d9fcc9b410a11597092bd2eb9ca53e5438c6cb90e4b3047ce1b723e9/fonttools-4.59.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:401b1941ce37e78b8fd119b419b617277c65ae9417742a63282257434fd68ea2", size = 2330764, upload_time = "2025-07-16T12:04:23.985Z" }, + { url = "https://files.pythonhosted.org/packages/75/b4/b96bb66f6f8cc4669de44a158099b249c8159231d254ab6b092909388be5/fonttools-4.59.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:efd7e6660674e234e29937bc1481dceb7e0336bfae75b856b4fb272b5093c5d4", size = 4890699, upload_time = "2025-07-16T12:04:25.664Z" }, + { url = "https://files.pythonhosted.org/packages/b5/57/7969af50b26408be12baa317c6147588db5b38af2759e6df94554dbc5fdb/fonttools-4.59.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51ab1ff33c19e336c02dee1e9fd1abd974a4ca3d8f7eef2a104d0816a241ce97", size = 4952934, upload_time = "2025-07-16T12:04:27.733Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e2/dd968053b6cf1f46c904f5bd409b22341477c017d8201619a265e50762d3/fonttools-4.59.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a9bf8adc9e1f3012edc8f09b08336272aec0c55bc677422273e21280db748f7c", size = 4892319, upload_time = "2025-07-16T12:04:30.074Z" }, + { url = "https://files.pythonhosted.org/packages/6b/95/a59810d8eda09129f83467a4e58f84205dc6994ebaeb9815406363e07250/fonttools-4.59.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:37e01c6ec0c98599778c2e688350d624fa4770fbd6144551bd5e032f1199171c", size = 5034753, upload_time = "2025-07-16T12:04:32.292Z" }, + { url = "https://files.pythonhosted.org/packages/a5/84/51a69ee89ff8d1fea0c6997e946657e25a3f08513de8435fe124929f3eef/fonttools-4.59.0-cp313-cp313-win32.whl", hash = "sha256:70d6b3ceaa9cc5a6ac52884f3b3d9544e8e231e95b23f138bdb78e6d4dc0eae3", size = 2199688, upload_time = "2025-07-16T12:04:34.444Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ee/f626cd372932d828508137a79b85167fdcf3adab2e3bed433f295c596c6a/fonttools-4.59.0-cp313-cp313-win_amd64.whl", hash = "sha256:26731739daa23b872643f0e4072d5939960237d540c35c14e6a06d47d71ca8fe", size = 2248560, upload_time = "2025-07-16T12:04:36.034Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9c/df0ef2c51845a13043e5088f7bb988ca6cd5bb82d5d4203d6a158aa58cf2/fonttools-4.59.0-py3-none-any.whl", hash = "sha256:241313683afd3baacb32a6bd124d0bce7404bc5280e12e291bae1b9bba28711d", size = 1128050, upload_time = "2025-07-16T12:04:52.687Z" }, ] [[package]] name = "fqdn" version = "1.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload_time = "2021-03-11T07:16:29.08Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload_time = "2021-03-11T07:16:28.351Z" }, ] [[package]] name = "h11" version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload_time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload_time = "2025-04-24T03:35:24.344Z" }, ] [[package]] @@ -546,9 +546,9 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload_time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload_time = "2025-04-24T22:06:20.566Z" }, ] [[package]] @@ -561,27 +561,27 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload_time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload_time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload_time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload_time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload_time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload_time = "2025-03-19T20:10:01.071Z" }, ] [[package]] @@ -603,9 +603,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload-time = "2025-08-04T15:47:35.018Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/76/11082e338e0daadc89c8ff866185de11daf67d181901038f9e139d109761/ipykernel-6.30.1.tar.gz", hash = "sha256:6abb270161896402e76b91394fcdce5d1be5d45f456671e5080572f8505be39b", size = 166260, upload_time = "2025-08-04T15:47:35.018Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload-time = "2025-08-04T15:47:32.622Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c7/b445faca8deb954fe536abebff4ece5b097b923de482b26e78448c89d1dd/ipykernel-6.30.1-py3-none-any.whl", hash = "sha256:aa6b9fb93dca949069d8b85b6c79b2518e32ac583ae9c7d37c51d119e18b3fb4", size = 117484, upload_time = "2025-08-04T15:47:32.622Z" }, ] [[package]] @@ -625,9 +625,9 @@ dependencies = [ { name = "traitlets" }, { name = "typing-extensions", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/54/80/406f9e3bde1c1fd9bf5a0be9d090f8ae623e401b7670d8f6fdf2ab679891/ipython-9.4.0.tar.gz", hash = "sha256:c033c6d4e7914c3d9768aabe76bbe87ba1dc66a92a05db6bfa1125d81f2ee270", size = 4385338, upload-time = "2025-07-01T11:11:30.606Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/80/406f9e3bde1c1fd9bf5a0be9d090f8ae623e401b7670d8f6fdf2ab679891/ipython-9.4.0.tar.gz", hash = "sha256:c033c6d4e7914c3d9768aabe76bbe87ba1dc66a92a05db6bfa1125d81f2ee270", size = 4385338, upload_time = "2025-07-01T11:11:30.606Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/f8/0031ee2b906a15a33d6bfc12dd09c3dfa966b3cb5b284ecfb7549e6ac3c4/ipython-9.4.0-py3-none-any.whl", hash = "sha256:25850f025a446d9b359e8d296ba175a36aedd32e83ca9b5060430fe16801f066", size = 611021, upload-time = "2025-07-01T11:11:27.85Z" }, + { url = "https://files.pythonhosted.org/packages/63/f8/0031ee2b906a15a33d6bfc12dd09c3dfa966b3cb5b284ecfb7549e6ac3c4/ipython-9.4.0-py3-none-any.whl", hash = "sha256:25850f025a446d9b359e8d296ba175a36aedd32e83ca9b5060430fe16801f066", size = 611021, upload_time = "2025-07-01T11:11:27.85Z" }, ] [[package]] @@ -637,9 +637,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload_time = "2025-01-17T11:24:34.505Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload_time = "2025-01-17T11:24:33.271Z" }, ] [[package]] @@ -653,9 +653,9 @@ dependencies = [ { name = "traitlets" }, { name = "widgetsnbextension" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/48/d3dbac45c2814cb73812f98dd6b38bbcc957a4e7bb31d6ea9c03bf94ed87/ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376", size = 116721, upload-time = "2025-05-05T12:42:03.489Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/48/d3dbac45c2814cb73812f98dd6b38bbcc957a4e7bb31d6ea9c03bf94ed87/ipywidgets-8.1.7.tar.gz", hash = "sha256:15f1ac050b9ccbefd45dccfbb2ef6bed0029d8278682d569d71b8dd96bee0376", size = 116721, upload_time = "2025-05-05T12:42:03.489Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb", size = 139806, upload-time = "2025-05-05T12:41:56.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/6a/9166369a2f092bd286d24e6307de555d63616e8ddb373ebad2b5635ca4cd/ipywidgets-8.1.7-py3-none-any.whl", hash = "sha256:764f2602d25471c213919b8a1997df04bef869251db4ca8efba1b76b1bd9f7bb", size = 139806, upload_time = "2025-05-05T12:41:56.833Z" }, ] [[package]] @@ -665,9 +665,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "arrow" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload_time = "2020-11-01T11:00:00.312Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload_time = "2020-11-01T10:59:58.02Z" }, ] [[package]] @@ -677,9 +677,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "parso" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload-time = "2024-11-11T01:41:42.873Z" } +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287, upload_time = "2024-11-11T01:41:42.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload-time = "2024-11-11T01:41:40.175Z" }, + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278, upload_time = "2024-11-11T01:41:40.175Z" }, ] [[package]] @@ -689,27 +689,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload_time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload_time = "2025-03-05T20:05:00.369Z" }, ] [[package]] name = "json5" version = "0.12.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/12/be/c6c745ec4c4539b25a278b70e29793f10382947df0d9efba2fa09120895d/json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a", size = 51907, upload-time = "2025-04-03T16:33:13.201Z" } +sdist = { url = "https://files.pythonhosted.org/packages/12/be/c6c745ec4c4539b25a278b70e29793f10382947df0d9efba2fa09120895d/json5-0.12.0.tar.gz", hash = "sha256:0b4b6ff56801a1c7dc817b0241bca4ce474a0e6a163bfef3fc594d3fd263ff3a", size = 51907, upload_time = "2025-04-03T16:33:13.201Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db", size = 36079, upload-time = "2025-04-03T16:33:11.927Z" }, + { url = "https://files.pythonhosted.org/packages/41/9f/3500910d5a98549e3098807493851eeef2b89cdd3032227558a104dfe926/json5-0.12.0-py3-none-any.whl", hash = "sha256:6d37aa6c08b0609f16e1ec5ff94697e2cbbfbad5ac112afa05794da9ab7810db", size = 36079, upload_time = "2025-04-03T16:33:11.927Z" }, ] [[package]] name = "jsonpointer" version = "3.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload_time = "2024-06-10T19:24:42.462Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" }, + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload_time = "2024-06-10T19:24:40.698Z" }, ] [[package]] @@ -722,9 +722,9 @@ dependencies = [ { name = "referencing" }, { name = "rpds-py" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f", size = 356830, upload-time = "2025-07-18T15:39:45.11Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/00/a297a868e9d0784450faa7365c2172a7d6110c763e30ba861867c32ae6a9/jsonschema-4.25.0.tar.gz", hash = "sha256:e63acf5c11762c0e6672ffb61482bdf57f0876684d8d249c0fe2d730d48bc55f", size = 356830, upload_time = "2025-07-18T15:39:45.11Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716", size = 89184, upload-time = "2025-07-18T15:39:42.956Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/c86cd8e011fe98803d7e382fd67c0df5ceab8d2b7ad8c5a81524f791551c/jsonschema-4.25.0-py3-none-any.whl", hash = "sha256:24c2e8da302de79c8b9382fee3e76b355e44d2a4364bb207159ce10b517bd716", size = 89184, upload_time = "2025-07-18T15:39:42.956Z" }, ] [package.optional-dependencies] @@ -747,9 +747,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "referencing" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload-time = "2025-04-23T12:34:07.418Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bf/ce/46fbd9c8119cfc3581ee5643ea49464d168028cfb5caff5fc0596d0cf914/jsonschema_specifications-2025.4.1.tar.gz", hash = "sha256:630159c9f4dbea161a6a2205c3011cc4f18ff381b189fff48bb39b9bf26ae608", size = 15513, upload_time = "2025-04-23T12:34:07.418Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload-time = "2025-04-23T12:34:05.422Z" }, + { url = "https://files.pythonhosted.org/packages/01/0e/b27cdbaccf30b890c40ed1da9fd4a3593a5cf94dae54fb34f8a4b74fcd3f/jsonschema_specifications-2025.4.1-py3-none-any.whl", hash = "sha256:4653bffbd6584f7de83a67e0d620ef16900b390ddc7939d56684d6c81e33f1af", size = 18437, upload_time = "2025-04-23T12:34:05.422Z" }, ] [[package]] @@ -764,9 +764,9 @@ dependencies = [ { name = "nbconvert" }, { name = "notebook" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959, upload-time = "2024-08-30T07:15:48.299Z" } +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959, upload_time = "2024-08-30T07:15:48.299Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload_time = "2024-08-30T07:15:47.045Z" }, ] [[package]] @@ -780,9 +780,9 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload-time = "2024-09-17T10:44:17.613Z" } +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019, upload_time = "2024-09-17T10:44:17.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload-time = "2024-09-17T10:44:15.218Z" }, + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105, upload_time = "2024-09-17T10:44:15.218Z" }, ] [[package]] @@ -799,9 +799,9 @@ dependencies = [ { name = "pyzmq" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363, upload-time = "2023-03-06T14:13:31.02Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363, upload_time = "2023-03-06T14:13:31.02Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510, upload-time = "2023-03-06T14:13:28.229Z" }, + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510, upload_time = "2023-03-06T14:13:28.229Z" }, ] [[package]] @@ -813,9 +813,9 @@ dependencies = [ { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload-time = "2025-05-27T07:38:16.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/1b/72906d554acfeb588332eaaa6f61577705e9ec752ddb486f302dafa292d9/jupyter_core-5.8.1.tar.gz", hash = "sha256:0a5f9706f70e64786b75acba995988915ebd4601c8a52e534a40b51c95f59941", size = 88923, upload_time = "2025-05-27T07:38:16.655Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload-time = "2025-05-27T07:38:15.137Z" }, + { url = "https://files.pythonhosted.org/packages/2f/57/6bffd4b20b88da3800c5d691e0337761576ee688eb01299eae865689d2df/jupyter_core-5.8.1-py3-none-any.whl", hash = "sha256:c28d268fc90fb53f1338ded2eb410704c5449a358406e8a948b75706e24863d0", size = 28880, upload_time = "2025-05-27T07:38:15.137Z" }, ] [[package]] @@ -832,9 +832,9 @@ dependencies = [ { name = "rfc3986-validator" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9d/c3/306d090461e4cf3cd91eceaff84bede12a8e52cd821c2d20c9a4fd728385/jupyter_events-0.12.0.tar.gz", hash = "sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b", size = 62196, upload-time = "2025-02-03T17:23:41.485Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/c3/306d090461e4cf3cd91eceaff84bede12a8e52cd821c2d20c9a4fd728385/jupyter_events-0.12.0.tar.gz", hash = "sha256:fc3fce98865f6784c9cd0a56a20644fc6098f21c8c33834a8d9fe383c17e554b", size = 62196, upload_time = "2025-02-03T17:23:41.485Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl", hash = "sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb", size = 19430, upload-time = "2025-02-03T17:23:38.643Z" }, + { url = "https://files.pythonhosted.org/packages/e2/48/577993f1f99c552f18a0428731a755e06171f9902fa118c379eb7c04ea22/jupyter_events-0.12.0-py3-none-any.whl", hash = "sha256:6464b2fa5ad10451c3d35fabc75eab39556ae1e2853ad0c0cc31b656731a97fb", size = 19430, upload_time = "2025-02-03T17:23:38.643Z" }, ] [[package]] @@ -844,9 +844,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/3d/40bdb41b665d3302390ed1356cebd5917c10769d1f190ee4ca595900840e/jupyter_lsp-2.2.6.tar.gz", hash = "sha256:0566bd9bb04fd9e6774a937ed01522b555ba78be37bebef787c8ab22de4c0361", size = 48948, upload-time = "2025-07-18T21:35:19.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/3d/40bdb41b665d3302390ed1356cebd5917c10769d1f190ee4ca595900840e/jupyter_lsp-2.2.6.tar.gz", hash = "sha256:0566bd9bb04fd9e6774a937ed01522b555ba78be37bebef787c8ab22de4c0361", size = 48948, upload_time = "2025-07-18T21:35:19.885Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/7c/12f68daf85b469b4896d5e4a629baa33c806d61de75ac5b39d8ef27ec4a2/jupyter_lsp-2.2.6-py3-none-any.whl", hash = "sha256:283783752bf0b459ee7fa88effa72104d87dd343b82d5c06cf113ef755b15b6d", size = 69371, upload-time = "2025-07-18T21:35:16.585Z" }, + { url = "https://files.pythonhosted.org/packages/47/7c/12f68daf85b469b4896d5e4a629baa33c806d61de75ac5b39d8ef27ec4a2/jupyter_lsp-2.2.6-py3-none-any.whl", hash = "sha256:283783752bf0b459ee7fa88effa72104d87dd343b82d5c06cf113ef755b15b6d", size = 69371, upload_time = "2025-07-18T21:35:16.585Z" }, ] [[package]] @@ -874,9 +874,9 @@ dependencies = [ { name = "traitlets" }, { name = "websocket-client" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/c8/ba2bbcd758c47f1124c4ca14061e8ce60d9c6fd537faee9534a95f83521a/jupyter_server-2.16.0.tar.gz", hash = "sha256:65d4b44fdf2dcbbdfe0aa1ace4a842d4aaf746a2b7b168134d5aaed35621b7f6", size = 728177, upload-time = "2025-05-12T16:44:46.245Z" } +sdist = { url = "https://files.pythonhosted.org/packages/41/c8/ba2bbcd758c47f1124c4ca14061e8ce60d9c6fd537faee9534a95f83521a/jupyter_server-2.16.0.tar.gz", hash = "sha256:65d4b44fdf2dcbbdfe0aa1ace4a842d4aaf746a2b7b168134d5aaed35621b7f6", size = 728177, upload_time = "2025-05-12T16:44:46.245Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl", hash = "sha256:3d8db5be3bc64403b1c65b400a1d7f4647a5ce743f3b20dbdefe8ddb7b55af9e", size = 386904, upload-time = "2025-05-12T16:44:43.335Z" }, + { url = "https://files.pythonhosted.org/packages/46/1f/5ebbced977171d09a7b0c08a285ff9a20aafb9c51bde07e52349ff1ddd71/jupyter_server-2.16.0-py3-none-any.whl", hash = "sha256:3d8db5be3bc64403b1c65b400a1d7f4647a5ce743f3b20dbdefe8ddb7b55af9e", size = 386904, upload_time = "2025-05-12T16:44:43.335Z" }, ] [[package]] @@ -887,9 +887,9 @@ dependencies = [ { name = "pywinpty", marker = "os_name == 'nt'" }, { name = "terminado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430, upload-time = "2024-03-12T14:37:03.049Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430, upload_time = "2024-03-12T14:37:03.049Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656, upload-time = "2024-03-12T14:37:00.708Z" }, + { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656, upload_time = "2024-03-12T14:37:00.708Z" }, ] [[package]] @@ -911,18 +911,18 @@ dependencies = [ { name = "tornado" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/89/695805a6564bafe08ef2505f3c473ae7140b8ba431d381436f11bdc2c266/jupyterlab-4.4.5.tar.gz", hash = "sha256:0bd6c18e6a3c3d91388af6540afa3d0bb0b2e76287a7b88ddf20ab41b336e595", size = 23037079, upload-time = "2025-07-20T09:21:30.151Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/89/695805a6564bafe08ef2505f3c473ae7140b8ba431d381436f11bdc2c266/jupyterlab-4.4.5.tar.gz", hash = "sha256:0bd6c18e6a3c3d91388af6540afa3d0bb0b2e76287a7b88ddf20ab41b336e595", size = 23037079, upload_time = "2025-07-20T09:21:30.151Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/47/74/e144ce85b34414e44b14c1f6bf2e3bfe17964c8e5670ebdc7629f2e53672/jupyterlab-4.4.5-py3-none-any.whl", hash = "sha256:e76244cceb2d1fb4a99341f3edc866f2a13a9e14c50368d730d75d8017be0863", size = 12267763, upload-time = "2025-07-20T09:21:26.37Z" }, + { url = "https://files.pythonhosted.org/packages/47/74/e144ce85b34414e44b14c1f6bf2e3bfe17964c8e5670ebdc7629f2e53672/jupyterlab-4.4.5-py3-none-any.whl", hash = "sha256:e76244cceb2d1fb4a99341f3edc866f2a13a9e14c50368d730d75d8017be0863", size = 12267763, upload_time = "2025-07-20T09:21:26.37Z" }, ] [[package]] name = "jupyterlab-pygments" version = "0.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload_time = "2023-11-23T09:26:37.44Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload_time = "2023-11-23T09:26:34.325Z" }, ] [[package]] @@ -938,141 +938,164 @@ dependencies = [ { name = "packaging" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173, upload-time = "2024-07-16T17:02:04.149Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173, upload_time = "2024-07-16T17:02:04.149Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700, upload-time = "2024-07-16T17:02:01.115Z" }, + { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700, upload_time = "2024-07-16T17:02:01.115Z" }, ] [[package]] name = "jupyterlab-widgets" version = "3.0.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b9/7d/160595ca88ee87ac6ba95d82177d29ec60aaa63821d3077babb22ce031a5/jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b", size = 213149, upload-time = "2025-05-05T12:32:31.004Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/7d/160595ca88ee87ac6ba95d82177d29ec60aaa63821d3077babb22ce031a5/jupyterlab_widgets-3.0.15.tar.gz", hash = "sha256:2920888a0c2922351a9202817957a68c07d99673504d6cd37345299e971bb08b", size = 213149, upload_time = "2025-05-05T12:32:31.004Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c", size = 216571, upload-time = "2025-05-05T12:32:29.534Z" }, + { url = "https://files.pythonhosted.org/packages/43/6a/ca128561b22b60bd5a0c4ea26649e68c8556b82bc70a0c396eebc977fe86/jupyterlab_widgets-3.0.15-py3-none-any.whl", hash = "sha256:d59023d7d7ef71400d51e6fee9a88867f6e65e10a4201605d2d7f3e8f012a31c", size = 216571, upload_time = "2025-05-05T12:32:29.534Z" }, ] [[package]] name = "kiwisolver" version = "1.4.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538, upload-time = "2024-12-24T18:30:51.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/82/59/7c91426a8ac292e1cdd53a63b6d9439abd573c875c3f92c146767dd33faf/kiwisolver-1.4.8.tar.gz", hash = "sha256:23d5f023bdc8c7e54eb65f03ca5d5bb25b601eac4d7f1a042888a1f45237987e", size = 97538, upload_time = "2024-12-24T18:30:51.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/ed/c913ee28936c371418cb167b128066ffb20bbf37771eecc2c97edf8a6e4c/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84", size = 124635, upload-time = "2024-12-24T18:28:51.826Z" }, - { url = "https://files.pythonhosted.org/packages/4c/45/4a7f896f7467aaf5f56ef093d1f329346f3b594e77c6a3c327b2d415f521/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561", size = 66717, upload-time = "2024-12-24T18:28:54.256Z" }, - { url = "https://files.pythonhosted.org/packages/5f/b4/c12b3ac0852a3a68f94598d4c8d569f55361beef6159dce4e7b624160da2/kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7", size = 65413, upload-time = "2024-12-24T18:28:55.184Z" }, - { url = "https://files.pythonhosted.org/packages/a9/98/1df4089b1ed23d83d410adfdc5947245c753bddfbe06541c4aae330e9e70/kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03", size = 1343994, upload-time = "2024-12-24T18:28:57.493Z" }, - { url = "https://files.pythonhosted.org/packages/8d/bf/b4b169b050c8421a7c53ea1ea74e4ef9c335ee9013216c558a047f162d20/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954", size = 1434804, upload-time = "2024-12-24T18:29:00.077Z" }, - { url = "https://files.pythonhosted.org/packages/66/5a/e13bd341fbcf73325ea60fdc8af752addf75c5079867af2e04cc41f34434/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79", size = 1450690, upload-time = "2024-12-24T18:29:01.401Z" }, - { url = "https://files.pythonhosted.org/packages/9b/4f/5955dcb376ba4a830384cc6fab7d7547bd6759fe75a09564910e9e3bb8ea/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6", size = 1376839, upload-time = "2024-12-24T18:29:02.685Z" }, - { url = "https://files.pythonhosted.org/packages/3a/97/5edbed69a9d0caa2e4aa616ae7df8127e10f6586940aa683a496c2c280b9/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0", size = 1435109, upload-time = "2024-12-24T18:29:04.113Z" }, - { url = "https://files.pythonhosted.org/packages/13/fc/e756382cb64e556af6c1809a1bbb22c141bbc2445049f2da06b420fe52bf/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab", size = 2245269, upload-time = "2024-12-24T18:29:05.488Z" }, - { url = "https://files.pythonhosted.org/packages/76/15/e59e45829d7f41c776d138245cabae6515cb4eb44b418f6d4109c478b481/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc", size = 2393468, upload-time = "2024-12-24T18:29:06.79Z" }, - { url = "https://files.pythonhosted.org/packages/e9/39/483558c2a913ab8384d6e4b66a932406f87c95a6080112433da5ed668559/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25", size = 2355394, upload-time = "2024-12-24T18:29:08.24Z" }, - { url = "https://files.pythonhosted.org/packages/01/aa/efad1fbca6570a161d29224f14b082960c7e08268a133fe5dc0f6906820e/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc", size = 2490901, upload-time = "2024-12-24T18:29:09.653Z" }, - { url = "https://files.pythonhosted.org/packages/c9/4f/15988966ba46bcd5ab9d0c8296914436720dd67fca689ae1a75b4ec1c72f/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67", size = 2312306, upload-time = "2024-12-24T18:29:12.644Z" }, - { url = "https://files.pythonhosted.org/packages/2d/27/bdf1c769c83f74d98cbc34483a972f221440703054894a37d174fba8aa68/kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34", size = 71966, upload-time = "2024-12-24T18:29:14.089Z" }, - { url = "https://files.pythonhosted.org/packages/4a/c9/9642ea855604aeb2968a8e145fc662edf61db7632ad2e4fb92424be6b6c0/kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2", size = 65311, upload-time = "2024-12-24T18:29:15.892Z" }, - { url = "https://files.pythonhosted.org/packages/fc/aa/cea685c4ab647f349c3bc92d2daf7ae34c8e8cf405a6dcd3a497f58a2ac3/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502", size = 124152, upload-time = "2024-12-24T18:29:16.85Z" }, - { url = "https://files.pythonhosted.org/packages/c5/0b/8db6d2e2452d60d5ebc4ce4b204feeb16176a851fd42462f66ade6808084/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31", size = 66555, upload-time = "2024-12-24T18:29:19.146Z" }, - { url = "https://files.pythonhosted.org/packages/60/26/d6a0db6785dd35d3ba5bf2b2df0aedc5af089962c6eb2cbf67a15b81369e/kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb", size = 65067, upload-time = "2024-12-24T18:29:20.096Z" }, - { url = "https://files.pythonhosted.org/packages/c9/ed/1d97f7e3561e09757a196231edccc1bcf59d55ddccefa2afc9c615abd8e0/kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f", size = 1378443, upload-time = "2024-12-24T18:29:22.843Z" }, - { url = "https://files.pythonhosted.org/packages/29/61/39d30b99954e6b46f760e6289c12fede2ab96a254c443639052d1b573fbc/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc", size = 1472728, upload-time = "2024-12-24T18:29:24.463Z" }, - { url = "https://files.pythonhosted.org/packages/0c/3e/804163b932f7603ef256e4a715e5843a9600802bb23a68b4e08c8c0ff61d/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a", size = 1478388, upload-time = "2024-12-24T18:29:25.776Z" }, - { url = "https://files.pythonhosted.org/packages/8a/9e/60eaa75169a154700be74f875a4d9961b11ba048bef315fbe89cb6999056/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a", size = 1413849, upload-time = "2024-12-24T18:29:27.202Z" }, - { url = "https://files.pythonhosted.org/packages/bc/b3/9458adb9472e61a998c8c4d95cfdfec91c73c53a375b30b1428310f923e4/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a", size = 1475533, upload-time = "2024-12-24T18:29:28.638Z" }, - { url = "https://files.pythonhosted.org/packages/e4/7a/0a42d9571e35798de80aef4bb43a9b672aa7f8e58643d7bd1950398ffb0a/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3", size = 2268898, upload-time = "2024-12-24T18:29:30.368Z" }, - { url = "https://files.pythonhosted.org/packages/d9/07/1255dc8d80271400126ed8db35a1795b1a2c098ac3a72645075d06fe5c5d/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b", size = 2425605, upload-time = "2024-12-24T18:29:33.151Z" }, - { url = "https://files.pythonhosted.org/packages/84/df/5a3b4cf13780ef6f6942df67b138b03b7e79e9f1f08f57c49957d5867f6e/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4", size = 2375801, upload-time = "2024-12-24T18:29:34.584Z" }, - { url = "https://files.pythonhosted.org/packages/8f/10/2348d068e8b0f635c8c86892788dac7a6b5c0cb12356620ab575775aad89/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d", size = 2520077, upload-time = "2024-12-24T18:29:36.138Z" }, - { url = "https://files.pythonhosted.org/packages/32/d8/014b89fee5d4dce157d814303b0fce4d31385a2af4c41fed194b173b81ac/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8", size = 2338410, upload-time = "2024-12-24T18:29:39.991Z" }, - { url = "https://files.pythonhosted.org/packages/bd/72/dfff0cc97f2a0776e1c9eb5bef1ddfd45f46246c6533b0191887a427bca5/kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50", size = 71853, upload-time = "2024-12-24T18:29:42.006Z" }, - { url = "https://files.pythonhosted.org/packages/dc/85/220d13d914485c0948a00f0b9eb419efaf6da81b7d72e88ce2391f7aed8d/kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476", size = 65424, upload-time = "2024-12-24T18:29:44.38Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/e62464a652f4f8cd9006e13d07abad844a47df1e6537f73ddfbf1bc997ec/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09", size = 124156, upload-time = "2024-12-24T18:29:45.368Z" }, - { url = "https://files.pythonhosted.org/packages/8d/2d/f13d06998b546a2ad4f48607a146e045bbe48030774de29f90bdc573df15/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1", size = 66555, upload-time = "2024-12-24T18:29:46.37Z" }, - { url = "https://files.pythonhosted.org/packages/59/e3/b8bd14b0a54998a9fd1e8da591c60998dc003618cb19a3f94cb233ec1511/kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c", size = 65071, upload-time = "2024-12-24T18:29:47.333Z" }, - { url = "https://files.pythonhosted.org/packages/f0/1c/6c86f6d85ffe4d0ce04228d976f00674f1df5dc893bf2dd4f1928748f187/kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b", size = 1378053, upload-time = "2024-12-24T18:29:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/4e/b9/1c6e9f6dcb103ac5cf87cb695845f5fa71379021500153566d8a8a9fc291/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47", size = 1472278, upload-time = "2024-12-24T18:29:51.164Z" }, - { url = "https://files.pythonhosted.org/packages/ee/81/aca1eb176de671f8bda479b11acdc42c132b61a2ac861c883907dde6debb/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16", size = 1478139, upload-time = "2024-12-24T18:29:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/49/f4/e081522473671c97b2687d380e9e4c26f748a86363ce5af48b4a28e48d06/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc", size = 1413517, upload-time = "2024-12-24T18:29:53.941Z" }, - { url = "https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246", size = 1474952, upload-time = "2024-12-24T18:29:56.523Z" }, - { url = "https://files.pythonhosted.org/packages/82/13/13fa685ae167bee5d94b415991c4fc7bb0a1b6ebea6e753a87044b209678/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794", size = 2269132, upload-time = "2024-12-24T18:29:57.989Z" }, - { url = "https://files.pythonhosted.org/packages/ef/92/bb7c9395489b99a6cb41d502d3686bac692586db2045adc19e45ee64ed23/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b", size = 2425997, upload-time = "2024-12-24T18:29:59.393Z" }, - { url = "https://files.pythonhosted.org/packages/ed/12/87f0e9271e2b63d35d0d8524954145837dd1a6c15b62a2d8c1ebe0f182b4/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3", size = 2376060, upload-time = "2024-12-24T18:30:01.338Z" }, - { url = "https://files.pythonhosted.org/packages/02/6e/c8af39288edbce8bf0fa35dee427b082758a4b71e9c91ef18fa667782138/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957", size = 2520471, upload-time = "2024-12-24T18:30:04.574Z" }, - { url = "https://files.pythonhosted.org/packages/13/78/df381bc7b26e535c91469f77f16adcd073beb3e2dd25042efd064af82323/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb", size = 2338793, upload-time = "2024-12-24T18:30:06.25Z" }, - { url = "https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2", size = 71855, upload-time = "2024-12-24T18:30:07.535Z" }, - { url = "https://files.pythonhosted.org/packages/a0/b6/21529d595b126ac298fdd90b705d87d4c5693de60023e0efcb4f387ed99e/kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30", size = 65430, upload-time = "2024-12-24T18:30:08.504Z" }, - { url = "https://files.pythonhosted.org/packages/34/bd/b89380b7298e3af9b39f49334e3e2a4af0e04819789f04b43d560516c0c8/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c", size = 126294, upload-time = "2024-12-24T18:30:09.508Z" }, - { url = "https://files.pythonhosted.org/packages/83/41/5857dc72e5e4148eaac5aa76e0703e594e4465f8ab7ec0fc60e3a9bb8fea/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc", size = 67736, upload-time = "2024-12-24T18:30:11.039Z" }, - { url = "https://files.pythonhosted.org/packages/e1/d1/be059b8db56ac270489fb0b3297fd1e53d195ba76e9bbb30e5401fa6b759/kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712", size = 66194, upload-time = "2024-12-24T18:30:14.886Z" }, - { url = "https://files.pythonhosted.org/packages/e1/83/4b73975f149819eb7dcf9299ed467eba068ecb16439a98990dcb12e63fdd/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e", size = 1465942, upload-time = "2024-12-24T18:30:18.927Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2c/30a5cdde5102958e602c07466bce058b9d7cb48734aa7a4327261ac8e002/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880", size = 1595341, upload-time = "2024-12-24T18:30:22.102Z" }, - { url = "https://files.pythonhosted.org/packages/ff/9b/1e71db1c000385aa069704f5990574b8244cce854ecd83119c19e83c9586/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062", size = 1598455, upload-time = "2024-12-24T18:30:24.947Z" }, - { url = "https://files.pythonhosted.org/packages/85/92/c8fec52ddf06231b31cbb779af77e99b8253cd96bd135250b9498144c78b/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7", size = 1522138, upload-time = "2024-12-24T18:30:26.286Z" }, - { url = "https://files.pythonhosted.org/packages/0b/51/9eb7e2cd07a15d8bdd976f6190c0164f92ce1904e5c0c79198c4972926b7/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed", size = 1582857, upload-time = "2024-12-24T18:30:28.86Z" }, - { url = "https://files.pythonhosted.org/packages/0f/95/c5a00387a5405e68ba32cc64af65ce881a39b98d73cc394b24143bebc5b8/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d", size = 2293129, upload-time = "2024-12-24T18:30:30.34Z" }, - { url = "https://files.pythonhosted.org/packages/44/83/eeb7af7d706b8347548313fa3a3a15931f404533cc54fe01f39e830dd231/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165", size = 2421538, upload-time = "2024-12-24T18:30:33.334Z" }, - { url = "https://files.pythonhosted.org/packages/05/f9/27e94c1b3eb29e6933b6986ffc5fa1177d2cd1f0c8efc5f02c91c9ac61de/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6", size = 2390661, upload-time = "2024-12-24T18:30:34.939Z" }, - { url = "https://files.pythonhosted.org/packages/d9/d4/3c9735faa36ac591a4afcc2980d2691000506050b7a7e80bcfe44048daa7/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90", size = 2546710, upload-time = "2024-12-24T18:30:37.281Z" }, - { url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213, upload-time = "2024-12-24T18:30:40.019Z" }, + { url = "https://files.pythonhosted.org/packages/da/ed/c913ee28936c371418cb167b128066ffb20bbf37771eecc2c97edf8a6e4c/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a4d3601908c560bdf880f07d94f31d734afd1bb71e96585cace0e38ef44c6d84", size = 124635, upload_time = "2024-12-24T18:28:51.826Z" }, + { url = "https://files.pythonhosted.org/packages/4c/45/4a7f896f7467aaf5f56ef093d1f329346f3b594e77c6a3c327b2d415f521/kiwisolver-1.4.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:856b269c4d28a5c0d5e6c1955ec36ebfd1651ac00e1ce0afa3e28da95293b561", size = 66717, upload_time = "2024-12-24T18:28:54.256Z" }, + { url = "https://files.pythonhosted.org/packages/5f/b4/c12b3ac0852a3a68f94598d4c8d569f55361beef6159dce4e7b624160da2/kiwisolver-1.4.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c2b9a96e0f326205af81a15718a9073328df1173a2619a68553decb7097fd5d7", size = 65413, upload_time = "2024-12-24T18:28:55.184Z" }, + { url = "https://files.pythonhosted.org/packages/a9/98/1df4089b1ed23d83d410adfdc5947245c753bddfbe06541c4aae330e9e70/kiwisolver-1.4.8-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5020c83e8553f770cb3b5fc13faac40f17e0b205bd237aebd21d53d733adb03", size = 1343994, upload_time = "2024-12-24T18:28:57.493Z" }, + { url = "https://files.pythonhosted.org/packages/8d/bf/b4b169b050c8421a7c53ea1ea74e4ef9c335ee9013216c558a047f162d20/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dace81d28c787956bfbfbbfd72fdcef014f37d9b48830829e488fdb32b49d954", size = 1434804, upload_time = "2024-12-24T18:29:00.077Z" }, + { url = "https://files.pythonhosted.org/packages/66/5a/e13bd341fbcf73325ea60fdc8af752addf75c5079867af2e04cc41f34434/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11e1022b524bd48ae56c9b4f9296bce77e15a2e42a502cceba602f804b32bb79", size = 1450690, upload_time = "2024-12-24T18:29:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/9b/4f/5955dcb376ba4a830384cc6fab7d7547bd6759fe75a09564910e9e3bb8ea/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b9b4d2892fefc886f30301cdd80debd8bb01ecdf165a449eb6e78f79f0fabd6", size = 1376839, upload_time = "2024-12-24T18:29:02.685Z" }, + { url = "https://files.pythonhosted.org/packages/3a/97/5edbed69a9d0caa2e4aa616ae7df8127e10f6586940aa683a496c2c280b9/kiwisolver-1.4.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a96c0e790ee875d65e340ab383700e2b4891677b7fcd30a699146f9384a2bb0", size = 1435109, upload_time = "2024-12-24T18:29:04.113Z" }, + { url = "https://files.pythonhosted.org/packages/13/fc/e756382cb64e556af6c1809a1bbb22c141bbc2445049f2da06b420fe52bf/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23454ff084b07ac54ca8be535f4174170c1094a4cff78fbae4f73a4bcc0d4dab", size = 2245269, upload_time = "2024-12-24T18:29:05.488Z" }, + { url = "https://files.pythonhosted.org/packages/76/15/e59e45829d7f41c776d138245cabae6515cb4eb44b418f6d4109c478b481/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:87b287251ad6488e95b4f0b4a79a6d04d3ea35fde6340eb38fbd1ca9cd35bbbc", size = 2393468, upload_time = "2024-12-24T18:29:06.79Z" }, + { url = "https://files.pythonhosted.org/packages/e9/39/483558c2a913ab8384d6e4b66a932406f87c95a6080112433da5ed668559/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b21dbe165081142b1232a240fc6383fd32cdd877ca6cc89eab93e5f5883e1c25", size = 2355394, upload_time = "2024-12-24T18:29:08.24Z" }, + { url = "https://files.pythonhosted.org/packages/01/aa/efad1fbca6570a161d29224f14b082960c7e08268a133fe5dc0f6906820e/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:768cade2c2df13db52475bd28d3a3fac8c9eff04b0e9e2fda0f3760f20b3f7fc", size = 2490901, upload_time = "2024-12-24T18:29:09.653Z" }, + { url = "https://files.pythonhosted.org/packages/c9/4f/15988966ba46bcd5ab9d0c8296914436720dd67fca689ae1a75b4ec1c72f/kiwisolver-1.4.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d47cfb2650f0e103d4bf68b0b5804c68da97272c84bb12850d877a95c056bd67", size = 2312306, upload_time = "2024-12-24T18:29:12.644Z" }, + { url = "https://files.pythonhosted.org/packages/2d/27/bdf1c769c83f74d98cbc34483a972f221440703054894a37d174fba8aa68/kiwisolver-1.4.8-cp311-cp311-win_amd64.whl", hash = "sha256:ed33ca2002a779a2e20eeb06aea7721b6e47f2d4b8a8ece979d8ba9e2a167e34", size = 71966, upload_time = "2024-12-24T18:29:14.089Z" }, + { url = "https://files.pythonhosted.org/packages/4a/c9/9642ea855604aeb2968a8e145fc662edf61db7632ad2e4fb92424be6b6c0/kiwisolver-1.4.8-cp311-cp311-win_arm64.whl", hash = "sha256:16523b40aab60426ffdebe33ac374457cf62863e330a90a0383639ce14bf44b2", size = 65311, upload_time = "2024-12-24T18:29:15.892Z" }, + { url = "https://files.pythonhosted.org/packages/fc/aa/cea685c4ab647f349c3bc92d2daf7ae34c8e8cf405a6dcd3a497f58a2ac3/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d6af5e8815fd02997cb6ad9bbed0ee1e60014438ee1a5c2444c96f87b8843502", size = 124152, upload_time = "2024-12-24T18:29:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/c5/0b/8db6d2e2452d60d5ebc4ce4b204feeb16176a851fd42462f66ade6808084/kiwisolver-1.4.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bade438f86e21d91e0cf5dd7c0ed00cda0f77c8c1616bd83f9fc157fa6760d31", size = 66555, upload_time = "2024-12-24T18:29:19.146Z" }, + { url = "https://files.pythonhosted.org/packages/60/26/d6a0db6785dd35d3ba5bf2b2df0aedc5af089962c6eb2cbf67a15b81369e/kiwisolver-1.4.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b83dc6769ddbc57613280118fb4ce3cd08899cc3369f7d0e0fab518a7cf37fdb", size = 65067, upload_time = "2024-12-24T18:29:20.096Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ed/1d97f7e3561e09757a196231edccc1bcf59d55ddccefa2afc9c615abd8e0/kiwisolver-1.4.8-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111793b232842991be367ed828076b03d96202c19221b5ebab421ce8bcad016f", size = 1378443, upload_time = "2024-12-24T18:29:22.843Z" }, + { url = "https://files.pythonhosted.org/packages/29/61/39d30b99954e6b46f760e6289c12fede2ab96a254c443639052d1b573fbc/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:257af1622860e51b1a9d0ce387bf5c2c4f36a90594cb9514f55b074bcc787cfc", size = 1472728, upload_time = "2024-12-24T18:29:24.463Z" }, + { url = "https://files.pythonhosted.org/packages/0c/3e/804163b932f7603ef256e4a715e5843a9600802bb23a68b4e08c8c0ff61d/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:69b5637c3f316cab1ec1c9a12b8c5f4750a4c4b71af9157645bf32830e39c03a", size = 1478388, upload_time = "2024-12-24T18:29:25.776Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9e/60eaa75169a154700be74f875a4d9961b11ba048bef315fbe89cb6999056/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:782bb86f245ec18009890e7cb8d13a5ef54dcf2ebe18ed65f795e635a96a1c6a", size = 1413849, upload_time = "2024-12-24T18:29:27.202Z" }, + { url = "https://files.pythonhosted.org/packages/bc/b3/9458adb9472e61a998c8c4d95cfdfec91c73c53a375b30b1428310f923e4/kiwisolver-1.4.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc978a80a0db3a66d25767b03688f1147a69e6237175c0f4ffffaaedf744055a", size = 1475533, upload_time = "2024-12-24T18:29:28.638Z" }, + { url = "https://files.pythonhosted.org/packages/e4/7a/0a42d9571e35798de80aef4bb43a9b672aa7f8e58643d7bd1950398ffb0a/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:36dbbfd34838500a31f52c9786990d00150860e46cd5041386f217101350f0d3", size = 2268898, upload_time = "2024-12-24T18:29:30.368Z" }, + { url = "https://files.pythonhosted.org/packages/d9/07/1255dc8d80271400126ed8db35a1795b1a2c098ac3a72645075d06fe5c5d/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:eaa973f1e05131de5ff3569bbba7f5fd07ea0595d3870ed4a526d486fe57fa1b", size = 2425605, upload_time = "2024-12-24T18:29:33.151Z" }, + { url = "https://files.pythonhosted.org/packages/84/df/5a3b4cf13780ef6f6942df67b138b03b7e79e9f1f08f57c49957d5867f6e/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a66f60f8d0c87ab7f59b6fb80e642ebb29fec354a4dfad687ca4092ae69d04f4", size = 2375801, upload_time = "2024-12-24T18:29:34.584Z" }, + { url = "https://files.pythonhosted.org/packages/8f/10/2348d068e8b0f635c8c86892788dac7a6b5c0cb12356620ab575775aad89/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:858416b7fb777a53f0c59ca08190ce24e9abbd3cffa18886a5781b8e3e26f65d", size = 2520077, upload_time = "2024-12-24T18:29:36.138Z" }, + { url = "https://files.pythonhosted.org/packages/32/d8/014b89fee5d4dce157d814303b0fce4d31385a2af4c41fed194b173b81ac/kiwisolver-1.4.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:085940635c62697391baafaaeabdf3dd7a6c3643577dde337f4d66eba021b2b8", size = 2338410, upload_time = "2024-12-24T18:29:39.991Z" }, + { url = "https://files.pythonhosted.org/packages/bd/72/dfff0cc97f2a0776e1c9eb5bef1ddfd45f46246c6533b0191887a427bca5/kiwisolver-1.4.8-cp312-cp312-win_amd64.whl", hash = "sha256:01c3d31902c7db5fb6182832713d3b4122ad9317c2c5877d0539227d96bb2e50", size = 71853, upload_time = "2024-12-24T18:29:42.006Z" }, + { url = "https://files.pythonhosted.org/packages/dc/85/220d13d914485c0948a00f0b9eb419efaf6da81b7d72e88ce2391f7aed8d/kiwisolver-1.4.8-cp312-cp312-win_arm64.whl", hash = "sha256:a3c44cb68861de93f0c4a8175fbaa691f0aa22550c331fefef02b618a9dcb476", size = 65424, upload_time = "2024-12-24T18:29:44.38Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/e62464a652f4f8cd9006e13d07abad844a47df1e6537f73ddfbf1bc997ec/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1c8ceb754339793c24aee1c9fb2485b5b1f5bb1c2c214ff13368431e51fc9a09", size = 124156, upload_time = "2024-12-24T18:29:45.368Z" }, + { url = "https://files.pythonhosted.org/packages/8d/2d/f13d06998b546a2ad4f48607a146e045bbe48030774de29f90bdc573df15/kiwisolver-1.4.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:54a62808ac74b5e55a04a408cda6156f986cefbcf0ada13572696b507cc92fa1", size = 66555, upload_time = "2024-12-24T18:29:46.37Z" }, + { url = "https://files.pythonhosted.org/packages/59/e3/b8bd14b0a54998a9fd1e8da591c60998dc003618cb19a3f94cb233ec1511/kiwisolver-1.4.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68269e60ee4929893aad82666821aaacbd455284124817af45c11e50a4b42e3c", size = 65071, upload_time = "2024-12-24T18:29:47.333Z" }, + { url = "https://files.pythonhosted.org/packages/f0/1c/6c86f6d85ffe4d0ce04228d976f00674f1df5dc893bf2dd4f1928748f187/kiwisolver-1.4.8-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34d142fba9c464bc3bbfeff15c96eab0e7310343d6aefb62a79d51421fcc5f1b", size = 1378053, upload_time = "2024-12-24T18:29:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/4e/b9/1c6e9f6dcb103ac5cf87cb695845f5fa71379021500153566d8a8a9fc291/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc373e0eef45b59197de815b1b28ef89ae3955e7722cc9710fb91cd77b7f47", size = 1472278, upload_time = "2024-12-24T18:29:51.164Z" }, + { url = "https://files.pythonhosted.org/packages/ee/81/aca1eb176de671f8bda479b11acdc42c132b61a2ac861c883907dde6debb/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:77e6f57a20b9bd4e1e2cedda4d0b986ebd0216236f0106e55c28aea3d3d69b16", size = 1478139, upload_time = "2024-12-24T18:29:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/49/f4/e081522473671c97b2687d380e9e4c26f748a86363ce5af48b4a28e48d06/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08e77738ed7538f036cd1170cbed942ef749137b1311fa2bbe2a7fda2f6bf3cc", size = 1413517, upload_time = "2024-12-24T18:29:53.941Z" }, + { url = "https://files.pythonhosted.org/packages/8f/e9/6a7d025d8da8c4931522922cd706105aa32b3291d1add8c5427cdcd66e63/kiwisolver-1.4.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5ce1e481a74b44dd5e92ff03ea0cb371ae7a0268318e202be06c8f04f4f1246", size = 1474952, upload_time = "2024-12-24T18:29:56.523Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/13fa685ae167bee5d94b415991c4fc7bb0a1b6ebea6e753a87044b209678/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:fc2ace710ba7c1dfd1a3b42530b62b9ceed115f19a1656adefce7b1782a37794", size = 2269132, upload_time = "2024-12-24T18:29:57.989Z" }, + { url = "https://files.pythonhosted.org/packages/ef/92/bb7c9395489b99a6cb41d502d3686bac692586db2045adc19e45ee64ed23/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3452046c37c7692bd52b0e752b87954ef86ee2224e624ef7ce6cb21e8c41cc1b", size = 2425997, upload_time = "2024-12-24T18:29:59.393Z" }, + { url = "https://files.pythonhosted.org/packages/ed/12/87f0e9271e2b63d35d0d8524954145837dd1a6c15b62a2d8c1ebe0f182b4/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7e9a60b50fe8b2ec6f448fe8d81b07e40141bfced7f896309df271a0b92f80f3", size = 2376060, upload_time = "2024-12-24T18:30:01.338Z" }, + { url = "https://files.pythonhosted.org/packages/02/6e/c8af39288edbce8bf0fa35dee427b082758a4b71e9c91ef18fa667782138/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:918139571133f366e8362fa4a297aeba86c7816b7ecf0bc79168080e2bd79957", size = 2520471, upload_time = "2024-12-24T18:30:04.574Z" }, + { url = "https://files.pythonhosted.org/packages/13/78/df381bc7b26e535c91469f77f16adcd073beb3e2dd25042efd064af82323/kiwisolver-1.4.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e063ef9f89885a1d68dd8b2e18f5ead48653176d10a0e324e3b0030e3a69adeb", size = 2338793, upload_time = "2024-12-24T18:30:06.25Z" }, + { url = "https://files.pythonhosted.org/packages/d0/dc/c1abe38c37c071d0fc71c9a474fd0b9ede05d42f5a458d584619cfd2371a/kiwisolver-1.4.8-cp313-cp313-win_amd64.whl", hash = "sha256:a17b7c4f5b2c51bb68ed379defd608a03954a1845dfed7cc0117f1cc8a9b7fd2", size = 71855, upload_time = "2024-12-24T18:30:07.535Z" }, + { url = "https://files.pythonhosted.org/packages/a0/b6/21529d595b126ac298fdd90b705d87d4c5693de60023e0efcb4f387ed99e/kiwisolver-1.4.8-cp313-cp313-win_arm64.whl", hash = "sha256:3cd3bc628b25f74aedc6d374d5babf0166a92ff1317f46267f12d2ed54bc1d30", size = 65430, upload_time = "2024-12-24T18:30:08.504Z" }, + { url = "https://files.pythonhosted.org/packages/34/bd/b89380b7298e3af9b39f49334e3e2a4af0e04819789f04b43d560516c0c8/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:370fd2df41660ed4e26b8c9d6bbcad668fbe2560462cba151a721d49e5b6628c", size = 126294, upload_time = "2024-12-24T18:30:09.508Z" }, + { url = "https://files.pythonhosted.org/packages/83/41/5857dc72e5e4148eaac5aa76e0703e594e4465f8ab7ec0fc60e3a9bb8fea/kiwisolver-1.4.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:84a2f830d42707de1d191b9490ac186bf7997a9495d4e9072210a1296345f7dc", size = 67736, upload_time = "2024-12-24T18:30:11.039Z" }, + { url = "https://files.pythonhosted.org/packages/e1/d1/be059b8db56ac270489fb0b3297fd1e53d195ba76e9bbb30e5401fa6b759/kiwisolver-1.4.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7a3ad337add5148cf51ce0b55642dc551c0b9d6248458a757f98796ca7348712", size = 66194, upload_time = "2024-12-24T18:30:14.886Z" }, + { url = "https://files.pythonhosted.org/packages/e1/83/4b73975f149819eb7dcf9299ed467eba068ecb16439a98990dcb12e63fdd/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7506488470f41169b86d8c9aeff587293f530a23a23a49d6bc64dab66bedc71e", size = 1465942, upload_time = "2024-12-24T18:30:18.927Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2c/30a5cdde5102958e602c07466bce058b9d7cb48734aa7a4327261ac8e002/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f0121b07b356a22fb0414cec4666bbe36fd6d0d759db3d37228f496ed67c880", size = 1595341, upload_time = "2024-12-24T18:30:22.102Z" }, + { url = "https://files.pythonhosted.org/packages/ff/9b/1e71db1c000385aa069704f5990574b8244cce854ecd83119c19e83c9586/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d6d6bd87df62c27d4185de7c511c6248040afae67028a8a22012b010bc7ad062", size = 1598455, upload_time = "2024-12-24T18:30:24.947Z" }, + { url = "https://files.pythonhosted.org/packages/85/92/c8fec52ddf06231b31cbb779af77e99b8253cd96bd135250b9498144c78b/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:291331973c64bb9cce50bbe871fb2e675c4331dab4f31abe89f175ad7679a4d7", size = 1522138, upload_time = "2024-12-24T18:30:26.286Z" }, + { url = "https://files.pythonhosted.org/packages/0b/51/9eb7e2cd07a15d8bdd976f6190c0164f92ce1904e5c0c79198c4972926b7/kiwisolver-1.4.8-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:893f5525bb92d3d735878ec00f781b2de998333659507d29ea4466208df37bed", size = 1582857, upload_time = "2024-12-24T18:30:28.86Z" }, + { url = "https://files.pythonhosted.org/packages/0f/95/c5a00387a5405e68ba32cc64af65ce881a39b98d73cc394b24143bebc5b8/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b47a465040146981dc9db8647981b8cb96366fbc8d452b031e4f8fdffec3f26d", size = 2293129, upload_time = "2024-12-24T18:30:30.34Z" }, + { url = "https://files.pythonhosted.org/packages/44/83/eeb7af7d706b8347548313fa3a3a15931f404533cc54fe01f39e830dd231/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:99cea8b9dd34ff80c521aef46a1dddb0dcc0283cf18bde6d756f1e6f31772165", size = 2421538, upload_time = "2024-12-24T18:30:33.334Z" }, + { url = "https://files.pythonhosted.org/packages/05/f9/27e94c1b3eb29e6933b6986ffc5fa1177d2cd1f0c8efc5f02c91c9ac61de/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:151dffc4865e5fe6dafce5480fab84f950d14566c480c08a53c663a0020504b6", size = 2390661, upload_time = "2024-12-24T18:30:34.939Z" }, + { url = "https://files.pythonhosted.org/packages/d9/d4/3c9735faa36ac591a4afcc2980d2691000506050b7a7e80bcfe44048daa7/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:577facaa411c10421314598b50413aa1ebcf5126f704f1e5d72d7e4e9f020d90", size = 2546710, upload_time = "2024-12-24T18:30:37.281Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fa/be89a49c640930180657482a74970cdcf6f7072c8d2471e1babe17a222dc/kiwisolver-1.4.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:be4816dc51c8a471749d664161b434912eee82f2ea66bd7628bd14583a833e85", size = 2349213, upload_time = "2024-12-24T18:30:40.019Z" }, ] [[package]] name = "lark" version = "1.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload-time = "2024-08-13T19:49:00.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/af/60/bc7622aefb2aee1c0b4ba23c1446d3e30225c8770b38d7aedbfb65ca9d5a/lark-1.2.2.tar.gz", hash = "sha256:ca807d0162cd16cef15a8feecb862d7319e7a09bdb13aef927968e45040fed80", size = 252132, upload_time = "2024-08-13T19:49:00.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload-time = "2024-08-13T19:48:58.603Z" }, + { url = "https://files.pythonhosted.org/packages/2d/00/d90b10b962b4277f5e64a78b6609968859ff86889f5b898c1a778c06ec00/lark-1.2.2-py3-none-any.whl", hash = "sha256:c2276486b02f0f1b90be155f2c8ba4a8e194d42775786db622faccd652d8e80c", size = 111036, upload_time = "2024-08-13T19:48:58.603Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.44.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/6a/95a3d3610d5c75293d5dbbb2a76480d5d4eeba641557b69fe90af6c5b84e/llvmlite-0.44.0.tar.gz", hash = "sha256:07667d66a5d150abed9157ab6c0b9393c9356f229784a4385c02f99e94fc94d4", size = 171880, upload_time = "2025-01-20T11:14:41.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/e2/86b245397052386595ad726f9742e5223d7aea999b18c518a50e96c3aca4/llvmlite-0.44.0-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:eed7d5f29136bda63b6d7804c279e2b72e08c952b7c5df61f45db408e0ee52f3", size = 28132305, upload_time = "2025-01-20T11:12:53.936Z" }, + { url = "https://files.pythonhosted.org/packages/ff/ec/506902dc6870249fbe2466d9cf66d531265d0f3a1157213c8f986250c033/llvmlite-0.44.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ace564d9fa44bb91eb6e6d8e7754977783c68e90a471ea7ce913bff30bd62427", size = 26201090, upload_time = "2025-01-20T11:12:59.847Z" }, + { url = "https://files.pythonhosted.org/packages/99/fe/d030f1849ebb1f394bb3f7adad5e729b634fb100515594aca25c354ffc62/llvmlite-0.44.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c5d22c3bfc842668168a786af4205ec8e3ad29fb1bc03fd11fd48460d0df64c1", size = 42361858, upload_time = "2025-01-20T11:13:07.623Z" }, + { url = "https://files.pythonhosted.org/packages/d7/7a/ce6174664b9077fc673d172e4c888cb0b128e707e306bc33fff8c2035f0d/llvmlite-0.44.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f01a394e9c9b7b1d4e63c327b096d10f6f0ed149ef53d38a09b3749dcf8c9610", size = 41184200, upload_time = "2025-01-20T11:13:20.058Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c6/258801143975a6d09a373f2641237992496e15567b907a4d401839d671b8/llvmlite-0.44.0-cp311-cp311-win_amd64.whl", hash = "sha256:d8489634d43c20cd0ad71330dde1d5bc7b9966937a263ff1ec1cebb90dc50955", size = 30331193, upload_time = "2025-01-20T11:13:26.976Z" }, + { url = "https://files.pythonhosted.org/packages/15/86/e3c3195b92e6e492458f16d233e58a1a812aa2bfbef9bdd0fbafcec85c60/llvmlite-0.44.0-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:1d671a56acf725bf1b531d5ef76b86660a5ab8ef19bb6a46064a705c6ca80aad", size = 28132297, upload_time = "2025-01-20T11:13:32.57Z" }, + { url = "https://files.pythonhosted.org/packages/d6/53/373b6b8be67b9221d12b24125fd0ec56b1078b660eeae266ec388a6ac9a0/llvmlite-0.44.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f79a728e0435493611c9f405168682bb75ffd1fbe6fc360733b850c80a026db", size = 26201105, upload_time = "2025-01-20T11:13:38.744Z" }, + { url = "https://files.pythonhosted.org/packages/cb/da/8341fd3056419441286c8e26bf436923021005ece0bff5f41906476ae514/llvmlite-0.44.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0143a5ef336da14deaa8ec26c5449ad5b6a2b564df82fcef4be040b9cacfea9", size = 42361901, upload_time = "2025-01-20T11:13:46.711Z" }, + { url = "https://files.pythonhosted.org/packages/53/ad/d79349dc07b8a395a99153d7ce8b01d6fcdc9f8231355a5df55ded649b61/llvmlite-0.44.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d752f89e31b66db6f8da06df8b39f9b91e78c5feea1bf9e8c1fba1d1c24c065d", size = 41184247, upload_time = "2025-01-20T11:13:56.159Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3b/a9a17366af80127bd09decbe2a54d8974b6d8b274b39bf47fbaedeec6307/llvmlite-0.44.0-cp312-cp312-win_amd64.whl", hash = "sha256:eae7e2d4ca8f88f89d315b48c6b741dcb925d6a1042da694aa16ab3dd4cbd3a1", size = 30332380, upload_time = "2025-01-20T11:14:02.442Z" }, + { url = "https://files.pythonhosted.org/packages/89/24/4c0ca705a717514c2092b18476e7a12c74d34d875e05e4d742618ebbf449/llvmlite-0.44.0-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:319bddd44e5f71ae2689859b7203080716448a3cd1128fb144fe5c055219d516", size = 28132306, upload_time = "2025-01-20T11:14:09.035Z" }, + { url = "https://files.pythonhosted.org/packages/01/cf/1dd5a60ba6aee7122ab9243fd614abcf22f36b0437cbbe1ccf1e3391461c/llvmlite-0.44.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c58867118bad04a0bb22a2e0068c693719658105e40009ffe95c7000fcde88e", size = 26201090, upload_time = "2025-01-20T11:14:15.401Z" }, + { url = "https://files.pythonhosted.org/packages/d2/1b/656f5a357de7135a3777bd735cc7c9b8f23b4d37465505bd0eaf4be9befe/llvmlite-0.44.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46224058b13c96af1365290bdfebe9a6264ae62fb79b2b55693deed11657a8bf", size = 42361904, upload_time = "2025-01-20T11:14:22.949Z" }, + { url = "https://files.pythonhosted.org/packages/d8/e1/12c5f20cb9168fb3464a34310411d5ad86e4163c8ff2d14a2b57e5cc6bac/llvmlite-0.44.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0097052c32bf721a4efc03bd109d335dfa57d9bffb3d4c24cc680711b8b4fc", size = 41184245, upload_time = "2025-01-20T11:14:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/d0/81/e66fc86539293282fd9cb7c9417438e897f369e79ffb62e1ae5e5154d4dd/llvmlite-0.44.0-cp313-cp313-win_amd64.whl", hash = "sha256:2fb7c4f2fb86cbae6dca3db9ab203eeea0e22d73b99bc2341cdf9de93612e930", size = 30331193, upload_time = "2025-01-20T11:14:38.578Z" }, ] [[package]] name = "markupsafe" version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload_time = "2024-10-18T15:21:54.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, - { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, - { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, - { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, - { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, - { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, - { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, - { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, - { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, - { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, - { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, - { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, - { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, - { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload_time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload_time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload_time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload_time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload_time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload_time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload_time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload_time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload_time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload_time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload_time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload_time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload_time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload_time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload_time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload_time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload_time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload_time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload_time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload_time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload_time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload_time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload_time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload_time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload_time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload_time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload_time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload_time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload_time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload_time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload_time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload_time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload_time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload_time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload_time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload_time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload_time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload_time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload_time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload_time = "2024-10-18T15:21:42.784Z" }, ] [[package]] @@ -1090,53 +1113,53 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/43/91/f2939bb60b7ebf12478b030e0d7f340247390f402b3b189616aad790c366/matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076", size = 34804044, upload-time = "2025-07-31T18:09:33.805Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/91/f2939bb60b7ebf12478b030e0d7f340247390f402b3b189616aad790c366/matplotlib-3.10.5.tar.gz", hash = "sha256:352ed6ccfb7998a00881692f38b4ca083c691d3e275b4145423704c34c909076", size = 34804044, upload_time = "2025-07-31T18:09:33.805Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/c7/1f2db90a1d43710478bb1e9b57b162852f79234d28e4f48a28cc415aa583/matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf", size = 8239216, upload-time = "2025-07-31T18:07:51.947Z" }, - { url = "https://files.pythonhosted.org/packages/82/6d/ca6844c77a4f89b1c9e4d481c412e1d1dbabf2aae2cbc5aa2da4a1d6683e/matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf", size = 8102130, upload-time = "2025-07-31T18:07:53.65Z" }, - { url = "https://files.pythonhosted.org/packages/1d/1e/5e187a30cc673a3e384f3723e5f3c416033c1d8d5da414f82e4e731128ea/matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a", size = 8666471, upload-time = "2025-07-31T18:07:55.304Z" }, - { url = "https://files.pythonhosted.org/packages/03/c0/95540d584d7d645324db99a845ac194e915ef75011a0d5e19e1b5cee7e69/matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc", size = 9500518, upload-time = "2025-07-31T18:07:57.199Z" }, - { url = "https://files.pythonhosted.org/packages/ba/2e/e019352099ea58b4169adb9c6e1a2ad0c568c6377c2b677ee1f06de2adc7/matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89", size = 9552372, upload-time = "2025-07-31T18:07:59.41Z" }, - { url = "https://files.pythonhosted.org/packages/b7/81/3200b792a5e8b354f31f4101ad7834743ad07b6d620259f2059317b25e4d/matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903", size = 8100634, upload-time = "2025-07-31T18:08:01.801Z" }, - { url = "https://files.pythonhosted.org/packages/52/46/a944f6f0c1f5476a0adfa501969d229ce5ae60cf9a663be0e70361381f89/matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420", size = 7978880, upload-time = "2025-07-31T18:08:03.407Z" }, - { url = "https://files.pythonhosted.org/packages/66/1e/c6f6bcd882d589410b475ca1fc22e34e34c82adff519caf18f3e6dd9d682/matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2", size = 8253056, upload-time = "2025-07-31T18:08:05.385Z" }, - { url = "https://files.pythonhosted.org/packages/53/e6/d6f7d1b59413f233793dda14419776f5f443bcccb2dfc84b09f09fe05dbe/matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389", size = 8110131, upload-time = "2025-07-31T18:08:07.293Z" }, - { url = "https://files.pythonhosted.org/packages/66/2b/bed8a45e74957549197a2ac2e1259671cd80b55ed9e1fe2b5c94d88a9202/matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea", size = 8669603, upload-time = "2025-07-31T18:08:09.064Z" }, - { url = "https://files.pythonhosted.org/packages/7e/a7/315e9435b10d057f5e52dfc603cd353167ae28bb1a4e033d41540c0067a4/matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468", size = 9508127, upload-time = "2025-07-31T18:08:10.845Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d9/edcbb1f02ca99165365d2768d517898c22c6040187e2ae2ce7294437c413/matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369", size = 9566926, upload-time = "2025-07-31T18:08:13.186Z" }, - { url = "https://files.pythonhosted.org/packages/3b/d9/6dd924ad5616c97b7308e6320cf392c466237a82a2040381163b7500510a/matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b", size = 8107599, upload-time = "2025-07-31T18:08:15.116Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f3/522dc319a50f7b0279fbe74f86f7a3506ce414bc23172098e8d2bdf21894/matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2", size = 7978173, upload-time = "2025-07-31T18:08:21.518Z" }, - { url = "https://files.pythonhosted.org/packages/8d/05/4f3c1f396075f108515e45cb8d334aff011a922350e502a7472e24c52d77/matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed", size = 8253586, upload-time = "2025-07-31T18:08:23.107Z" }, - { url = "https://files.pythonhosted.org/packages/2f/2c/e084415775aac7016c3719fe7006cdb462582c6c99ac142f27303c56e243/matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1", size = 8110715, upload-time = "2025-07-31T18:08:24.675Z" }, - { url = "https://files.pythonhosted.org/packages/52/1b/233e3094b749df16e3e6cd5a44849fd33852e692ad009cf7de00cf58ddf6/matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7", size = 8669397, upload-time = "2025-07-31T18:08:26.778Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ec/03f9e003a798f907d9f772eed9b7c6a9775d5bd00648b643ebfb88e25414/matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f", size = 9508646, upload-time = "2025-07-31T18:08:28.848Z" }, - { url = "https://files.pythonhosted.org/packages/91/e7/c051a7a386680c28487bca27d23b02d84f63e3d2a9b4d2fc478e6a42e37e/matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4", size = 9567424, upload-time = "2025-07-31T18:08:30.726Z" }, - { url = "https://files.pythonhosted.org/packages/36/c2/24302e93ff431b8f4173ee1dd88976c8d80483cadbc5d3d777cef47b3a1c/matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe", size = 8107809, upload-time = "2025-07-31T18:08:33.928Z" }, - { url = "https://files.pythonhosted.org/packages/0b/33/423ec6a668d375dad825197557ed8fbdb74d62b432c1ed8235465945475f/matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674", size = 7978078, upload-time = "2025-07-31T18:08:36.764Z" }, - { url = "https://files.pythonhosted.org/packages/51/17/521fc16ec766455c7bb52cc046550cf7652f6765ca8650ff120aa2d197b6/matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c", size = 8295590, upload-time = "2025-07-31T18:08:38.521Z" }, - { url = "https://files.pythonhosted.org/packages/f8/12/23c28b2c21114c63999bae129fce7fd34515641c517ae48ce7b7dcd33458/matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e", size = 8158518, upload-time = "2025-07-31T18:08:40.195Z" }, - { url = "https://files.pythonhosted.org/packages/81/f8/aae4eb25e8e7190759f3cb91cbeaa344128159ac92bb6b409e24f8711f78/matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b", size = 8691815, upload-time = "2025-07-31T18:08:42.238Z" }, - { url = "https://files.pythonhosted.org/packages/d0/ba/450c39ebdd486bd33a359fc17365ade46c6a96bf637bbb0df7824de2886c/matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea", size = 9522814, upload-time = "2025-07-31T18:08:44.914Z" }, - { url = "https://files.pythonhosted.org/packages/89/11/9c66f6a990e27bb9aa023f7988d2d5809cb98aa39c09cbf20fba75a542ef/matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124", size = 9573917, upload-time = "2025-07-31T18:08:47.038Z" }, - { url = "https://files.pythonhosted.org/packages/b3/69/8b49394de92569419e5e05e82e83df9b749a0ff550d07631ea96ed2eb35a/matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce", size = 8181034, upload-time = "2025-07-31T18:08:48.943Z" }, - { url = "https://files.pythonhosted.org/packages/47/23/82dc435bb98a2fc5c20dffcac8f0b083935ac28286413ed8835df40d0baa/matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154", size = 8023337, upload-time = "2025-07-31T18:08:50.791Z" }, - { url = "https://files.pythonhosted.org/packages/ac/e0/26b6cfde31f5383503ee45dcb7e691d45dadf0b3f54639332b59316a97f8/matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715", size = 8253591, upload-time = "2025-07-31T18:08:53.254Z" }, - { url = "https://files.pythonhosted.org/packages/c1/89/98488c7ef7ea20ea659af7499628c240a608b337af4be2066d644cfd0a0f/matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837", size = 8112566, upload-time = "2025-07-31T18:08:55.116Z" }, - { url = "https://files.pythonhosted.org/packages/52/67/42294dfedc82aea55e1a767daf3263aacfb5a125f44ba189e685bab41b6f/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202", size = 9513281, upload-time = "2025-07-31T18:08:56.885Z" }, - { url = "https://files.pythonhosted.org/packages/e7/68/f258239e0cf34c2cbc816781c7ab6fca768452e6bf1119aedd2bd4a882a3/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb", size = 9780873, upload-time = "2025-07-31T18:08:59.241Z" }, - { url = "https://files.pythonhosted.org/packages/89/64/f4881554006bd12e4558bd66778bdd15d47b00a1f6c6e8b50f6208eda4b3/matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975", size = 9568954, upload-time = "2025-07-31T18:09:01.244Z" }, - { url = "https://files.pythonhosted.org/packages/06/f8/42779d39c3f757e1f012f2dda3319a89fb602bd2ef98ce8faf0281f4febd/matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667", size = 8237465, upload-time = "2025-07-31T18:09:03.206Z" }, - { url = "https://files.pythonhosted.org/packages/cf/f8/153fd06b5160f0cd27c8b9dd797fcc9fb56ac6a0ebf3c1f765b6b68d3c8a/matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516", size = 8108898, upload-time = "2025-07-31T18:09:05.231Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ee/c4b082a382a225fe0d2a73f1f57cf6f6f132308805b493a54c8641006238/matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e", size = 8295636, upload-time = "2025-07-31T18:09:07.306Z" }, - { url = "https://files.pythonhosted.org/packages/30/73/2195fa2099718b21a20da82dfc753bf2af58d596b51aefe93e359dd5915a/matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a", size = 8158575, upload-time = "2025-07-31T18:09:09.083Z" }, - { url = "https://files.pythonhosted.org/packages/f6/e9/a08cdb34618a91fa08f75e6738541da5cacde7c307cea18ff10f0d03fcff/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569", size = 9522815, upload-time = "2025-07-31T18:09:11.191Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/34d8b7e0d1bb6d06ef45db01dfa560d5a67b1c40c0b998ce9ccde934bb09/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012", size = 9783514, upload-time = "2025-07-31T18:09:13.307Z" }, - { url = "https://files.pythonhosted.org/packages/12/09/d330d1e55dcca2e11b4d304cc5227f52e2512e46828d6249b88e0694176e/matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592", size = 9573932, upload-time = "2025-07-31T18:09:15.335Z" }, - { url = "https://files.pythonhosted.org/packages/eb/3b/f70258ac729aa004aca673800a53a2b0a26d49ca1df2eaa03289a1c40f81/matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959", size = 8322003, upload-time = "2025-07-31T18:09:17.416Z" }, - { url = "https://files.pythonhosted.org/packages/5b/60/3601f8ce6d76a7c81c7f25a0e15fde0d6b66226dd187aa6d2838e6374161/matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b", size = 8153849, upload-time = "2025-07-31T18:09:19.673Z" }, - { url = "https://files.pythonhosted.org/packages/dc/d6/e921be4e1a5f7aca5194e1f016cb67ec294548e530013251f630713e456d/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f", size = 8233224, upload-time = "2025-07-31T18:09:27.512Z" }, - { url = "https://files.pythonhosted.org/packages/ec/74/a2b9b04824b9c349c8f1b2d21d5af43fa7010039427f2b133a034cb09e59/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b", size = 8098539, upload-time = "2025-07-31T18:09:29.629Z" }, - { url = "https://files.pythonhosted.org/packages/fc/66/cd29ebc7f6c0d2a15d216fb572573e8fc38bd5d6dec3bd9d7d904c0949f7/matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61", size = 8672192, upload-time = "2025-07-31T18:09:31.407Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c7/1f2db90a1d43710478bb1e9b57b162852f79234d28e4f48a28cc415aa583/matplotlib-3.10.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dcfc39c452c6a9f9028d3e44d2d721484f665304857188124b505b2c95e1eecf", size = 8239216, upload_time = "2025-07-31T18:07:51.947Z" }, + { url = "https://files.pythonhosted.org/packages/82/6d/ca6844c77a4f89b1c9e4d481c412e1d1dbabf2aae2cbc5aa2da4a1d6683e/matplotlib-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:903352681b59f3efbf4546985142a9686ea1d616bb054b09a537a06e4b892ccf", size = 8102130, upload_time = "2025-07-31T18:07:53.65Z" }, + { url = "https://files.pythonhosted.org/packages/1d/1e/5e187a30cc673a3e384f3723e5f3c416033c1d8d5da414f82e4e731128ea/matplotlib-3.10.5-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:080c3676a56b8ee1c762bcf8fca3fe709daa1ee23e6ef06ad9f3fc17332f2d2a", size = 8666471, upload_time = "2025-07-31T18:07:55.304Z" }, + { url = "https://files.pythonhosted.org/packages/03/c0/95540d584d7d645324db99a845ac194e915ef75011a0d5e19e1b5cee7e69/matplotlib-3.10.5-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b4984d5064a35b6f66d2c11d668565f4389b1119cc64db7a4c1725bc11adffc", size = 9500518, upload_time = "2025-07-31T18:07:57.199Z" }, + { url = "https://files.pythonhosted.org/packages/ba/2e/e019352099ea58b4169adb9c6e1a2ad0c568c6377c2b677ee1f06de2adc7/matplotlib-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3967424121d3a46705c9fa9bdb0931de3228f13f73d7bb03c999c88343a89d89", size = 9552372, upload_time = "2025-07-31T18:07:59.41Z" }, + { url = "https://files.pythonhosted.org/packages/b7/81/3200b792a5e8b354f31f4101ad7834743ad07b6d620259f2059317b25e4d/matplotlib-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:33775bbeb75528555a15ac29396940128ef5613cf9a2d31fb1bfd18b3c0c0903", size = 8100634, upload_time = "2025-07-31T18:08:01.801Z" }, + { url = "https://files.pythonhosted.org/packages/52/46/a944f6f0c1f5476a0adfa501969d229ce5ae60cf9a663be0e70361381f89/matplotlib-3.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:c61333a8e5e6240e73769d5826b9a31d8b22df76c0778f8480baf1b4b01c9420", size = 7978880, upload_time = "2025-07-31T18:08:03.407Z" }, + { url = "https://files.pythonhosted.org/packages/66/1e/c6f6bcd882d589410b475ca1fc22e34e34c82adff519caf18f3e6dd9d682/matplotlib-3.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:00b6feadc28a08bd3c65b2894f56cf3c94fc8f7adcbc6ab4516ae1e8ed8f62e2", size = 8253056, upload_time = "2025-07-31T18:08:05.385Z" }, + { url = "https://files.pythonhosted.org/packages/53/e6/d6f7d1b59413f233793dda14419776f5f443bcccb2dfc84b09f09fe05dbe/matplotlib-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee98a5c5344dc7f48dc261b6ba5d9900c008fc12beb3fa6ebda81273602cc389", size = 8110131, upload_time = "2025-07-31T18:08:07.293Z" }, + { url = "https://files.pythonhosted.org/packages/66/2b/bed8a45e74957549197a2ac2e1259671cd80b55ed9e1fe2b5c94d88a9202/matplotlib-3.10.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a17e57e33de901d221a07af32c08870ed4528db0b6059dce7d7e65c1122d4bea", size = 8669603, upload_time = "2025-07-31T18:08:09.064Z" }, + { url = "https://files.pythonhosted.org/packages/7e/a7/315e9435b10d057f5e52dfc603cd353167ae28bb1a4e033d41540c0067a4/matplotlib-3.10.5-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97b9d6443419085950ee4a5b1ee08c363e5c43d7176e55513479e53669e88468", size = 9508127, upload_time = "2025-07-31T18:08:10.845Z" }, + { url = "https://files.pythonhosted.org/packages/7f/d9/edcbb1f02ca99165365d2768d517898c22c6040187e2ae2ce7294437c413/matplotlib-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ceefe5d40807d29a66ae916c6a3915d60ef9f028ce1927b84e727be91d884369", size = 9566926, upload_time = "2025-07-31T18:08:13.186Z" }, + { url = "https://files.pythonhosted.org/packages/3b/d9/6dd924ad5616c97b7308e6320cf392c466237a82a2040381163b7500510a/matplotlib-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:c04cba0f93d40e45b3c187c6c52c17f24535b27d545f757a2fffebc06c12b98b", size = 8107599, upload_time = "2025-07-31T18:08:15.116Z" }, + { url = "https://files.pythonhosted.org/packages/0e/f3/522dc319a50f7b0279fbe74f86f7a3506ce414bc23172098e8d2bdf21894/matplotlib-3.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:a41bcb6e2c8e79dc99c5511ae6f7787d2fb52efd3d805fff06d5d4f667db16b2", size = 7978173, upload_time = "2025-07-31T18:08:21.518Z" }, + { url = "https://files.pythonhosted.org/packages/8d/05/4f3c1f396075f108515e45cb8d334aff011a922350e502a7472e24c52d77/matplotlib-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:354204db3f7d5caaa10e5de74549ef6a05a4550fdd1c8f831ab9bca81efd39ed", size = 8253586, upload_time = "2025-07-31T18:08:23.107Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2c/e084415775aac7016c3719fe7006cdb462582c6c99ac142f27303c56e243/matplotlib-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b072aac0c3ad563a2b3318124756cb6112157017f7431626600ecbe890df57a1", size = 8110715, upload_time = "2025-07-31T18:08:24.675Z" }, + { url = "https://files.pythonhosted.org/packages/52/1b/233e3094b749df16e3e6cd5a44849fd33852e692ad009cf7de00cf58ddf6/matplotlib-3.10.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d52fd5b684d541b5a51fb276b2b97b010c75bee9aa392f96b4a07aeb491e33c7", size = 8669397, upload_time = "2025-07-31T18:08:26.778Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ec/03f9e003a798f907d9f772eed9b7c6a9775d5bd00648b643ebfb88e25414/matplotlib-3.10.5-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee7a09ae2f4676276f5a65bd9f2bd91b4f9fbaedf49f40267ce3f9b448de501f", size = 9508646, upload_time = "2025-07-31T18:08:28.848Z" }, + { url = "https://files.pythonhosted.org/packages/91/e7/c051a7a386680c28487bca27d23b02d84f63e3d2a9b4d2fc478e6a42e37e/matplotlib-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ba6c3c9c067b83481d647af88b4e441d532acdb5ef22178a14935b0b881188f4", size = 9567424, upload_time = "2025-07-31T18:08:30.726Z" }, + { url = "https://files.pythonhosted.org/packages/36/c2/24302e93ff431b8f4173ee1dd88976c8d80483cadbc5d3d777cef47b3a1c/matplotlib-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:07442d2692c9bd1cceaa4afb4bbe5b57b98a7599de4dabfcca92d3eea70f9ebe", size = 8107809, upload_time = "2025-07-31T18:08:33.928Z" }, + { url = "https://files.pythonhosted.org/packages/0b/33/423ec6a668d375dad825197557ed8fbdb74d62b432c1ed8235465945475f/matplotlib-3.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:48fe6d47380b68a37ccfcc94f009530e84d41f71f5dae7eda7c4a5a84aa0a674", size = 7978078, upload_time = "2025-07-31T18:08:36.764Z" }, + { url = "https://files.pythonhosted.org/packages/51/17/521fc16ec766455c7bb52cc046550cf7652f6765ca8650ff120aa2d197b6/matplotlib-3.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b80eb8621331449fc519541a7461987f10afa4f9cfd91afcd2276ebe19bd56c", size = 8295590, upload_time = "2025-07-31T18:08:38.521Z" }, + { url = "https://files.pythonhosted.org/packages/f8/12/23c28b2c21114c63999bae129fce7fd34515641c517ae48ce7b7dcd33458/matplotlib-3.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47a388908e469d6ca2a6015858fa924e0e8a2345a37125948d8e93a91c47933e", size = 8158518, upload_time = "2025-07-31T18:08:40.195Z" }, + { url = "https://files.pythonhosted.org/packages/81/f8/aae4eb25e8e7190759f3cb91cbeaa344128159ac92bb6b409e24f8711f78/matplotlib-3.10.5-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b6b49167d208358983ce26e43aa4196073b4702858670f2eb111f9a10652b4b", size = 8691815, upload_time = "2025-07-31T18:08:42.238Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ba/450c39ebdd486bd33a359fc17365ade46c6a96bf637bbb0df7824de2886c/matplotlib-3.10.5-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a8da0453a7fd8e3da114234ba70c5ba9ef0e98f190309ddfde0f089accd46ea", size = 9522814, upload_time = "2025-07-31T18:08:44.914Z" }, + { url = "https://files.pythonhosted.org/packages/89/11/9c66f6a990e27bb9aa023f7988d2d5809cb98aa39c09cbf20fba75a542ef/matplotlib-3.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:52c6573dfcb7726a9907b482cd5b92e6b5499b284ffacb04ffbfe06b3e568124", size = 9573917, upload_time = "2025-07-31T18:08:47.038Z" }, + { url = "https://files.pythonhosted.org/packages/b3/69/8b49394de92569419e5e05e82e83df9b749a0ff550d07631ea96ed2eb35a/matplotlib-3.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:a23193db2e9d64ece69cac0c8231849db7dd77ce59c7b89948cf9d0ce655a3ce", size = 8181034, upload_time = "2025-07-31T18:08:48.943Z" }, + { url = "https://files.pythonhosted.org/packages/47/23/82dc435bb98a2fc5c20dffcac8f0b083935ac28286413ed8835df40d0baa/matplotlib-3.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:56da3b102cf6da2776fef3e71cd96fcf22103a13594a18ac9a9b31314e0be154", size = 8023337, upload_time = "2025-07-31T18:08:50.791Z" }, + { url = "https://files.pythonhosted.org/packages/ac/e0/26b6cfde31f5383503ee45dcb7e691d45dadf0b3f54639332b59316a97f8/matplotlib-3.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:96ef8f5a3696f20f55597ffa91c28e2e73088df25c555f8d4754931515512715", size = 8253591, upload_time = "2025-07-31T18:08:53.254Z" }, + { url = "https://files.pythonhosted.org/packages/c1/89/98488c7ef7ea20ea659af7499628c240a608b337af4be2066d644cfd0a0f/matplotlib-3.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:77fab633e94b9da60512d4fa0213daeb76d5a7b05156840c4fd0399b4b818837", size = 8112566, upload_time = "2025-07-31T18:08:55.116Z" }, + { url = "https://files.pythonhosted.org/packages/52/67/42294dfedc82aea55e1a767daf3263aacfb5a125f44ba189e685bab41b6f/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27f52634315e96b1debbfdc5c416592edcd9c4221bc2f520fd39c33db5d9f202", size = 9513281, upload_time = "2025-07-31T18:08:56.885Z" }, + { url = "https://files.pythonhosted.org/packages/e7/68/f258239e0cf34c2cbc816781c7ab6fca768452e6bf1119aedd2bd4a882a3/matplotlib-3.10.5-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:525f6e28c485c769d1f07935b660c864de41c37fd716bfa64158ea646f7084bb", size = 9780873, upload_time = "2025-07-31T18:08:59.241Z" }, + { url = "https://files.pythonhosted.org/packages/89/64/f4881554006bd12e4558bd66778bdd15d47b00a1f6c6e8b50f6208eda4b3/matplotlib-3.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1f5f3ec4c191253c5f2b7c07096a142c6a1c024d9f738247bfc8e3f9643fc975", size = 9568954, upload_time = "2025-07-31T18:09:01.244Z" }, + { url = "https://files.pythonhosted.org/packages/06/f8/42779d39c3f757e1f012f2dda3319a89fb602bd2ef98ce8faf0281f4febd/matplotlib-3.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:707f9c292c4cd4716f19ab8a1f93f26598222cd931e0cd98fbbb1c5994bf7667", size = 8237465, upload_time = "2025-07-31T18:09:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/cf/f8/153fd06b5160f0cd27c8b9dd797fcc9fb56ac6a0ebf3c1f765b6b68d3c8a/matplotlib-3.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:21a95b9bf408178d372814de7baacd61c712a62cae560b5e6f35d791776f6516", size = 8108898, upload_time = "2025-07-31T18:09:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/c4b082a382a225fe0d2a73f1f57cf6f6f132308805b493a54c8641006238/matplotlib-3.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a6b310f95e1102a8c7c817ef17b60ee5d1851b8c71b63d9286b66b177963039e", size = 8295636, upload_time = "2025-07-31T18:09:07.306Z" }, + { url = "https://files.pythonhosted.org/packages/30/73/2195fa2099718b21a20da82dfc753bf2af58d596b51aefe93e359dd5915a/matplotlib-3.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:94986a242747a0605cb3ff1cb98691c736f28a59f8ffe5175acaeb7397c49a5a", size = 8158575, upload_time = "2025-07-31T18:09:09.083Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e9/a08cdb34618a91fa08f75e6738541da5cacde7c307cea18ff10f0d03fcff/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ff10ea43288f0c8bab608a305dc6c918cc729d429c31dcbbecde3b9f4d5b569", size = 9522815, upload_time = "2025-07-31T18:09:11.191Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/34d8b7e0d1bb6d06ef45db01dfa560d5a67b1c40c0b998ce9ccde934bb09/matplotlib-3.10.5-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f6adb644c9d040ffb0d3434e440490a66cf73dbfa118a6f79cd7568431f7a012", size = 9783514, upload_time = "2025-07-31T18:09:13.307Z" }, + { url = "https://files.pythonhosted.org/packages/12/09/d330d1e55dcca2e11b4d304cc5227f52e2512e46828d6249b88e0694176e/matplotlib-3.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:4fa40a8f98428f789a9dcacd625f59b7bc4e3ef6c8c7c80187a7a709475cf592", size = 9573932, upload_time = "2025-07-31T18:09:15.335Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3b/f70258ac729aa004aca673800a53a2b0a26d49ca1df2eaa03289a1c40f81/matplotlib-3.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:95672a5d628b44207aab91ec20bf59c26da99de12b88f7e0b1fb0a84a86ff959", size = 8322003, upload_time = "2025-07-31T18:09:17.416Z" }, + { url = "https://files.pythonhosted.org/packages/5b/60/3601f8ce6d76a7c81c7f25a0e15fde0d6b66226dd187aa6d2838e6374161/matplotlib-3.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:2efaf97d72629e74252e0b5e3c46813e9eeaa94e011ecf8084a971a31a97f40b", size = 8153849, upload_time = "2025-07-31T18:09:19.673Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d6/e921be4e1a5f7aca5194e1f016cb67ec294548e530013251f630713e456d/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:160e125da27a749481eaddc0627962990f6029811dbeae23881833a011a0907f", size = 8233224, upload_time = "2025-07-31T18:09:27.512Z" }, + { url = "https://files.pythonhosted.org/packages/ec/74/a2b9b04824b9c349c8f1b2d21d5af43fa7010039427f2b133a034cb09e59/matplotlib-3.10.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac3d50760394d78a3c9be6b28318fe22b494c4fcf6407e8fd4794b538251899b", size = 8098539, upload_time = "2025-07-31T18:09:29.629Z" }, + { url = "https://files.pythonhosted.org/packages/fc/66/cd29ebc7f6c0d2a15d216fb572573e8fc38bd5d6dec3bd9d7d904c0949f7/matplotlib-3.10.5-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6c49465bf689c4d59d174d0c7795fb42a21d4244d11d70e52b8011987367ac61", size = 8672192, upload_time = "2025-07-31T18:09:31.407Z" }, ] [[package]] @@ -1146,9 +1169,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload-time = "2024-04-15T13:44:44.803Z" } +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159, upload_time = "2024-04-15T13:44:44.803Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload-time = "2024-04-15T13:44:43.265Z" }, + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899, upload_time = "2024-04-15T13:44:43.265Z" }, ] [[package]] @@ -1159,18 +1182,18 @@ dependencies = [ { name = "numpy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/b8/93/2d2246e0c3cb4dce1528f088ef5bf1fe4d6cb3ef109a8af805ac09bcf44b/MetaTrader5-5.0.5200-cp311-cp311-win_amd64.whl", hash = "sha256:5e5b037b4466425b1533b94ae085f23df77c88e0cfe927cf5d0b46b91fe2288c", size = 50321, upload-time = "2025-08-01T16:09:30.652Z" }, - { url = "https://files.pythonhosted.org/packages/d1/85/d1f05394310f6005fe502b316775d5285f1ea6a1e41c21b24ebf976fe475/MetaTrader5-5.0.5200-cp312-cp312-win_amd64.whl", hash = "sha256:9bfb2063abd985e05424eb3c5e8ae978ee3de7557804982e2797319a57be0d66", size = 50465, upload-time = "2025-08-01T16:09:31.517Z" }, - { url = "https://files.pythonhosted.org/packages/41/84/3487b188f52b784a0d6a8778307c9a71a288d31e53408374e7aae67038d6/MetaTrader5-5.0.5200-cp313-cp313-win_amd64.whl", hash = "sha256:2f652415a3f6620d1b29ba0cb593d4d91c4559ded8cfe86bde282f10f0b2dedc", size = 50459, upload-time = "2025-08-01T16:09:32.926Z" }, + { url = "https://files.pythonhosted.org/packages/b8/93/2d2246e0c3cb4dce1528f088ef5bf1fe4d6cb3ef109a8af805ac09bcf44b/MetaTrader5-5.0.5200-cp311-cp311-win_amd64.whl", hash = "sha256:5e5b037b4466425b1533b94ae085f23df77c88e0cfe927cf5d0b46b91fe2288c", size = 50321, upload_time = "2025-08-01T16:09:30.652Z" }, + { url = "https://files.pythonhosted.org/packages/d1/85/d1f05394310f6005fe502b316775d5285f1ea6a1e41c21b24ebf976fe475/MetaTrader5-5.0.5200-cp312-cp312-win_amd64.whl", hash = "sha256:9bfb2063abd985e05424eb3c5e8ae978ee3de7557804982e2797319a57be0d66", size = 50465, upload_time = "2025-08-01T16:09:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/41/84/3487b188f52b784a0d6a8778307c9a71a288d31e53408374e7aae67038d6/MetaTrader5-5.0.5200-cp313-cp313-win_amd64.whl", hash = "sha256:2f652415a3f6620d1b29ba0cb593d4d91c4559ded8cfe86bde282f10f0b2dedc", size = 50459, upload_time = "2025-08-01T16:09:32.926Z" }, ] [[package]] name = "mistune" version = "3.1.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/79/bda47f7dd7c3c55770478d6d02c9960c430b0cf1773b72366ff89126ea31/mistune-3.1.3.tar.gz", hash = "sha256:a7035c21782b2becb6be62f8f25d3df81ccb4d6fa477a6525b15af06539f02a0", size = 94347, upload-time = "2025-03-19T14:27:24.955Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/79/bda47f7dd7c3c55770478d6d02c9960c430b0cf1773b72366ff89126ea31/mistune-3.1.3.tar.gz", hash = "sha256:a7035c21782b2becb6be62f8f25d3df81ccb4d6fa477a6525b15af06539f02a0", size = 94347, upload_time = "2025-03-19T14:27:24.955Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl", hash = "sha256:1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9", size = 53410, upload-time = "2025-03-19T14:27:23.451Z" }, + { url = "https://files.pythonhosted.org/packages/01/4d/23c4e4f09da849e127e9f123241946c23c1e30f45a88366879e064211815/mistune-3.1.3-py3-none-any.whl", hash = "sha256:1a32314113cff28aa6432e99e522677c8587fd83e3d51c29b82a52409c842bd9", size = 53410, upload_time = "2025-03-19T14:27:23.451Z" }, ] [[package]] @@ -1181,9 +1204,9 @@ dependencies = [ { name = "matplotlib" }, { name = "pandas" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6c/a9/34e7998d02fb58fae04f750444ce4e95e75f3a08dad17fb2d32098a97834/mplfinance-0.12.10b0.tar.gz", hash = "sha256:7da150b5851aa5119ad6e06b55e48338b619bb6773f1b85df5de67a5ffd917bf", size = 70117, upload-time = "2023-08-02T15:13:53.829Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/a9/34e7998d02fb58fae04f750444ce4e95e75f3a08dad17fb2d32098a97834/mplfinance-0.12.10b0.tar.gz", hash = "sha256:7da150b5851aa5119ad6e06b55e48338b619bb6773f1b85df5de67a5ffd917bf", size = 70117, upload_time = "2023-08-02T15:13:53.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/d9/31c436ea7673c21a5bf3fc747bc7f63377582dfe845c3004d3e46f9deee0/mplfinance-0.12.10b0-py3-none-any.whl", hash = "sha256:76d3b095f05ff35de730751649de063bea4064d0c49b21b6182c82997a7f52bb", size = 75016, upload-time = "2023-08-02T15:13:52.022Z" }, + { url = "https://files.pythonhosted.org/packages/d7/d9/31c436ea7673c21a5bf3fc747bc7f63377582dfe845c3004d3e46f9deee0/mplfinance-0.12.10b0-py3-none-any.whl", hash = "sha256:76d3b095f05ff35de730751649de063bea4064d0c49b21b6182c82997a7f52bb", size = 75016, upload_time = "2023-08-02T15:13:52.022Z" }, ] [[package]] @@ -1196,9 +1219,9 @@ dependencies = [ { name = "nbformat" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424, upload-time = "2024-12-19T10:32:27.164Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424, upload_time = "2024-12-19T10:32:27.164Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434, upload-time = "2024-12-19T10:32:24.139Z" }, + { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434, upload_time = "2024-12-19T10:32:24.139Z" }, ] [[package]] @@ -1221,9 +1244,9 @@ dependencies = [ { name = "pygments" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a3/59/f28e15fc47ffb73af68a8d9b47367a8630d76e97ae85ad18271b9db96fdf/nbconvert-7.16.6.tar.gz", hash = "sha256:576a7e37c6480da7b8465eefa66c17844243816ce1ccc372633c6b71c3c0f582", size = 857715, upload-time = "2025-01-28T09:29:14.724Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/59/f28e15fc47ffb73af68a8d9b47367a8630d76e97ae85ad18271b9db96fdf/nbconvert-7.16.6.tar.gz", hash = "sha256:576a7e37c6480da7b8465eefa66c17844243816ce1ccc372633c6b71c3c0f582", size = 857715, upload_time = "2025-01-28T09:29:14.724Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl", hash = "sha256:1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b", size = 258525, upload-time = "2025-01-28T09:29:12.551Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9a/cd673b2f773a12c992f41309ef81b99da1690426bd2f96957a7ade0d3ed7/nbconvert-7.16.6-py3-none-any.whl", hash = "sha256:1375a7b67e0c2883678c48e506dc320febb57685e5ee67faa51b18a90f3a712b", size = 258525, upload_time = "2025-01-28T09:29:12.551Z" }, ] [[package]] @@ -1236,18 +1259,18 @@ dependencies = [ { name = "jupyter-core" }, { name = "traitlets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload_time = "2024-04-04T11:20:37.371Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload_time = "2024-04-04T11:20:34.895Z" }, ] [[package]] name = "nest-asyncio" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload-time = "2024-01-21T14:25:19.227Z" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418, upload_time = "2024-01-21T14:25:19.227Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload-time = "2024-01-21T14:25:17.223Z" }, + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195, upload_time = "2024-01-21T14:25:17.223Z" }, ] [[package]] @@ -1261,9 +1284,9 @@ dependencies = [ { name = "notebook-shim" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/21/9669982f9569e7478763837e0d35b9fd9f43de0eb5ab5d6ca620b8019cfc/notebook-7.4.5.tar.gz", hash = "sha256:7c2c4ea245913c3ad8ab3e5d36b34a842c06e524556f5c2e1f5d7d08c986615e", size = 13888993, upload-time = "2025-08-05T07:40:56.529Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9f/21/9669982f9569e7478763837e0d35b9fd9f43de0eb5ab5d6ca620b8019cfc/notebook-7.4.5.tar.gz", hash = "sha256:7c2c4ea245913c3ad8ab3e5d36b34a842c06e524556f5c2e1f5d7d08c986615e", size = 13888993, upload_time = "2025-08-05T07:40:56.529Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/c7/207fd1138bd82435d13b6d8640a240be4d855b8ddb41f6bf31aca5be64df/notebook-7.4.5-py3-none-any.whl", hash = "sha256:351635461aca9dad08cf8946a4216f963e2760cc1bf7b1aaaecb23afc33ec046", size = 14295193, upload-time = "2025-08-05T07:40:52.586Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c7/207fd1138bd82435d13b6d8640a240be4d855b8ddb41f6bf31aca5be64df/notebook-7.4.5-py3-none-any.whl", hash = "sha256:351635461aca9dad08cf8946a4216f963e2760cc1bf7b1aaaecb23afc33ec046", size = 14295193, upload_time = "2025-08-05T07:40:52.586Z" }, ] [[package]] @@ -1273,108 +1296,102 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jupyter-server" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload-time = "2024-02-14T23:35:18.353Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload_time = "2024-02-14T23:35:18.353Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload-time = "2024-02-14T23:35:16.286Z" }, + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload_time = "2024-02-14T23:35:16.286Z" }, +] + +[[package]] +name = "numba" +version = "0.61.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite" }, + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/a0/e21f57604304aa03ebb8e098429222722ad99176a4f979d34af1d1ee80da/numba-0.61.2.tar.gz", hash = "sha256:8750ee147940a6637b80ecf7f95062185ad8726c8c28a2295b8ec1160a196f7d", size = 2820615, upload_time = "2025-04-09T02:58:07.659Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/97/c99d1056aed767503c228f7099dc11c402906b42a4757fec2819329abb98/numba-0.61.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:efd3db391df53aaa5cfbee189b6c910a5b471488749fd6606c3f33fc984c2ae2", size = 2775825, upload_time = "2025-04-09T02:57:43.442Z" }, + { url = "https://files.pythonhosted.org/packages/95/9e/63c549f37136e892f006260c3e2613d09d5120672378191f2dc387ba65a2/numba-0.61.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:49c980e4171948ffebf6b9a2520ea81feed113c1f4890747ba7f59e74be84b1b", size = 2778695, upload_time = "2025-04-09T02:57:44.968Z" }, + { url = "https://files.pythonhosted.org/packages/97/c8/8740616c8436c86c1b9a62e72cb891177d2c34c2d24ddcde4c390371bf4c/numba-0.61.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3945615cd73c2c7eba2a85ccc9c1730c21cd3958bfcf5a44302abae0fb07bb60", size = 3829227, upload_time = "2025-04-09T02:57:46.63Z" }, + { url = "https://files.pythonhosted.org/packages/fc/06/66e99ae06507c31d15ff3ecd1f108f2f59e18b6e08662cd5f8a5853fbd18/numba-0.61.2-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:bbfdf4eca202cebade0b7d43896978e146f39398909a42941c9303f82f403a18", size = 3523422, upload_time = "2025-04-09T02:57:48.222Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a4/2b309a6a9f6d4d8cfba583401c7c2f9ff887adb5d54d8e2e130274c0973f/numba-0.61.2-cp311-cp311-win_amd64.whl", hash = "sha256:76bcec9f46259cedf888041b9886e257ae101c6268261b19fda8cfbc52bec9d1", size = 2831505, upload_time = "2025-04-09T02:57:50.108Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a0/c6b7b9c615cfa3b98c4c63f4316e3f6b3bbe2387740277006551784218cd/numba-0.61.2-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:34fba9406078bac7ab052efbf0d13939426c753ad72946baaa5bf9ae0ebb8dd2", size = 2776626, upload_time = "2025-04-09T02:57:51.857Z" }, + { url = "https://files.pythonhosted.org/packages/92/4a/fe4e3c2ecad72d88f5f8cd04e7f7cff49e718398a2fac02d2947480a00ca/numba-0.61.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ddce10009bc097b080fc96876d14c051cc0c7679e99de3e0af59014dab7dfe8", size = 2779287, upload_time = "2025-04-09T02:57:53.658Z" }, + { url = "https://files.pythonhosted.org/packages/9a/2d/e518df036feab381c23a624dac47f8445ac55686ec7f11083655eb707da3/numba-0.61.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b1bb509d01f23d70325d3a5a0e237cbc9544dd50e50588bc581ba860c213546", size = 3885928, upload_time = "2025-04-09T02:57:55.206Z" }, + { url = "https://files.pythonhosted.org/packages/10/0f/23cced68ead67b75d77cfcca3df4991d1855c897ee0ff3fe25a56ed82108/numba-0.61.2-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48a53a3de8f8793526cbe330f2a39fe9a6638efcbf11bd63f3d2f9757ae345cd", size = 3577115, upload_time = "2025-04-09T02:57:56.818Z" }, + { url = "https://files.pythonhosted.org/packages/68/1d/ddb3e704c5a8fb90142bf9dc195c27db02a08a99f037395503bfbc1d14b3/numba-0.61.2-cp312-cp312-win_amd64.whl", hash = "sha256:97cf4f12c728cf77c9c1d7c23707e4d8fb4632b46275f8f3397de33e5877af18", size = 2831929, upload_time = "2025-04-09T02:57:58.45Z" }, + { url = "https://files.pythonhosted.org/packages/0b/f3/0fe4c1b1f2569e8a18ad90c159298d862f96c3964392a20d74fc628aee44/numba-0.61.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:3a10a8fc9afac40b1eac55717cece1b8b1ac0b946f5065c89e00bde646b5b154", size = 2771785, upload_time = "2025-04-09T02:57:59.96Z" }, + { url = "https://files.pythonhosted.org/packages/e9/71/91b277d712e46bd5059f8a5866862ed1116091a7cb03bd2704ba8ebe015f/numba-0.61.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7d3bcada3c9afba3bed413fba45845f2fb9cd0d2b27dd58a1be90257e293d140", size = 2773289, upload_time = "2025-04-09T02:58:01.435Z" }, + { url = "https://files.pythonhosted.org/packages/0d/e0/5ea04e7ad2c39288c0f0f9e8d47638ad70f28e275d092733b5817cf243c9/numba-0.61.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bdbca73ad81fa196bd53dc12e3aaf1564ae036e0c125f237c7644fe64a4928ab", size = 3893918, upload_time = "2025-04-09T02:58:02.933Z" }, + { url = "https://files.pythonhosted.org/packages/17/58/064f4dcb7d7e9412f16ecf80ed753f92297e39f399c905389688cf950b81/numba-0.61.2-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:5f154aaea625fb32cfbe3b80c5456d514d416fcdf79733dd69c0df3a11348e9e", size = 3584056, upload_time = "2025-04-09T02:58:04.538Z" }, + { url = "https://files.pythonhosted.org/packages/af/a4/6d3a0f2d3989e62a18749e1e9913d5fa4910bbb3e3311a035baea6caf26d/numba-0.61.2-cp313-cp313-win_amd64.whl", hash = "sha256:59321215e2e0ac5fa928a8020ab00b8e57cda8a97384963ac0dfa4d4e6aa54e7", size = 2831846, upload_time = "2025-04-09T02:58:06.125Z" }, ] [[package]] name = "numpy" -version = "2.3.2" +version = "2.2.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/3fec4199c5ffb892bed55cff901e4f39a58c81df9c44c280499e92cad264/numpy-2.3.2.tar.gz", hash = "sha256:e0486a11ec30cdecb53f184d496d1c6a20786c81e55e41640270130056f8ee48", size = 20489306, upload-time = "2025-07-24T21:32:07.553Z" } +sdist = { url = "https://files.pythonhosted.org/packages/76/21/7d2a95e4bba9dc13d043ee156a356c0a8f0c6309dff6b21b4d71a073b8a8/numpy-2.2.6.tar.gz", hash = "sha256:e29554e2bef54a90aa5cc07da6ce955accb83f21ab5de01a62c8478897b264fd", size = 20276440, upload_time = "2025-05-17T22:38:04.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/26/1320083986108998bd487e2931eed2aeedf914b6e8905431487543ec911d/numpy-2.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:852ae5bed3478b92f093e30f785c98e0cb62fa0a939ed057c31716e18a7a22b9", size = 21259016, upload-time = "2025-07-24T20:24:35.214Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2b/792b341463fa93fc7e55abbdbe87dac316c5b8cb5e94fb7a59fb6fa0cda5/numpy-2.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a0e27186e781a69959d0230dd9909b5e26024f8da10683bd6344baea1885168", size = 14451158, upload-time = "2025-07-24T20:24:58.397Z" }, - { url = "https://files.pythonhosted.org/packages/b7/13/e792d7209261afb0c9f4759ffef6135b35c77c6349a151f488f531d13595/numpy-2.3.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:f0a1a8476ad77a228e41619af2fa9505cf69df928e9aaa165746584ea17fed2b", size = 5379817, upload-time = "2025-07-24T20:25:07.746Z" }, - { url = "https://files.pythonhosted.org/packages/49/ce/055274fcba4107c022b2113a213c7287346563f48d62e8d2a5176ad93217/numpy-2.3.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cbc95b3813920145032412f7e33d12080f11dc776262df1712e1638207dde9e8", size = 6913606, upload-time = "2025-07-24T20:25:18.84Z" }, - { url = "https://files.pythonhosted.org/packages/17/f2/e4d72e6bc5ff01e2ab613dc198d560714971900c03674b41947e38606502/numpy-2.3.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f75018be4980a7324edc5930fe39aa391d5734531b1926968605416ff58c332d", size = 14589652, upload-time = "2025-07-24T20:25:40.356Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b0/fbeee3000a51ebf7222016e2939b5c5ecf8000a19555d04a18f1e02521b8/numpy-2.3.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20b8200721840f5621b7bd03f8dcd78de33ec522fc40dc2641aa09537df010c3", size = 16938816, upload-time = "2025-07-24T20:26:05.721Z" }, - { url = "https://files.pythonhosted.org/packages/a9/ec/2f6c45c3484cc159621ea8fc000ac5a86f1575f090cac78ac27193ce82cd/numpy-2.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f91e5c028504660d606340a084db4b216567ded1056ea2b4be4f9d10b67197f", size = 16370512, upload-time = "2025-07-24T20:26:30.545Z" }, - { url = "https://files.pythonhosted.org/packages/b5/01/dd67cf511850bd7aefd6347aaae0956ed415abea741ae107834aae7d6d4e/numpy-2.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:fb1752a3bb9a3ad2d6b090b88a9a0ae1cd6f004ef95f75825e2f382c183b2097", size = 18884947, upload-time = "2025-07-24T20:26:58.24Z" }, - { url = "https://files.pythonhosted.org/packages/a7/17/2cf60fd3e6a61d006778735edf67a222787a8c1a7842aed43ef96d777446/numpy-2.3.2-cp311-cp311-win32.whl", hash = "sha256:4ae6863868aaee2f57503c7a5052b3a2807cf7a3914475e637a0ecd366ced220", size = 6599494, upload-time = "2025-07-24T20:27:09.786Z" }, - { url = "https://files.pythonhosted.org/packages/d5/03/0eade211c504bda872a594f045f98ddcc6caef2b7c63610946845e304d3f/numpy-2.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:240259d6564f1c65424bcd10f435145a7644a65a6811cfc3201c4a429ba79170", size = 13087889, upload-time = "2025-07-24T20:27:29.558Z" }, - { url = "https://files.pythonhosted.org/packages/13/32/2c7979d39dafb2a25087e12310fc7f3b9d3c7d960df4f4bc97955ae0ce1d/numpy-2.3.2-cp311-cp311-win_arm64.whl", hash = "sha256:4209f874d45f921bde2cff1ffcd8a3695f545ad2ffbef6d3d3c6768162efab89", size = 10459560, upload-time = "2025-07-24T20:27:46.803Z" }, - { url = "https://files.pythonhosted.org/packages/00/6d/745dd1c1c5c284d17725e5c802ca4d45cfc6803519d777f087b71c9f4069/numpy-2.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bc3186bea41fae9d8e90c2b4fb5f0a1f5a690682da79b92574d63f56b529080b", size = 20956420, upload-time = "2025-07-24T20:28:18.002Z" }, - { url = "https://files.pythonhosted.org/packages/bc/96/e7b533ea5740641dd62b07a790af5d9d8fec36000b8e2d0472bd7574105f/numpy-2.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f4f0215edb189048a3c03bd5b19345bdfa7b45a7a6f72ae5945d2a28272727f", size = 14184660, upload-time = "2025-07-24T20:28:39.522Z" }, - { url = "https://files.pythonhosted.org/packages/2b/53/102c6122db45a62aa20d1b18c9986f67e6b97e0d6fbc1ae13e3e4c84430c/numpy-2.3.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:8b1224a734cd509f70816455c3cffe13a4f599b1bf7130f913ba0e2c0b2006c0", size = 5113382, upload-time = "2025-07-24T20:28:48.544Z" }, - { url = "https://files.pythonhosted.org/packages/2b/21/376257efcbf63e624250717e82b4fae93d60178f09eb03ed766dbb48ec9c/numpy-2.3.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:3dcf02866b977a38ba3ec10215220609ab9667378a9e2150615673f3ffd6c73b", size = 6647258, upload-time = "2025-07-24T20:28:59.104Z" }, - { url = "https://files.pythonhosted.org/packages/91/ba/f4ebf257f08affa464fe6036e13f2bf9d4642a40228781dc1235da81be9f/numpy-2.3.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:572d5512df5470f50ada8d1972c5f1082d9a0b7aa5944db8084077570cf98370", size = 14281409, upload-time = "2025-07-24T20:40:30.298Z" }, - { url = "https://files.pythonhosted.org/packages/59/ef/f96536f1df42c668cbacb727a8c6da7afc9c05ece6d558927fb1722693e1/numpy-2.3.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8145dd6d10df13c559d1e4314df29695613575183fa2e2d11fac4c208c8a1f73", size = 16641317, upload-time = "2025-07-24T20:40:56.625Z" }, - { url = "https://files.pythonhosted.org/packages/f6/a7/af813a7b4f9a42f498dde8a4c6fcbff8100eed00182cc91dbaf095645f38/numpy-2.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:103ea7063fa624af04a791c39f97070bf93b96d7af7eb23530cd087dc8dbe9dc", size = 16056262, upload-time = "2025-07-24T20:41:20.797Z" }, - { url = "https://files.pythonhosted.org/packages/8b/5d/41c4ef8404caaa7f05ed1cfb06afe16a25895260eacbd29b4d84dff2920b/numpy-2.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fc927d7f289d14f5e037be917539620603294454130b6de200091e23d27dc9be", size = 18579342, upload-time = "2025-07-24T20:41:50.753Z" }, - { url = "https://files.pythonhosted.org/packages/a1/4f/9950e44c5a11636f4a3af6e825ec23003475cc9a466edb7a759ed3ea63bd/numpy-2.3.2-cp312-cp312-win32.whl", hash = "sha256:d95f59afe7f808c103be692175008bab926b59309ade3e6d25009e9a171f7036", size = 6320610, upload-time = "2025-07-24T20:42:01.551Z" }, - { url = "https://files.pythonhosted.org/packages/7c/2f/244643a5ce54a94f0a9a2ab578189c061e4a87c002e037b0829dd77293b6/numpy-2.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:9e196ade2400c0c737d93465327d1ae7c06c7cb8a1756121ebf54b06ca183c7f", size = 12786292, upload-time = "2025-07-24T20:42:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/54/cd/7b5f49d5d78db7badab22d8323c1b6ae458fbf86c4fdfa194ab3cd4eb39b/numpy-2.3.2-cp312-cp312-win_arm64.whl", hash = "sha256:ee807923782faaf60d0d7331f5e86da7d5e3079e28b291973c545476c2b00d07", size = 10194071, upload-time = "2025-07-24T20:42:36.657Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c0/c6bb172c916b00700ed3bf71cb56175fd1f7dbecebf8353545d0b5519f6c/numpy-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c8d9727f5316a256425892b043736d63e89ed15bbfe6556c5ff4d9d4448ff3b3", size = 20949074, upload-time = "2025-07-24T20:43:07.813Z" }, - { url = "https://files.pythonhosted.org/packages/20/4e/c116466d22acaf4573e58421c956c6076dc526e24a6be0903219775d862e/numpy-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:efc81393f25f14d11c9d161e46e6ee348637c0a1e8a54bf9dedc472a3fae993b", size = 14177311, upload-time = "2025-07-24T20:43:29.335Z" }, - { url = "https://files.pythonhosted.org/packages/78/45/d4698c182895af189c463fc91d70805d455a227261d950e4e0f1310c2550/numpy-2.3.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dd937f088a2df683cbb79dda9a772b62a3e5a8a7e76690612c2737f38c6ef1b6", size = 5106022, upload-time = "2025-07-24T20:43:37.999Z" }, - { url = "https://files.pythonhosted.org/packages/9f/76/3e6880fef4420179309dba72a8c11f6166c431cf6dee54c577af8906f914/numpy-2.3.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:11e58218c0c46c80509186e460d79fbdc9ca1eb8d8aee39d8f2dc768eb781089", size = 6640135, upload-time = "2025-07-24T20:43:49.28Z" }, - { url = "https://files.pythonhosted.org/packages/34/fa/87ff7f25b3c4ce9085a62554460b7db686fef1e0207e8977795c7b7d7ba1/numpy-2.3.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ad4ebcb683a1f99f4f392cc522ee20a18b2bb12a2c1c42c3d48d5a1adc9d3d2", size = 14278147, upload-time = "2025-07-24T20:44:10.328Z" }, - { url = "https://files.pythonhosted.org/packages/1d/0f/571b2c7a3833ae419fe69ff7b479a78d313581785203cc70a8db90121b9a/numpy-2.3.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:938065908d1d869c7d75d8ec45f735a034771c6ea07088867f713d1cd3bbbe4f", size = 16635989, upload-time = "2025-07-24T20:44:34.88Z" }, - { url = "https://files.pythonhosted.org/packages/24/5a/84ae8dca9c9a4c592fe11340b36a86ffa9fd3e40513198daf8a97839345c/numpy-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:66459dccc65d8ec98cc7df61307b64bf9e08101f9598755d42d8ae65d9a7a6ee", size = 16053052, upload-time = "2025-07-24T20:44:58.872Z" }, - { url = "https://files.pythonhosted.org/packages/57/7c/e5725d99a9133b9813fcf148d3f858df98511686e853169dbaf63aec6097/numpy-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a7af9ed2aa9ec5950daf05bb11abc4076a108bd3c7db9aa7251d5f107079b6a6", size = 18577955, upload-time = "2025-07-24T20:45:26.714Z" }, - { url = "https://files.pythonhosted.org/packages/ae/11/7c546fcf42145f29b71e4d6f429e96d8d68e5a7ba1830b2e68d7418f0bbd/numpy-2.3.2-cp313-cp313-win32.whl", hash = "sha256:906a30249315f9c8e17b085cc5f87d3f369b35fedd0051d4a84686967bdbbd0b", size = 6311843, upload-time = "2025-07-24T20:49:24.444Z" }, - { url = "https://files.pythonhosted.org/packages/aa/6f/a428fd1cb7ed39b4280d057720fed5121b0d7754fd2a9768640160f5517b/numpy-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:c63d95dc9d67b676e9108fe0d2182987ccb0f11933c1e8959f42fa0da8d4fa56", size = 12782876, upload-time = "2025-07-24T20:49:43.227Z" }, - { url = "https://files.pythonhosted.org/packages/65/85/4ea455c9040a12595fb6c43f2c217257c7b52dd0ba332c6a6c1d28b289fe/numpy-2.3.2-cp313-cp313-win_arm64.whl", hash = "sha256:b05a89f2fb84d21235f93de47129dd4f11c16f64c87c33f5e284e6a3a54e43f2", size = 10192786, upload-time = "2025-07-24T20:49:59.443Z" }, - { url = "https://files.pythonhosted.org/packages/80/23/8278f40282d10c3f258ec3ff1b103d4994bcad78b0cba9208317f6bb73da/numpy-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4e6ecfeddfa83b02318f4d84acf15fbdbf9ded18e46989a15a8b6995dfbf85ab", size = 21047395, upload-time = "2025-07-24T20:45:58.821Z" }, - { url = "https://files.pythonhosted.org/packages/1f/2d/624f2ce4a5df52628b4ccd16a4f9437b37c35f4f8a50d00e962aae6efd7a/numpy-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:508b0eada3eded10a3b55725b40806a4b855961040180028f52580c4729916a2", size = 14300374, upload-time = "2025-07-24T20:46:20.207Z" }, - { url = "https://files.pythonhosted.org/packages/f6/62/ff1e512cdbb829b80a6bd08318a58698867bca0ca2499d101b4af063ee97/numpy-2.3.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:754d6755d9a7588bdc6ac47dc4ee97867271b17cee39cb87aef079574366db0a", size = 5228864, upload-time = "2025-07-24T20:46:30.58Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8e/74bc18078fff03192d4032cfa99d5a5ca937807136d6f5790ce07ca53515/numpy-2.3.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f66e7d2b2d7712410d3bc5684149040ef5f19856f20277cd17ea83e5006286", size = 6737533, upload-time = "2025-07-24T20:46:46.111Z" }, - { url = "https://files.pythonhosted.org/packages/19/ea/0731efe2c9073ccca5698ef6a8c3667c4cf4eea53fcdcd0b50140aba03bc/numpy-2.3.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:de6ea4e5a65d5a90c7d286ddff2b87f3f4ad61faa3db8dabe936b34c2275b6f8", size = 14352007, upload-time = "2025-07-24T20:47:07.1Z" }, - { url = "https://files.pythonhosted.org/packages/cf/90/36be0865f16dfed20f4bc7f75235b963d5939707d4b591f086777412ff7b/numpy-2.3.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a3ef07ec8cbc8fc9e369c8dcd52019510c12da4de81367d8b20bc692aa07573a", size = 16701914, upload-time = "2025-07-24T20:47:32.459Z" }, - { url = "https://files.pythonhosted.org/packages/94/30/06cd055e24cb6c38e5989a9e747042b4e723535758e6153f11afea88c01b/numpy-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:27c9f90e7481275c7800dc9c24b7cc40ace3fdb970ae4d21eaff983a32f70c91", size = 16132708, upload-time = "2025-07-24T20:47:58.129Z" }, - { url = "https://files.pythonhosted.org/packages/9a/14/ecede608ea73e58267fd7cb78f42341b3b37ba576e778a1a06baffbe585c/numpy-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:07b62978075b67eee4065b166d000d457c82a1efe726cce608b9db9dd66a73a5", size = 18651678, upload-time = "2025-07-24T20:48:25.402Z" }, - { url = "https://files.pythonhosted.org/packages/40/f3/2fe6066b8d07c3685509bc24d56386534c008b462a488b7f503ba82b8923/numpy-2.3.2-cp313-cp313t-win32.whl", hash = "sha256:c771cfac34a4f2c0de8e8c97312d07d64fd8f8ed45bc9f5726a7e947270152b5", size = 6441832, upload-time = "2025-07-24T20:48:37.181Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ba/0937d66d05204d8f28630c9c60bc3eda68824abde4cf756c4d6aad03b0c6/numpy-2.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:72dbebb2dcc8305c431b2836bcc66af967df91be793d63a24e3d9b741374c450", size = 12927049, upload-time = "2025-07-24T20:48:56.24Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ed/13542dd59c104d5e654dfa2ac282c199ba64846a74c2c4bcdbc3a0f75df1/numpy-2.3.2-cp313-cp313t-win_arm64.whl", hash = "sha256:72c6df2267e926a6d5286b0a6d556ebe49eae261062059317837fda12ddf0c1a", size = 10262935, upload-time = "2025-07-24T20:49:13.136Z" }, - { url = "https://files.pythonhosted.org/packages/c9/7c/7659048aaf498f7611b783e000c7268fcc4dcf0ce21cd10aad7b2e8f9591/numpy-2.3.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:448a66d052d0cf14ce9865d159bfc403282c9bc7bb2a31b03cc18b651eca8b1a", size = 20950906, upload-time = "2025-07-24T20:50:30.346Z" }, - { url = "https://files.pythonhosted.org/packages/80/db/984bea9d4ddf7112a04cfdfb22b1050af5757864cfffe8e09e44b7f11a10/numpy-2.3.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:546aaf78e81b4081b2eba1d105c3b34064783027a06b3ab20b6eba21fb64132b", size = 14185607, upload-time = "2025-07-24T20:50:51.923Z" }, - { url = "https://files.pythonhosted.org/packages/e4/76/b3d6f414f4eca568f469ac112a3b510938d892bc5a6c190cb883af080b77/numpy-2.3.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:87c930d52f45df092f7578889711a0768094debf73cfcde105e2d66954358125", size = 5114110, upload-time = "2025-07-24T20:51:01.041Z" }, - { url = "https://files.pythonhosted.org/packages/9e/d2/6f5e6826abd6bca52392ed88fe44a4b52aacb60567ac3bc86c67834c3a56/numpy-2.3.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:8dc082ea901a62edb8f59713c6a7e28a85daddcb67454c839de57656478f5b19", size = 6642050, upload-time = "2025-07-24T20:51:11.64Z" }, - { url = "https://files.pythonhosted.org/packages/c4/43/f12b2ade99199e39c73ad182f103f9d9791f48d885c600c8e05927865baf/numpy-2.3.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:af58de8745f7fa9ca1c0c7c943616c6fe28e75d0c81f5c295810e3c83b5be92f", size = 14296292, upload-time = "2025-07-24T20:51:33.488Z" }, - { url = "https://files.pythonhosted.org/packages/5d/f9/77c07d94bf110a916b17210fac38680ed8734c236bfed9982fd8524a7b47/numpy-2.3.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed5527c4cf10f16c6d0b6bee1f89958bccb0ad2522c8cadc2efd318bcd545f5", size = 16638913, upload-time = "2025-07-24T20:51:58.517Z" }, - { url = "https://files.pythonhosted.org/packages/9b/d1/9d9f2c8ea399cc05cfff8a7437453bd4e7d894373a93cdc46361bbb49a7d/numpy-2.3.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:095737ed986e00393ec18ec0b21b47c22889ae4b0cd2d5e88342e08b01141f58", size = 16071180, upload-time = "2025-07-24T20:52:22.827Z" }, - { url = "https://files.pythonhosted.org/packages/4c/41/82e2c68aff2a0c9bf315e47d61951099fed65d8cb2c8d9dc388cb87e947e/numpy-2.3.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5e40e80299607f597e1a8a247ff8d71d79c5b52baa11cc1cce30aa92d2da6e0", size = 18576809, upload-time = "2025-07-24T20:52:51.015Z" }, - { url = "https://files.pythonhosted.org/packages/14/14/4b4fd3efb0837ed252d0f583c5c35a75121038a8c4e065f2c259be06d2d8/numpy-2.3.2-cp314-cp314-win32.whl", hash = "sha256:7d6e390423cc1f76e1b8108c9b6889d20a7a1f59d9a60cac4a050fa734d6c1e2", size = 6366410, upload-time = "2025-07-24T20:56:44.949Z" }, - { url = "https://files.pythonhosted.org/packages/11/9e/b4c24a6b8467b61aced5c8dc7dcfce23621baa2e17f661edb2444a418040/numpy-2.3.2-cp314-cp314-win_amd64.whl", hash = "sha256:b9d0878b21e3918d76d2209c924ebb272340da1fb51abc00f986c258cd5e957b", size = 12918821, upload-time = "2025-07-24T20:57:06.479Z" }, - { url = "https://files.pythonhosted.org/packages/0e/0f/0dc44007c70b1007c1cef86b06986a3812dd7106d8f946c09cfa75782556/numpy-2.3.2-cp314-cp314-win_arm64.whl", hash = "sha256:2738534837c6a1d0c39340a190177d7d66fdf432894f469728da901f8f6dc910", size = 10477303, upload-time = "2025-07-24T20:57:22.879Z" }, - { url = "https://files.pythonhosted.org/packages/8b/3e/075752b79140b78ddfc9c0a1634d234cfdbc6f9bbbfa6b7504e445ad7d19/numpy-2.3.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:4d002ecf7c9b53240be3bb69d80f86ddbd34078bae04d87be81c1f58466f264e", size = 21047524, upload-time = "2025-07-24T20:53:22.086Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6d/60e8247564a72426570d0e0ea1151b95ce5bd2f1597bb878a18d32aec855/numpy-2.3.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:293b2192c6bcce487dbc6326de5853787f870aeb6c43f8f9c6496db5b1781e45", size = 14300519, upload-time = "2025-07-24T20:53:44.053Z" }, - { url = "https://files.pythonhosted.org/packages/4d/73/d8326c442cd428d47a067070c3ac6cc3b651a6e53613a1668342a12d4479/numpy-2.3.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:0a4f2021a6da53a0d580d6ef5db29947025ae8b35b3250141805ea9a32bbe86b", size = 5228972, upload-time = "2025-07-24T20:53:53.81Z" }, - { url = "https://files.pythonhosted.org/packages/34/2e/e71b2d6dad075271e7079db776196829019b90ce3ece5c69639e4f6fdc44/numpy-2.3.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9c144440db4bf3bb6372d2c3e49834cc0ff7bb4c24975ab33e01199e645416f2", size = 6737439, upload-time = "2025-07-24T20:54:04.742Z" }, - { url = "https://files.pythonhosted.org/packages/15/b0/d004bcd56c2c5e0500ffc65385eb6d569ffd3363cb5e593ae742749b2daa/numpy-2.3.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f92d6c2a8535dc4fe4419562294ff957f83a16ebdec66df0805e473ffaad8bd0", size = 14352479, upload-time = "2025-07-24T20:54:25.819Z" }, - { url = "https://files.pythonhosted.org/packages/11/e3/285142fcff8721e0c99b51686426165059874c150ea9ab898e12a492e291/numpy-2.3.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cefc2219baa48e468e3db7e706305fcd0c095534a192a08f31e98d83a7d45fb0", size = 16702805, upload-time = "2025-07-24T20:54:50.814Z" }, - { url = "https://files.pythonhosted.org/packages/33/c3/33b56b0e47e604af2c7cd065edca892d180f5899599b76830652875249a3/numpy-2.3.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:76c3e9501ceb50b2ff3824c3589d5d1ab4ac857b0ee3f8f49629d0de55ecf7c2", size = 16133830, upload-time = "2025-07-24T20:55:17.306Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ae/7b1476a1f4d6a48bc669b8deb09939c56dd2a439db1ab03017844374fb67/numpy-2.3.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:122bf5ed9a0221b3419672493878ba4967121514b1d7d4656a7580cd11dddcbf", size = 18652665, upload-time = "2025-07-24T20:55:46.665Z" }, - { url = "https://files.pythonhosted.org/packages/14/ba/5b5c9978c4bb161034148ade2de9db44ec316fab89ce8c400db0e0c81f86/numpy-2.3.2-cp314-cp314t-win32.whl", hash = "sha256:6f1ae3dcb840edccc45af496f312528c15b1f79ac318169d094e85e4bb35fdf1", size = 6514777, upload-time = "2025-07-24T20:55:57.66Z" }, - { url = "https://files.pythonhosted.org/packages/eb/46/3dbaf0ae7c17cdc46b9f662c56da2054887b8d9e737c1476f335c83d33db/numpy-2.3.2-cp314-cp314t-win_amd64.whl", hash = "sha256:087ffc25890d89a43536f75c5fe8770922008758e8eeeef61733957041ed2f9b", size = 13111856, upload-time = "2025-07-24T20:56:17.318Z" }, - { url = "https://files.pythonhosted.org/packages/c1/9e/1652778bce745a67b5fe05adde60ed362d38eb17d919a540e813d30f6874/numpy-2.3.2-cp314-cp314t-win_arm64.whl", hash = "sha256:092aeb3449833ea9c0bf0089d70c29ae480685dd2377ec9cdbbb620257f84631", size = 10544226, upload-time = "2025-07-24T20:56:34.509Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ea/50ebc91d28b275b23b7128ef25c3d08152bc4068f42742867e07a870a42a/numpy-2.3.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:14a91ebac98813a49bc6aa1a0dfc09513dcec1d97eaf31ca21a87221a1cdcb15", size = 21130338, upload-time = "2025-07-24T20:57:54.37Z" }, - { url = "https://files.pythonhosted.org/packages/9f/57/cdd5eac00dd5f137277355c318a955c0d8fb8aa486020c22afd305f8b88f/numpy-2.3.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:71669b5daae692189540cffc4c439468d35a3f84f0c88b078ecd94337f6cb0ec", size = 14375776, upload-time = "2025-07-24T20:58:16.303Z" }, - { url = "https://files.pythonhosted.org/packages/83/85/27280c7f34fcd305c2209c0cdca4d70775e4859a9eaa92f850087f8dea50/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:69779198d9caee6e547adb933941ed7520f896fd9656834c300bdf4dd8642712", size = 5304882, upload-time = "2025-07-24T20:58:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/48/b4/6500b24d278e15dd796f43824e69939d00981d37d9779e32499e823aa0aa/numpy-2.3.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:2c3271cc4097beb5a60f010bcc1cc204b300bb3eafb4399376418a83a1c6373c", size = 6818405, upload-time = "2025-07-24T20:58:37.341Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c9/142c1e03f199d202da8e980c2496213509291b6024fd2735ad28ae7065c7/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8446acd11fe3dc1830568c941d44449fd5cb83068e5c70bd5a470d323d448296", size = 14419651, upload-time = "2025-07-24T20:58:59.048Z" }, - { url = "https://files.pythonhosted.org/packages/8b/95/8023e87cbea31a750a6c00ff9427d65ebc5fef104a136bfa69f76266d614/numpy-2.3.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aa098a5ab53fa407fded5870865c6275a5cd4101cfdef8d6fafc48286a96e981", size = 16760166, upload-time = "2025-07-24T21:28:56.38Z" }, - { url = "https://files.pythonhosted.org/packages/78/e3/6690b3f85a05506733c7e90b577e4762517404ea78bab2ca3a5cb1aeb78d/numpy-2.3.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:6936aff90dda378c09bea075af0d9c675fe3a977a9d2402f95a87f440f59f619", size = 12977811, upload-time = "2025-07-24T21:29:18.234Z" }, + { url = "https://files.pythonhosted.org/packages/da/a8/4f83e2aa666a9fbf56d6118faaaf5f1974d456b1823fda0a176eff722839/numpy-2.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f9f1adb22318e121c5c69a09142811a201ef17ab257a1e66ca3025065b7f53ae", size = 21176963, upload_time = "2025-05-17T21:31:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/b3/2b/64e1affc7972decb74c9e29e5649fac940514910960ba25cd9af4488b66c/numpy-2.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c820a93b0255bc360f53eca31a0e676fd1101f673dda8da93454a12e23fc5f7a", size = 14406743, upload_time = "2025-05-17T21:31:41.087Z" }, + { url = "https://files.pythonhosted.org/packages/4a/9f/0121e375000b5e50ffdd8b25bf78d8e1a5aa4cca3f185d41265198c7b834/numpy-2.2.6-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3d70692235e759f260c3d837193090014aebdf026dfd167834bcba43e30c2a42", size = 5352616, upload_time = "2025-05-17T21:31:50.072Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/b48c405c91693635fbe2dcd7bc84a33a602add5f63286e024d3b6741411c/numpy-2.2.6-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:481b49095335f8eed42e39e8041327c05b0f6f4780488f61286ed3c01368d491", size = 6889579, upload_time = "2025-05-17T21:32:01.712Z" }, + { url = "https://files.pythonhosted.org/packages/52/b8/7f0554d49b565d0171eab6e99001846882000883998e7b7d9f0d98b1f934/numpy-2.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b64d8d4d17135e00c8e346e0a738deb17e754230d7e0810ac5012750bbd85a5a", size = 14312005, upload_time = "2025-05-17T21:32:23.332Z" }, + { url = "https://files.pythonhosted.org/packages/b3/dd/2238b898e51bd6d389b7389ffb20d7f4c10066d80351187ec8e303a5a475/numpy-2.2.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba10f8411898fc418a521833e014a77d3ca01c15b0c6cdcce6a0d2897e6dbbdf", size = 16821570, upload_time = "2025-05-17T21:32:47.991Z" }, + { url = "https://files.pythonhosted.org/packages/83/6c/44d0325722cf644f191042bf47eedad61c1e6df2432ed65cbe28509d404e/numpy-2.2.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:bd48227a919f1bafbdda0583705e547892342c26fb127219d60a5c36882609d1", size = 15818548, upload_time = "2025-05-17T21:33:11.728Z" }, + { url = "https://files.pythonhosted.org/packages/ae/9d/81e8216030ce66be25279098789b665d49ff19eef08bfa8cb96d4957f422/numpy-2.2.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9551a499bf125c1d4f9e250377c1ee2eddd02e01eac6644c080162c0c51778ab", size = 18620521, upload_time = "2025-05-17T21:33:39.139Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/e19617b9530b031db51b0926eed5345ce8ddc669bb3bc0044b23e275ebe8/numpy-2.2.6-cp311-cp311-win32.whl", hash = "sha256:0678000bb9ac1475cd454c6b8c799206af8107e310843532b04d49649c717a47", size = 6525866, upload_time = "2025-05-17T21:33:50.273Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/f354fb7176b81747d870f7991dc763e157a934c717b67b58456bc63da3df/numpy-2.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:e8213002e427c69c45a52bbd94163084025f533a55a59d6f9c5b820774ef3303", size = 12907455, upload_time = "2025-05-17T21:34:09.135Z" }, + { url = "https://files.pythonhosted.org/packages/82/5d/c00588b6cf18e1da539b45d3598d3557084990dcc4331960c15ee776ee41/numpy-2.2.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:41c5a21f4a04fa86436124d388f6ed60a9343a6f767fced1a8a71c3fbca038ff", size = 20875348, upload_time = "2025-05-17T21:34:39.648Z" }, + { url = "https://files.pythonhosted.org/packages/66/ee/560deadcdde6c2f90200450d5938f63a34b37e27ebff162810f716f6a230/numpy-2.2.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de749064336d37e340f640b05f24e9e3dd678c57318c7289d222a8a2f543e90c", size = 14119362, upload_time = "2025-05-17T21:35:01.241Z" }, + { url = "https://files.pythonhosted.org/packages/3c/65/4baa99f1c53b30adf0acd9a5519078871ddde8d2339dc5a7fde80d9d87da/numpy-2.2.6-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:894b3a42502226a1cac872f840030665f33326fc3dac8e57c607905773cdcde3", size = 5084103, upload_time = "2025-05-17T21:35:10.622Z" }, + { url = "https://files.pythonhosted.org/packages/cc/89/e5a34c071a0570cc40c9a54eb472d113eea6d002e9ae12bb3a8407fb912e/numpy-2.2.6-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:71594f7c51a18e728451bb50cc60a3ce4e6538822731b2933209a1f3614e9282", size = 6625382, upload_time = "2025-05-17T21:35:21.414Z" }, + { url = "https://files.pythonhosted.org/packages/f8/35/8c80729f1ff76b3921d5c9487c7ac3de9b2a103b1cd05e905b3090513510/numpy-2.2.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2618db89be1b4e05f7a1a847a9c1c0abd63e63a1607d892dd54668dd92faf87", size = 14018462, upload_time = "2025-05-17T21:35:42.174Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3d/1e1db36cfd41f895d266b103df00ca5b3cbe965184df824dec5c08c6b803/numpy-2.2.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd83c01228a688733f1ded5201c678f0c53ecc1006ffbc404db9f7a899ac6249", size = 16527618, upload_time = "2025-05-17T21:36:06.711Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/03ed30992602c85aa3cd95b9070a514f8b3c33e31124694438d88809ae36/numpy-2.2.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:37c0ca431f82cd5fa716eca9506aefcabc247fb27ba69c5062a6d3ade8cf8f49", size = 15505511, upload_time = "2025-05-17T21:36:29.965Z" }, + { url = "https://files.pythonhosted.org/packages/b7/25/5761d832a81df431e260719ec45de696414266613c9ee268394dd5ad8236/numpy-2.2.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fe27749d33bb772c80dcd84ae7e8df2adc920ae8297400dabec45f0dedb3f6de", size = 18313783, upload_time = "2025-05-17T21:36:56.883Z" }, + { url = "https://files.pythonhosted.org/packages/57/0a/72d5a3527c5ebffcd47bde9162c39fae1f90138c961e5296491ce778e682/numpy-2.2.6-cp312-cp312-win32.whl", hash = "sha256:4eeaae00d789f66c7a25ac5f34b71a7035bb474e679f410e5e1a94deb24cf2d4", size = 6246506, upload_time = "2025-05-17T21:37:07.368Z" }, + { url = "https://files.pythonhosted.org/packages/36/fa/8c9210162ca1b88529ab76b41ba02d433fd54fecaf6feb70ef9f124683f1/numpy-2.2.6-cp312-cp312-win_amd64.whl", hash = "sha256:c1f9540be57940698ed329904db803cf7a402f3fc200bfe599334c9bd84a40b2", size = 12614190, upload_time = "2025-05-17T21:37:26.213Z" }, + { url = "https://files.pythonhosted.org/packages/f9/5c/6657823f4f594f72b5471f1db1ab12e26e890bb2e41897522d134d2a3e81/numpy-2.2.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0811bb762109d9708cca4d0b13c4f67146e3c3b7cf8d34018c722adb2d957c84", size = 20867828, upload_time = "2025-05-17T21:37:56.699Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9e/14520dc3dadf3c803473bd07e9b2bd1b69bc583cb2497b47000fed2fa92f/numpy-2.2.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:287cc3162b6f01463ccd86be154f284d0893d2b3ed7292439ea97eafa8170e0b", size = 14143006, upload_time = "2025-05-17T21:38:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/4f/06/7e96c57d90bebdce9918412087fc22ca9851cceaf5567a45c1f404480e9e/numpy-2.2.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:f1372f041402e37e5e633e586f62aa53de2eac8d98cbfb822806ce4bbefcb74d", size = 5076765, upload_time = "2025-05-17T21:38:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/73/ed/63d920c23b4289fdac96ddbdd6132e9427790977d5457cd132f18e76eae0/numpy-2.2.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:55a4d33fa519660d69614a9fad433be87e5252f4b03850642f88993f7b2ca566", size = 6617736, upload_time = "2025-05-17T21:38:38.141Z" }, + { url = "https://files.pythonhosted.org/packages/85/c5/e19c8f99d83fd377ec8c7e0cf627a8049746da54afc24ef0a0cb73d5dfb5/numpy-2.2.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f92729c95468a2f4f15e9bb94c432a9229d0d50de67304399627a943201baa2f", size = 14010719, upload_time = "2025-05-17T21:38:58.433Z" }, + { url = "https://files.pythonhosted.org/packages/19/49/4df9123aafa7b539317bf6d342cb6d227e49f7a35b99c287a6109b13dd93/numpy-2.2.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc23a79bfabc5d056d106f9befb8d50c31ced2fbc70eedb8155aec74a45798f", size = 16526072, upload_time = "2025-05-17T21:39:22.638Z" }, + { url = "https://files.pythonhosted.org/packages/b2/6c/04b5f47f4f32f7c2b0e7260442a8cbcf8168b0e1a41ff1495da42f42a14f/numpy-2.2.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e3143e4451880bed956e706a3220b4e5cf6172ef05fcc397f6f36a550b1dd868", size = 15503213, upload_time = "2025-05-17T21:39:45.865Z" }, + { url = "https://files.pythonhosted.org/packages/17/0a/5cd92e352c1307640d5b6fec1b2ffb06cd0dabe7d7b8227f97933d378422/numpy-2.2.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4f13750ce79751586ae2eb824ba7e1e8dba64784086c98cdbbcc6a42112ce0d", size = 18316632, upload_time = "2025-05-17T21:40:13.331Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3b/5cba2b1d88760ef86596ad0f3d484b1cbff7c115ae2429678465057c5155/numpy-2.2.6-cp313-cp313-win32.whl", hash = "sha256:5beb72339d9d4fa36522fc63802f469b13cdbe4fdab4a288f0c441b74272ebfd", size = 6244532, upload_time = "2025-05-17T21:43:46.099Z" }, + { url = "https://files.pythonhosted.org/packages/cb/3b/d58c12eafcb298d4e6d0d40216866ab15f59e55d148a5658bb3132311fcf/numpy-2.2.6-cp313-cp313-win_amd64.whl", hash = "sha256:b0544343a702fa80c95ad5d3d608ea3599dd54d4632df855e4c8d24eb6ecfa1c", size = 12610885, upload_time = "2025-05-17T21:44:05.145Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9e/4bf918b818e516322db999ac25d00c75788ddfd2d2ade4fa66f1f38097e1/numpy-2.2.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0bca768cd85ae743b2affdc762d617eddf3bcf8724435498a1e80132d04879e6", size = 20963467, upload_time = "2025-05-17T21:40:44Z" }, + { url = "https://files.pythonhosted.org/packages/61/66/d2de6b291507517ff2e438e13ff7b1e2cdbdb7cb40b3ed475377aece69f9/numpy-2.2.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fc0c5673685c508a142ca65209b4e79ed6740a4ed6b2267dbba90f34b0b3cfda", size = 14225144, upload_time = "2025-05-17T21:41:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/25/480387655407ead912e28ba3a820bc69af9adf13bcbe40b299d454ec011f/numpy-2.2.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:5bd4fc3ac8926b3819797a7c0e2631eb889b4118a9898c84f585a54d475b7e40", size = 5200217, upload_time = "2025-05-17T21:41:15.903Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4a/6e313b5108f53dcbf3aca0c0f3e9c92f4c10ce57a0a721851f9785872895/numpy-2.2.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:fee4236c876c4e8369388054d02d0e9bb84821feb1a64dd59e137e6511a551f8", size = 6712014, upload_time = "2025-05-17T21:41:27.321Z" }, + { url = "https://files.pythonhosted.org/packages/b7/30/172c2d5c4be71fdf476e9de553443cf8e25feddbe185e0bd88b096915bcc/numpy-2.2.6-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1dda9c7e08dc141e0247a5b8f49cf05984955246a327d4c48bda16821947b2f", size = 14077935, upload_time = "2025-05-17T21:41:49.738Z" }, + { url = "https://files.pythonhosted.org/packages/12/fb/9e743f8d4e4d3c710902cf87af3512082ae3d43b945d5d16563f26ec251d/numpy-2.2.6-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f447e6acb680fd307f40d3da4852208af94afdfab89cf850986c3ca00562f4fa", size = 16600122, upload_time = "2025-05-17T21:42:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/12/75/ee20da0e58d3a66f204f38916757e01e33a9737d0b22373b3eb5a27358f9/numpy-2.2.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:389d771b1623ec92636b0786bc4ae56abafad4a4c513d36a55dce14bd9ce8571", size = 15586143, upload_time = "2025-05-17T21:42:37.464Z" }, + { url = "https://files.pythonhosted.org/packages/76/95/bef5b37f29fc5e739947e9ce5179ad402875633308504a52d188302319c8/numpy-2.2.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8e9ace4a37db23421249ed236fdcdd457d671e25146786dfc96835cd951aa7c1", size = 18385260, upload_time = "2025-05-17T21:43:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/09/04/f2f83279d287407cf36a7a8053a5abe7be3622a4363337338f2585e4afda/numpy-2.2.6-cp313-cp313t-win32.whl", hash = "sha256:038613e9fb8c72b0a41f025a7e4c3f0b7a1b5d768ece4796b674c8f3fe13efff", size = 6377225, upload_time = "2025-05-17T21:43:16.254Z" }, + { url = "https://files.pythonhosted.org/packages/67/0e/35082d13c09c02c011cf21570543d202ad929d961c02a147493cb0c2bdf5/numpy-2.2.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6031dd6dfecc0cf9f668681a37648373bddd6421fff6c66ec1624eed0180ee06", size = 12771374, upload_time = "2025-05-17T21:43:35.479Z" }, ] [[package]] name = "overrides" version = "7.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload-time = "2024-01-27T21:01:33.423Z" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812, upload_time = "2024-01-27T21:01:33.423Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload-time = "2024-01-27T21:01:31.393Z" }, + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832, upload_time = "2024-01-27T21:01:31.393Z" }, ] [[package]] name = "packaging" version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload_time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload_time = "2025-04-19T11:48:57.875Z" }, ] [[package]] @@ -1387,66 +1404,53 @@ dependencies = [ { name = "pytz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d1/6f/75aa71f8a14267117adeeed5d21b204770189c0a0025acbdc03c337b28fc/pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2", size = 4487493, upload-time = "2025-07-07T19:20:04.079Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d1/6f/75aa71f8a14267117adeeed5d21b204770189c0a0025acbdc03c337b28fc/pandas-2.3.1.tar.gz", hash = "sha256:0a95b9ac964fe83ce317827f80304d37388ea77616b1425f0ae41c9d2d0d7bb2", size = 4487493, upload_time = "2025-07-07T19:20:04.079Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/1c/ccf70029e927e473a4476c00e0d5b32e623bff27f0402d0a92b7fc29bb9f/pandas-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b", size = 11566608, upload-time = "2025-07-07T19:18:33.86Z" }, - { url = "https://files.pythonhosted.org/packages/ec/d3/3c37cb724d76a841f14b8f5fe57e5e3645207cc67370e4f84717e8bb7657/pandas-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f", size = 10823181, upload-time = "2025-07-07T19:18:36.151Z" }, - { url = "https://files.pythonhosted.org/packages/8a/4c/367c98854a1251940edf54a4df0826dcacfb987f9068abf3e3064081a382/pandas-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85", size = 11793570, upload-time = "2025-07-07T19:18:38.385Z" }, - { url = "https://files.pythonhosted.org/packages/07/5f/63760ff107bcf5146eee41b38b3985f9055e710a72fdd637b791dea3495c/pandas-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d", size = 12378887, upload-time = "2025-07-07T19:18:41.284Z" }, - { url = "https://files.pythonhosted.org/packages/15/53/f31a9b4dfe73fe4711c3a609bd8e60238022f48eacedc257cd13ae9327a7/pandas-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678", size = 13230957, upload-time = "2025-07-07T19:18:44.187Z" }, - { url = "https://files.pythonhosted.org/packages/e0/94/6fce6bf85b5056d065e0a7933cba2616dcb48596f7ba3c6341ec4bcc529d/pandas-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299", size = 13883883, upload-time = "2025-07-07T19:18:46.498Z" }, - { url = "https://files.pythonhosted.org/packages/c8/7b/bdcb1ed8fccb63d04bdb7635161d0ec26596d92c9d7a6cce964e7876b6c1/pandas-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab", size = 11340212, upload-time = "2025-07-07T19:18:49.293Z" }, - { url = "https://files.pythonhosted.org/packages/46/de/b8445e0f5d217a99fe0eeb2f4988070908979bec3587c0633e5428ab596c/pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3", size = 11588172, upload-time = "2025-07-07T19:18:52.054Z" }, - { url = "https://files.pythonhosted.org/packages/1e/e0/801cdb3564e65a5ac041ab99ea6f1d802a6c325bb6e58c79c06a3f1cd010/pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232", size = 10717365, upload-time = "2025-07-07T19:18:54.785Z" }, - { url = "https://files.pythonhosted.org/packages/51/a5/c76a8311833c24ae61a376dbf360eb1b1c9247a5d9c1e8b356563b31b80c/pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e", size = 11280411, upload-time = "2025-07-07T19:18:57.045Z" }, - { url = "https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4", size = 11988013, upload-time = "2025-07-07T19:18:59.771Z" }, - { url = "https://files.pythonhosted.org/packages/5b/14/cec7760d7c9507f11c97d64f29022e12a6cc4fc03ac694535e89f88ad2ec/pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8", size = 12767210, upload-time = "2025-07-07T19:19:02.944Z" }, - { url = "https://files.pythonhosted.org/packages/50/b9/6e2d2c6728ed29fb3d4d4d302504fb66f1a543e37eb2e43f352a86365cdf/pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679", size = 13440571, upload-time = "2025-07-07T19:19:06.82Z" }, - { url = "https://files.pythonhosted.org/packages/80/a5/3a92893e7399a691bad7664d977cb5e7c81cf666c81f89ea76ba2bff483d/pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8", size = 10987601, upload-time = "2025-07-07T19:19:09.589Z" }, - { url = "https://files.pythonhosted.org/packages/32/ed/ff0a67a2c5505e1854e6715586ac6693dd860fbf52ef9f81edee200266e7/pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22", size = 11531393, upload-time = "2025-07-07T19:19:12.245Z" }, - { url = "https://files.pythonhosted.org/packages/c7/db/d8f24a7cc9fb0972adab0cc80b6817e8bef888cfd0024eeb5a21c0bb5c4a/pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a", size = 10668750, upload-time = "2025-07-07T19:19:14.612Z" }, - { url = "https://files.pythonhosted.org/packages/0f/b0/80f6ec783313f1e2356b28b4fd8d2148c378370045da918c73145e6aab50/pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928", size = 11342004, upload-time = "2025-07-07T19:19:16.857Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e2/20a317688435470872885e7fc8f95109ae9683dec7c50be29b56911515a5/pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9", size = 12050869, upload-time = "2025-07-07T19:19:19.265Z" }, - { url = "https://files.pythonhosted.org/packages/55/79/20d746b0a96c67203a5bee5fb4e00ac49c3e8009a39e1f78de264ecc5729/pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12", size = 12750218, upload-time = "2025-07-07T19:19:21.547Z" }, - { url = "https://files.pythonhosted.org/packages/7c/0f/145c8b41e48dbf03dd18fdd7f24f8ba95b8254a97a3379048378f33e7838/pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb", size = 13416763, upload-time = "2025-07-07T19:19:23.939Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c0/54415af59db5cdd86a3d3bf79863e8cc3fa9ed265f0745254061ac09d5f2/pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956", size = 10987482, upload-time = "2025-07-07T19:19:42.699Z" }, - { url = "https://files.pythonhosted.org/packages/48/64/2fd2e400073a1230e13b8cd604c9bc95d9e3b962e5d44088ead2e8f0cfec/pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a", size = 12029159, upload-time = "2025-07-07T19:19:26.362Z" }, - { url = "https://files.pythonhosted.org/packages/d8/0a/d84fd79b0293b7ef88c760d7dca69828d867c89b6d9bc52d6a27e4d87316/pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9", size = 11393287, upload-time = "2025-07-07T19:19:29.157Z" }, - { url = "https://files.pythonhosted.org/packages/50/ae/ff885d2b6e88f3c7520bb74ba319268b42f05d7e583b5dded9837da2723f/pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275", size = 11309381, upload-time = "2025-07-07T19:19:31.436Z" }, - { url = "https://files.pythonhosted.org/packages/85/86/1fa345fc17caf5d7780d2699985c03dbe186c68fee00b526813939062bb0/pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab", size = 11883998, upload-time = "2025-07-07T19:19:34.267Z" }, - { url = "https://files.pythonhosted.org/packages/81/aa/e58541a49b5e6310d89474333e994ee57fea97c8aaa8fc7f00b873059bbf/pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96", size = 12704705, upload-time = "2025-07-07T19:19:36.856Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f9/07086f5b0f2a19872554abeea7658200824f5835c58a106fa8f2ae96a46c/pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444", size = 13189044, upload-time = "2025-07-07T19:19:39.999Z" }, -] - -[[package]] -name = "pandas-stubs" -version = "2.3.0.250703" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, - { name = "types-pytz" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ec/df/c1c51c5cec087b8f4d04669308b700e9648745a77cdd0c8c5e16520703ca/pandas_stubs-2.3.0.250703.tar.gz", hash = "sha256:fb6a8478327b16ed65c46b1541de74f5c5947f3601850caf3e885e0140584717", size = 103910, upload-time = "2025-07-02T17:49:11.667Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/75/cb/09d5f9bf7c8659af134ae0ffc1a349038a5d0ff93e45aedc225bde2872a3/pandas_stubs-2.3.0.250703-py3-none-any.whl", hash = "sha256:a9265fc69909f0f7a9cabc5f596d86c9d531499fed86b7838fd3278285d76b81", size = 154719, upload-time = "2025-07-02T17:49:10.697Z" }, + { url = "https://files.pythonhosted.org/packages/76/1c/ccf70029e927e473a4476c00e0d5b32e623bff27f0402d0a92b7fc29bb9f/pandas-2.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2b0540963d83431f5ce8870ea02a7430adca100cec8a050f0811f8e31035541b", size = 11566608, upload_time = "2025-07-07T19:18:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/ec/d3/3c37cb724d76a841f14b8f5fe57e5e3645207cc67370e4f84717e8bb7657/pandas-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fe7317f578c6a153912bd2292f02e40c1d8f253e93c599e82620c7f69755c74f", size = 10823181, upload_time = "2025-07-07T19:18:36.151Z" }, + { url = "https://files.pythonhosted.org/packages/8a/4c/367c98854a1251940edf54a4df0826dcacfb987f9068abf3e3064081a382/pandas-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6723a27ad7b244c0c79d8e7007092d7c8f0f11305770e2f4cd778b3ad5f9f85", size = 11793570, upload_time = "2025-07-07T19:18:38.385Z" }, + { url = "https://files.pythonhosted.org/packages/07/5f/63760ff107bcf5146eee41b38b3985f9055e710a72fdd637b791dea3495c/pandas-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3462c3735fe19f2638f2c3a40bd94ec2dc5ba13abbb032dd2fa1f540a075509d", size = 12378887, upload_time = "2025-07-07T19:18:41.284Z" }, + { url = "https://files.pythonhosted.org/packages/15/53/f31a9b4dfe73fe4711c3a609bd8e60238022f48eacedc257cd13ae9327a7/pandas-2.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:98bcc8b5bf7afed22cc753a28bc4d9e26e078e777066bc53fac7904ddef9a678", size = 13230957, upload_time = "2025-07-07T19:18:44.187Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/6fce6bf85b5056d065e0a7933cba2616dcb48596f7ba3c6341ec4bcc529d/pandas-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d544806b485ddf29e52d75b1f559142514e60ef58a832f74fb38e48d757b299", size = 13883883, upload_time = "2025-07-07T19:18:46.498Z" }, + { url = "https://files.pythonhosted.org/packages/c8/7b/bdcb1ed8fccb63d04bdb7635161d0ec26596d92c9d7a6cce964e7876b6c1/pandas-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:b3cd4273d3cb3707b6fffd217204c52ed92859533e31dc03b7c5008aa933aaab", size = 11340212, upload_time = "2025-07-07T19:18:49.293Z" }, + { url = "https://files.pythonhosted.org/packages/46/de/b8445e0f5d217a99fe0eeb2f4988070908979bec3587c0633e5428ab596c/pandas-2.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:689968e841136f9e542020698ee1c4fbe9caa2ed2213ae2388dc7b81721510d3", size = 11588172, upload_time = "2025-07-07T19:18:52.054Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e0/801cdb3564e65a5ac041ab99ea6f1d802a6c325bb6e58c79c06a3f1cd010/pandas-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:025e92411c16cbe5bb2a4abc99732a6b132f439b8aab23a59fa593eb00704232", size = 10717365, upload_time = "2025-07-07T19:18:54.785Z" }, + { url = "https://files.pythonhosted.org/packages/51/a5/c76a8311833c24ae61a376dbf360eb1b1c9247a5d9c1e8b356563b31b80c/pandas-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7ff55f31c4fcb3e316e8f7fa194566b286d6ac430afec0d461163312c5841e", size = 11280411, upload_time = "2025-07-07T19:18:57.045Z" }, + { url = "https://files.pythonhosted.org/packages/da/01/e383018feba0a1ead6cf5fe8728e5d767fee02f06a3d800e82c489e5daaf/pandas-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7dcb79bf373a47d2a40cf7232928eb7540155abbc460925c2c96d2d30b006eb4", size = 11988013, upload_time = "2025-07-07T19:18:59.771Z" }, + { url = "https://files.pythonhosted.org/packages/5b/14/cec7760d7c9507f11c97d64f29022e12a6cc4fc03ac694535e89f88ad2ec/pandas-2.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:56a342b231e8862c96bdb6ab97170e203ce511f4d0429589c8ede1ee8ece48b8", size = 12767210, upload_time = "2025-07-07T19:19:02.944Z" }, + { url = "https://files.pythonhosted.org/packages/50/b9/6e2d2c6728ed29fb3d4d4d302504fb66f1a543e37eb2e43f352a86365cdf/pandas-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ca7ed14832bce68baef331f4d7f294411bed8efd032f8109d690df45e00c4679", size = 13440571, upload_time = "2025-07-07T19:19:06.82Z" }, + { url = "https://files.pythonhosted.org/packages/80/a5/3a92893e7399a691bad7664d977cb5e7c81cf666c81f89ea76ba2bff483d/pandas-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ac942bfd0aca577bef61f2bc8da8147c4ef6879965ef883d8e8d5d2dc3e744b8", size = 10987601, upload_time = "2025-07-07T19:19:09.589Z" }, + { url = "https://files.pythonhosted.org/packages/32/ed/ff0a67a2c5505e1854e6715586ac6693dd860fbf52ef9f81edee200266e7/pandas-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9026bd4a80108fac2239294a15ef9003c4ee191a0f64b90f170b40cfb7cf2d22", size = 11531393, upload_time = "2025-07-07T19:19:12.245Z" }, + { url = "https://files.pythonhosted.org/packages/c7/db/d8f24a7cc9fb0972adab0cc80b6817e8bef888cfd0024eeb5a21c0bb5c4a/pandas-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6de8547d4fdb12421e2d047a2c446c623ff4c11f47fddb6b9169eb98ffba485a", size = 10668750, upload_time = "2025-07-07T19:19:14.612Z" }, + { url = "https://files.pythonhosted.org/packages/0f/b0/80f6ec783313f1e2356b28b4fd8d2148c378370045da918c73145e6aab50/pandas-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:782647ddc63c83133b2506912cc6b108140a38a37292102aaa19c81c83db2928", size = 11342004, upload_time = "2025-07-07T19:19:16.857Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e2/20a317688435470872885e7fc8f95109ae9683dec7c50be29b56911515a5/pandas-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba6aff74075311fc88504b1db890187a3cd0f887a5b10f5525f8e2ef55bfdb9", size = 12050869, upload_time = "2025-07-07T19:19:19.265Z" }, + { url = "https://files.pythonhosted.org/packages/55/79/20d746b0a96c67203a5bee5fb4e00ac49c3e8009a39e1f78de264ecc5729/pandas-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e5635178b387bd2ba4ac040f82bc2ef6e6b500483975c4ebacd34bec945fda12", size = 12750218, upload_time = "2025-07-07T19:19:21.547Z" }, + { url = "https://files.pythonhosted.org/packages/7c/0f/145c8b41e48dbf03dd18fdd7f24f8ba95b8254a97a3379048378f33e7838/pandas-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6f3bf5ec947526106399a9e1d26d40ee2b259c66422efdf4de63c848492d91bb", size = 13416763, upload_time = "2025-07-07T19:19:23.939Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c0/54415af59db5cdd86a3d3bf79863e8cc3fa9ed265f0745254061ac09d5f2/pandas-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:1c78cf43c8fde236342a1cb2c34bcff89564a7bfed7e474ed2fffa6aed03a956", size = 10987482, upload_time = "2025-07-07T19:19:42.699Z" }, + { url = "https://files.pythonhosted.org/packages/48/64/2fd2e400073a1230e13b8cd604c9bc95d9e3b962e5d44088ead2e8f0cfec/pandas-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8dfc17328e8da77be3cf9f47509e5637ba8f137148ed0e9b5241e1baf526e20a", size = 12029159, upload_time = "2025-07-07T19:19:26.362Z" }, + { url = "https://files.pythonhosted.org/packages/d8/0a/d84fd79b0293b7ef88c760d7dca69828d867c89b6d9bc52d6a27e4d87316/pandas-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ec6c851509364c59a5344458ab935e6451b31b818be467eb24b0fe89bd05b6b9", size = 11393287, upload_time = "2025-07-07T19:19:29.157Z" }, + { url = "https://files.pythonhosted.org/packages/50/ae/ff885d2b6e88f3c7520bb74ba319268b42f05d7e583b5dded9837da2723f/pandas-2.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:911580460fc4884d9b05254b38a6bfadddfcc6aaef856fb5859e7ca202e45275", size = 11309381, upload_time = "2025-07-07T19:19:31.436Z" }, + { url = "https://files.pythonhosted.org/packages/85/86/1fa345fc17caf5d7780d2699985c03dbe186c68fee00b526813939062bb0/pandas-2.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f4d6feeba91744872a600e6edbbd5b033005b431d5ae8379abee5bcfa479fab", size = 11883998, upload_time = "2025-07-07T19:19:34.267Z" }, + { url = "https://files.pythonhosted.org/packages/81/aa/e58541a49b5e6310d89474333e994ee57fea97c8aaa8fc7f00b873059bbf/pandas-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fe37e757f462d31a9cd7580236a82f353f5713a80e059a29753cf938c6775d96", size = 12704705, upload_time = "2025-07-07T19:19:36.856Z" }, + { url = "https://files.pythonhosted.org/packages/d5/f9/07086f5b0f2a19872554abeea7658200824f5835c58a106fa8f2ae96a46c/pandas-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5db9637dbc24b631ff3707269ae4559bce4b7fd75c1c4d7e13f40edc42df4444", size = 13189044, upload_time = "2025-07-07T19:19:39.999Z" }, ] [[package]] name = "pandocfilters" version = "1.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload_time = "2024-01-18T20:08:13.726Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload_time = "2024-01-18T20:08:11.28Z" }, ] [[package]] name = "parso" version = "0.8.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload-time = "2024-04-05T09:43:55.897Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609, upload_time = "2024-04-05T09:43:55.897Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload-time = "2024-04-05T09:43:53.299Z" }, + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650, upload_time = "2024-04-05T09:43:53.299Z" }, ] [[package]] @@ -1456,120 +1460,120 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ptyprocess" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload_time = "2023-11-25T09:07:26.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload_time = "2023-11-25T06:56:14.81Z" }, ] [[package]] name = "pillow" version = "11.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload_time = "2025-07-01T09:16:30.666Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload-time = "2025-07-01T09:13:59.203Z" }, - { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload-time = "2025-07-01T09:14:01.101Z" }, - { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload-time = "2025-07-03T13:09:55.638Z" }, - { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload-time = "2025-07-03T13:10:00.37Z" }, - { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload-time = "2025-07-01T09:14:04.491Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload-time = "2025-07-01T09:14:06.235Z" }, - { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload-time = "2025-07-01T09:14:07.978Z" }, - { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload-time = "2025-07-01T09:14:10.233Z" }, - { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload-time = "2025-07-01T09:14:11.921Z" }, - { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload-time = "2025-07-01T09:14:13.623Z" }, - { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload-time = "2025-07-01T09:14:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload-time = "2025-07-01T09:14:17.648Z" }, - { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload-time = "2025-07-01T09:14:19.828Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload-time = "2025-07-03T13:10:04.448Z" }, - { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload-time = "2025-07-03T13:10:10.391Z" }, - { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload-time = "2025-07-01T09:14:21.63Z" }, - { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload-time = "2025-07-01T09:14:23.321Z" }, - { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload-time = "2025-07-01T09:14:25.237Z" }, - { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload-time = "2025-07-01T09:14:27.053Z" }, - { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload-time = "2025-07-01T09:14:30.104Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload-time = "2025-07-01T09:14:31.899Z" }, - { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload-time = "2025-07-01T09:14:33.709Z" }, - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, - { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload-time = "2025-07-01T09:16:19.801Z" }, - { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload-time = "2025-07-01T09:16:21.818Z" }, - { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload-time = "2025-07-03T13:11:20.738Z" }, - { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload-time = "2025-07-03T13:11:26.283Z" }, - { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload-time = "2025-07-01T09:16:23.762Z" }, - { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload-time = "2025-07-01T09:16:25.593Z" }, - { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload-time = "2025-07-01T09:16:27.732Z" }, + { url = "https://files.pythonhosted.org/packages/db/26/77f8ed17ca4ffd60e1dcd220a6ec6d71210ba398cfa33a13a1cd614c5613/pillow-11.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1cd110edf822773368b396281a2293aeb91c90a2db00d78ea43e7e861631b722", size = 5316531, upload_time = "2025-07-01T09:13:59.203Z" }, + { url = "https://files.pythonhosted.org/packages/cb/39/ee475903197ce709322a17a866892efb560f57900d9af2e55f86db51b0a5/pillow-11.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9c412fddd1b77a75aa904615ebaa6001f169b26fd467b4be93aded278266b288", size = 4686560, upload_time = "2025-07-01T09:14:01.101Z" }, + { url = "https://files.pythonhosted.org/packages/d5/90/442068a160fd179938ba55ec8c97050a612426fae5ec0a764e345839f76d/pillow-11.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1aa4de119a0ecac0a34a9c8bde33f34022e2e8f99104e47a3ca392fd60e37d", size = 5870978, upload_time = "2025-07-03T13:09:55.638Z" }, + { url = "https://files.pythonhosted.org/packages/13/92/dcdd147ab02daf405387f0218dcf792dc6dd5b14d2573d40b4caeef01059/pillow-11.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:91da1d88226663594e3f6b4b8c3c8d85bd504117d043740a8e0ec449087cc494", size = 7641168, upload_time = "2025-07-03T13:10:00.37Z" }, + { url = "https://files.pythonhosted.org/packages/6e/db/839d6ba7fd38b51af641aa904e2960e7a5644d60ec754c046b7d2aee00e5/pillow-11.3.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:643f189248837533073c405ec2f0bb250ba54598cf80e8c1e043381a60632f58", size = 5973053, upload_time = "2025-07-01T09:14:04.491Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2f/d7675ecae6c43e9f12aa8d58b6012683b20b6edfbdac7abcb4e6af7a3784/pillow-11.3.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:106064daa23a745510dabce1d84f29137a37224831d88eb4ce94bb187b1d7e5f", size = 6640273, upload_time = "2025-07-01T09:14:06.235Z" }, + { url = "https://files.pythonhosted.org/packages/45/ad/931694675ede172e15b2ff03c8144a0ddaea1d87adb72bb07655eaffb654/pillow-11.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cd8ff254faf15591e724dc7c4ddb6bf4793efcbe13802a4ae3e863cd300b493e", size = 6082043, upload_time = "2025-07-01T09:14:07.978Z" }, + { url = "https://files.pythonhosted.org/packages/3a/04/ba8f2b11fc80d2dd462d7abec16351b45ec99cbbaea4387648a44190351a/pillow-11.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:932c754c2d51ad2b2271fd01c3d121daaa35e27efae2a616f77bf164bc0b3e94", size = 6715516, upload_time = "2025-07-01T09:14:10.233Z" }, + { url = "https://files.pythonhosted.org/packages/48/59/8cd06d7f3944cc7d892e8533c56b0acb68399f640786313275faec1e3b6f/pillow-11.3.0-cp311-cp311-win32.whl", hash = "sha256:b4b8f3efc8d530a1544e5962bd6b403d5f7fe8b9e08227c6b255f98ad82b4ba0", size = 6274768, upload_time = "2025-07-01T09:14:11.921Z" }, + { url = "https://files.pythonhosted.org/packages/f1/cc/29c0f5d64ab8eae20f3232da8f8571660aa0ab4b8f1331da5c2f5f9a938e/pillow-11.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:1a992e86b0dd7aeb1f053cd506508c0999d710a8f07b4c791c63843fc6a807ac", size = 6986055, upload_time = "2025-07-01T09:14:13.623Z" }, + { url = "https://files.pythonhosted.org/packages/c6/df/90bd886fabd544c25addd63e5ca6932c86f2b701d5da6c7839387a076b4a/pillow-11.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:30807c931ff7c095620fe04448e2c2fc673fcbb1ffe2a7da3fb39613489b1ddd", size = 2423079, upload_time = "2025-07-01T09:14:15.268Z" }, + { url = "https://files.pythonhosted.org/packages/40/fe/1bc9b3ee13f68487a99ac9529968035cca2f0a51ec36892060edcc51d06a/pillow-11.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdae223722da47b024b867c1ea0be64e0df702c5e0a60e27daad39bf960dd1e4", size = 5278800, upload_time = "2025-07-01T09:14:17.648Z" }, + { url = "https://files.pythonhosted.org/packages/2c/32/7e2ac19b5713657384cec55f89065fb306b06af008cfd87e572035b27119/pillow-11.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:921bd305b10e82b4d1f5e802b6850677f965d8394203d182f078873851dada69", size = 4686296, upload_time = "2025-07-01T09:14:19.828Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1e/b9e12bbe6e4c2220effebc09ea0923a07a6da1e1f1bfbc8d7d29a01ce32b/pillow-11.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb76541cba2f958032d79d143b98a3a6b3ea87f0959bbe256c0b5e416599fd5d", size = 5871726, upload_time = "2025-07-03T13:10:04.448Z" }, + { url = "https://files.pythonhosted.org/packages/8d/33/e9200d2bd7ba00dc3ddb78df1198a6e80d7669cce6c2bdbeb2530a74ec58/pillow-11.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:67172f2944ebba3d4a7b54f2e95c786a3a50c21b88456329314caaa28cda70f6", size = 7644652, upload_time = "2025-07-03T13:10:10.391Z" }, + { url = "https://files.pythonhosted.org/packages/41/f1/6f2427a26fc683e00d985bc391bdd76d8dd4e92fac33d841127eb8fb2313/pillow-11.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97f07ed9f56a3b9b5f49d3661dc9607484e85c67e27f3e8be2c7d28ca032fec7", size = 5977787, upload_time = "2025-07-01T09:14:21.63Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c9/06dd4a38974e24f932ff5f98ea3c546ce3f8c995d3f0985f8e5ba48bba19/pillow-11.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:676b2815362456b5b3216b4fd5bd89d362100dc6f4945154ff172e206a22c024", size = 6645236, upload_time = "2025-07-01T09:14:23.321Z" }, + { url = "https://files.pythonhosted.org/packages/40/e7/848f69fb79843b3d91241bad658e9c14f39a32f71a301bcd1d139416d1be/pillow-11.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3e184b2f26ff146363dd07bde8b711833d7b0202e27d13540bfe2e35a323a809", size = 6086950, upload_time = "2025-07-01T09:14:25.237Z" }, + { url = "https://files.pythonhosted.org/packages/0b/1a/7cff92e695a2a29ac1958c2a0fe4c0b2393b60aac13b04a4fe2735cad52d/pillow-11.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6be31e3fc9a621e071bc17bb7de63b85cbe0bfae91bb0363c893cbe67247780d", size = 6723358, upload_time = "2025-07-01T09:14:27.053Z" }, + { url = "https://files.pythonhosted.org/packages/26/7d/73699ad77895f69edff76b0f332acc3d497f22f5d75e5360f78cbcaff248/pillow-11.3.0-cp312-cp312-win32.whl", hash = "sha256:7b161756381f0918e05e7cb8a371fff367e807770f8fe92ecb20d905d0e1c149", size = 6275079, upload_time = "2025-07-01T09:14:30.104Z" }, + { url = "https://files.pythonhosted.org/packages/8c/ce/e7dfc873bdd9828f3b6e5c2bbb74e47a98ec23cc5c74fc4e54462f0d9204/pillow-11.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:a6444696fce635783440b7f7a9fc24b3ad10a9ea3f0ab66c5905be1c19ccf17d", size = 6986324, upload_time = "2025-07-01T09:14:31.899Z" }, + { url = "https://files.pythonhosted.org/packages/16/8f/b13447d1bf0b1f7467ce7d86f6e6edf66c0ad7cf44cf5c87a37f9bed9936/pillow-11.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:2aceea54f957dd4448264f9bf40875da0415c83eb85f55069d89c0ed436e3542", size = 2423067, upload_time = "2025-07-01T09:14:33.709Z" }, + { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload_time = "2025-07-01T09:14:35.276Z" }, + { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload_time = "2025-07-01T09:14:37.203Z" }, + { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload_time = "2025-07-01T09:14:39.344Z" }, + { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload_time = "2025-07-01T09:14:41.843Z" }, + { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload_time = "2025-07-01T09:14:44.008Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload_time = "2025-07-03T13:10:15.628Z" }, + { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload_time = "2025-07-03T13:10:21.857Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload_time = "2025-07-01T09:14:45.698Z" }, + { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload_time = "2025-07-01T09:14:47.415Z" }, + { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload_time = "2025-07-01T09:14:49.636Z" }, + { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload_time = "2025-07-01T09:14:51.962Z" }, + { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload_time = "2025-07-01T09:14:54.142Z" }, + { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload_time = "2025-07-01T09:14:56.436Z" }, + { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload_time = "2025-07-01T09:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload_time = "2025-07-01T09:14:59.79Z" }, + { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload_time = "2025-07-01T09:15:01.648Z" }, + { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload_time = "2025-07-03T13:10:27.018Z" }, + { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload_time = "2025-07-03T13:10:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload_time = "2025-07-01T09:15:03.365Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload_time = "2025-07-01T09:15:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload_time = "2025-07-01T09:15:07.358Z" }, + { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload_time = "2025-07-01T09:15:09.317Z" }, + { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload_time = "2025-07-01T09:15:11.311Z" }, + { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload_time = "2025-07-01T09:15:13.164Z" }, + { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload_time = "2025-07-01T09:15:15.695Z" }, + { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload_time = "2025-07-01T09:15:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload_time = "2025-07-01T09:15:19.423Z" }, + { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload_time = "2025-07-03T13:10:38.404Z" }, + { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload_time = "2025-07-03T13:10:44.987Z" }, + { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload_time = "2025-07-01T09:15:21.237Z" }, + { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload_time = "2025-07-01T09:15:23.186Z" }, + { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload_time = "2025-07-01T09:15:25.1Z" }, + { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload_time = "2025-07-01T09:15:27.378Z" }, + { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload_time = "2025-07-01T09:15:29.294Z" }, + { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload_time = "2025-07-01T09:15:31.128Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload_time = "2025-07-01T09:15:33.328Z" }, + { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload_time = "2025-07-01T09:15:35.194Z" }, + { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload_time = "2025-07-01T09:15:37.114Z" }, + { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload_time = "2025-07-03T13:10:50.248Z" }, + { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload_time = "2025-07-03T13:10:56.432Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload_time = "2025-07-01T09:15:39.436Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload_time = "2025-07-01T09:15:41.269Z" }, + { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload_time = "2025-07-01T09:15:43.13Z" }, + { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload_time = "2025-07-01T09:15:44.937Z" }, + { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload_time = "2025-07-01T09:15:46.673Z" }, + { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload_time = "2025-07-01T09:15:48.512Z" }, + { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload_time = "2025-07-01T09:15:50.399Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e3/6fa84033758276fb31da12e5fb66ad747ae83b93c67af17f8c6ff4cc8f34/pillow-11.3.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7c8ec7a017ad1bd562f93dbd8505763e688d388cde6e4a010ae1486916e713e6", size = 5270566, upload_time = "2025-07-01T09:16:19.801Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ee/e8d2e1ab4892970b561e1ba96cbd59c0d28cf66737fc44abb2aec3795a4e/pillow-11.3.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:9ab6ae226de48019caa8074894544af5b53a117ccb9d3b3dcb2871464c829438", size = 4654618, upload_time = "2025-07-01T09:16:21.818Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6d/17f80f4e1f0761f02160fc433abd4109fa1548dcfdca46cfdadaf9efa565/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fe27fb049cdcca11f11a7bfda64043c37b30e6b91f10cb5bab275806c32f6ab3", size = 4874248, upload_time = "2025-07-03T13:11:20.738Z" }, + { url = "https://files.pythonhosted.org/packages/de/5f/c22340acd61cef960130585bbe2120e2fd8434c214802f07e8c03596b17e/pillow-11.3.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:465b9e8844e3c3519a983d58b80be3f668e2a7a5db97f2784e7079fbc9f9822c", size = 6583963, upload_time = "2025-07-03T13:11:26.283Z" }, + { url = "https://files.pythonhosted.org/packages/31/5e/03966aedfbfcbb4d5f8aa042452d3361f325b963ebbadddac05b122e47dd/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5418b53c0d59b3824d05e029669efa023bbef0f3e92e75ec8428f3799487f361", size = 4957170, upload_time = "2025-07-01T09:16:23.762Z" }, + { url = "https://files.pythonhosted.org/packages/cc/2d/e082982aacc927fc2cab48e1e731bdb1643a1406acace8bed0900a61464e/pillow-11.3.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:504b6f59505f08ae014f724b6207ff6222662aab5cc9542577fb084ed0676ac7", size = 5581505, upload_time = "2025-07-01T09:16:25.593Z" }, + { url = "https://files.pythonhosted.org/packages/34/e7/ae39f538fd6844e982063c3a5e4598b8ced43b9633baa3a85ef33af8c05c/pillow-11.3.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c84d689db21a1c397d001aa08241044aa2069e7587b398c8cc63020390b1c1b8", size = 6984598, upload_time = "2025-07-01T09:16:27.732Z" }, ] [[package]] name = "platformdirs" version = "4.3.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload_time = "2025-05-07T22:47:42.121Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, + { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload_time = "2025-05-07T22:47:40.376Z" }, ] [[package]] name = "pluggy" version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload_time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload_time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "prometheus-client" version = "0.22.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload_time = "2025-06-02T14:29:01.152Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, + { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload_time = "2025-06-02T14:29:00.068Z" }, ] [[package]] @@ -1579,69 +1583,69 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wcwidth" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload-time = "2025-04-15T09:18:47.731Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/6e/9d084c929dfe9e3bfe0c6a47e31f78a25c54627d64a66e884a8bf5474f1c/prompt_toolkit-3.0.51.tar.gz", hash = "sha256:931a162e3b27fc90c86f1b48bb1fb2c528c2761475e57c9c06de13311c7b54ed", size = 428940, upload_time = "2025-04-15T09:18:47.731Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload-time = "2025-04-15T09:18:44.753Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/5249960887b1fbe561d9ff265496d170b55a735b76724f10ef19f9e40716/prompt_toolkit-3.0.51-py3-none-any.whl", hash = "sha256:52742911fde84e2d423e2f9a4cf1de7d7ac4e51958f648d9540e0fb8db077b07", size = 387810, upload_time = "2025-04-15T09:18:44.753Z" }, ] [[package]] name = "psutil" version = "7.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload-time = "2025-02-13T21:54:07.946Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003, upload_time = "2025-02-13T21:54:07.946Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload-time = "2025-02-13T21:54:12.36Z" }, - { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload-time = "2025-02-13T21:54:16.07Z" }, - { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload-time = "2025-02-13T21:54:18.662Z" }, - { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload-time = "2025-02-13T21:54:21.811Z" }, - { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload-time = "2025-02-13T21:54:24.68Z" }, - { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload-time = "2025-02-13T21:54:34.31Z" }, - { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload-time = "2025-02-13T21:54:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051, upload_time = "2025-02-13T21:54:12.36Z" }, + { url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535, upload_time = "2025-02-13T21:54:16.07Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004, upload_time = "2025-02-13T21:54:18.662Z" }, + { url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986, upload_time = "2025-02-13T21:54:21.811Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544, upload_time = "2025-02-13T21:54:24.68Z" }, + { url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053, upload_time = "2025-02-13T21:54:34.31Z" }, + { url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885, upload_time = "2025-02-13T21:54:37.486Z" }, ] [[package]] name = "ptyprocess" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload_time = "2020-12-28T15:15:30.155Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload_time = "2020-12-28T15:15:28.35Z" }, ] [[package]] name = "pure-eval" version = "0.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload_time = "2024-07-21T12:58:21.801Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload_time = "2024-07-21T12:58:20.04Z" }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload_time = "2024-03-30T13:22:22.564Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload_time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pygments" version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload_time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload_time = "2025-06-21T13:39:07.939Z" }, ] [[package]] name = "pyparsing" version = "3.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload_time = "2025-03-25T05:01:28.114Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload_time = "2025-03-25T05:01:24.908Z" }, ] [[package]] @@ -1655,9 +1659,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload_time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload_time = "2025-06-18T05:48:03.955Z" }, ] [[package]] @@ -1667,27 +1671,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload_time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload_time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-json-logger" version = "3.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/de/d3144a0bceede957f961e975f3752760fbe390d57fbe194baf709d8f1f7b/python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84", size = 16642, upload-time = "2025-03-07T07:08:27.301Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/de/d3144a0bceede957f961e975f3752760fbe390d57fbe194baf709d8f1f7b/python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84", size = 16642, upload_time = "2025-03-07T07:08:27.301Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7", size = 15163, upload-time = "2025-03-07T07:08:25.627Z" }, + { url = "https://files.pythonhosted.org/packages/08/20/0f2523b9e50a8052bc6a8b732dfc8568abbdc42010aef03a2d750bdab3b2/python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7", size = 15163, upload_time = "2025-03-07T07:08:25.627Z" }, ] [[package]] name = "pytz" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload_time = "2025-03-25T02:25:00.538Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload_time = "2025-03-25T02:24:58.468Z" }, ] [[package]] @@ -1695,65 +1699,65 @@ name = "pywin32" version = "311" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload-time = "2025-07-14T20:13:13.266Z" }, - { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload-time = "2025-07-14T20:13:15.147Z" }, - { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload-time = "2025-07-14T20:13:16.945Z" }, - { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload-time = "2025-07-14T20:13:20.765Z" }, - { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload-time = "2025-07-14T20:13:22.543Z" }, - { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload-time = "2025-07-14T20:13:24.682Z" }, - { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload-time = "2025-07-14T20:13:26.471Z" }, - { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload-time = "2025-07-14T20:13:28.243Z" }, - { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload-time = "2025-07-14T20:13:30.348Z" }, - { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload-time = "2025-07-14T20:13:32.449Z" }, - { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload-time = "2025-07-14T20:13:34.312Z" }, - { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/449a6a91e5d6db51420875c54f6aff7c97a86a3b13a0b4f1a5c13b988de3/pywin32-311-cp311-cp311-win32.whl", hash = "sha256:184eb5e436dea364dcd3d2316d577d625c0351bf237c4e9a5fabbcfa5a58b151", size = 8697031, upload_time = "2025-07-14T20:13:13.266Z" }, + { url = "https://files.pythonhosted.org/packages/51/8f/9bb81dd5bb77d22243d33c8397f09377056d5c687aa6d4042bea7fbf8364/pywin32-311-cp311-cp311-win_amd64.whl", hash = "sha256:3ce80b34b22b17ccbd937a6e78e7225d80c52f5ab9940fe0506a1a16f3dab503", size = 9508308, upload_time = "2025-07-14T20:13:15.147Z" }, + { url = "https://files.pythonhosted.org/packages/44/7b/9c2ab54f74a138c491aba1b1cd0795ba61f144c711daea84a88b63dc0f6c/pywin32-311-cp311-cp311-win_arm64.whl", hash = "sha256:a733f1388e1a842abb67ffa8e7aad0e70ac519e09b0f6a784e65a136ec7cefd2", size = 8703930, upload_time = "2025-07-14T20:13:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/01ea1943d4eba0f850c3c61e78e8dd59757ff815ff3ccd0a84de5f541f42/pywin32-311-cp312-cp312-win32.whl", hash = "sha256:750ec6e621af2b948540032557b10a2d43b0cee2ae9758c54154d711cc852d31", size = 8706543, upload_time = "2025-07-14T20:13:20.765Z" }, + { url = "https://files.pythonhosted.org/packages/d1/a8/a0e8d07d4d051ec7502cd58b291ec98dcc0c3fff027caad0470b72cfcc2f/pywin32-311-cp312-cp312-win_amd64.whl", hash = "sha256:b8c095edad5c211ff31c05223658e71bf7116daa0ecf3ad85f3201ea3190d067", size = 9495040, upload_time = "2025-07-14T20:13:22.543Z" }, + { url = "https://files.pythonhosted.org/packages/ba/3a/2ae996277b4b50f17d61f0603efd8253cb2d79cc7ae159468007b586396d/pywin32-311-cp312-cp312-win_arm64.whl", hash = "sha256:e286f46a9a39c4a18b319c28f59b61de793654af2f395c102b4f819e584b5852", size = 8710102, upload_time = "2025-07-14T20:13:24.682Z" }, + { url = "https://files.pythonhosted.org/packages/a5/be/3fd5de0979fcb3994bfee0d65ed8ca9506a8a1260651b86174f6a86f52b3/pywin32-311-cp313-cp313-win32.whl", hash = "sha256:f95ba5a847cba10dd8c4d8fefa9f2a6cf283b8b88ed6178fa8a6c1ab16054d0d", size = 8705700, upload_time = "2025-07-14T20:13:26.471Z" }, + { url = "https://files.pythonhosted.org/packages/e3/28/e0a1909523c6890208295a29e05c2adb2126364e289826c0a8bc7297bd5c/pywin32-311-cp313-cp313-win_amd64.whl", hash = "sha256:718a38f7e5b058e76aee1c56ddd06908116d35147e133427e59a3983f703a20d", size = 9494700, upload_time = "2025-07-14T20:13:28.243Z" }, + { url = "https://files.pythonhosted.org/packages/04/bf/90339ac0f55726dce7d794e6d79a18a91265bdf3aa70b6b9ca52f35e022a/pywin32-311-cp313-cp313-win_arm64.whl", hash = "sha256:7b4075d959648406202d92a2310cb990fea19b535c7f4a78d3f5e10b926eeb8a", size = 8709318, upload_time = "2025-07-14T20:13:30.348Z" }, + { url = "https://files.pythonhosted.org/packages/c9/31/097f2e132c4f16d99a22bfb777e0fd88bd8e1c634304e102f313af69ace5/pywin32-311-cp314-cp314-win32.whl", hash = "sha256:b7a2c10b93f8986666d0c803ee19b5990885872a7de910fc460f9b0c2fbf92ee", size = 8840714, upload_time = "2025-07-14T20:13:32.449Z" }, + { url = "https://files.pythonhosted.org/packages/90/4b/07c77d8ba0e01349358082713400435347df8426208171ce297da32c313d/pywin32-311-cp314-cp314-win_amd64.whl", hash = "sha256:3aca44c046bd2ed8c90de9cb8427f581c479e594e99b5c0bb19b29c10fd6cb87", size = 9656800, upload_time = "2025-07-14T20:13:34.312Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload_time = "2025-07-14T20:13:36.379Z" }, ] [[package]] name = "pywinpty" version = "2.0.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/7c/917f9c4681bb8d34bfbe0b79d36bbcd902651aeab48790df3d30ba0202fb/pywinpty-2.0.15.tar.gz", hash = "sha256:312cf39153a8736c617d45ce8b6ad6cd2107de121df91c455b10ce6bba7a39b2", size = 29017, upload-time = "2025-02-03T21:53:23.265Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/7c/917f9c4681bb8d34bfbe0b79d36bbcd902651aeab48790df3d30ba0202fb/pywinpty-2.0.15.tar.gz", hash = "sha256:312cf39153a8736c617d45ce8b6ad6cd2107de121df91c455b10ce6bba7a39b2", size = 29017, upload_time = "2025-02-03T21:53:23.265Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/ac/6884dcb7108af66ad53f73ef4dad096e768c9203a6e6ce5e6b0c4a46e238/pywinpty-2.0.15-cp311-cp311-win_amd64.whl", hash = "sha256:9a6bcec2df2707aaa9d08b86071970ee32c5026e10bcc3cc5f6f391d85baf7ca", size = 1405249, upload-time = "2025-02-03T21:55:47.114Z" }, - { url = "https://files.pythonhosted.org/packages/88/e5/9714def18c3a411809771a3fbcec70bffa764b9675afb00048a620fca604/pywinpty-2.0.15-cp312-cp312-win_amd64.whl", hash = "sha256:83a8f20b430bbc5d8957249f875341a60219a4e971580f2ba694fbfb54a45ebc", size = 1405243, upload-time = "2025-02-03T21:56:52.476Z" }, - { url = "https://files.pythonhosted.org/packages/fb/16/2ab7b3b7f55f3c6929e5f629e1a68362981e4e5fed592a2ed1cb4b4914a5/pywinpty-2.0.15-cp313-cp313-win_amd64.whl", hash = "sha256:ab5920877dd632c124b4ed17bc6dd6ef3b9f86cd492b963ffdb1a67b85b0f408", size = 1405020, upload-time = "2025-02-03T21:56:04.753Z" }, - { url = "https://files.pythonhosted.org/packages/7c/16/edef3515dd2030db2795dbfbe392232c7a0f3dc41b98e92b38b42ba497c7/pywinpty-2.0.15-cp313-cp313t-win_amd64.whl", hash = "sha256:a4560ad8c01e537708d2790dbe7da7d986791de805d89dd0d3697ca59e9e4901", size = 1404151, upload-time = "2025-02-03T21:55:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/5e/ac/6884dcb7108af66ad53f73ef4dad096e768c9203a6e6ce5e6b0c4a46e238/pywinpty-2.0.15-cp311-cp311-win_amd64.whl", hash = "sha256:9a6bcec2df2707aaa9d08b86071970ee32c5026e10bcc3cc5f6f391d85baf7ca", size = 1405249, upload_time = "2025-02-03T21:55:47.114Z" }, + { url = "https://files.pythonhosted.org/packages/88/e5/9714def18c3a411809771a3fbcec70bffa764b9675afb00048a620fca604/pywinpty-2.0.15-cp312-cp312-win_amd64.whl", hash = "sha256:83a8f20b430bbc5d8957249f875341a60219a4e971580f2ba694fbfb54a45ebc", size = 1405243, upload_time = "2025-02-03T21:56:52.476Z" }, + { url = "https://files.pythonhosted.org/packages/fb/16/2ab7b3b7f55f3c6929e5f629e1a68362981e4e5fed592a2ed1cb4b4914a5/pywinpty-2.0.15-cp313-cp313-win_amd64.whl", hash = "sha256:ab5920877dd632c124b4ed17bc6dd6ef3b9f86cd492b963ffdb1a67b85b0f408", size = 1405020, upload_time = "2025-02-03T21:56:04.753Z" }, + { url = "https://files.pythonhosted.org/packages/7c/16/edef3515dd2030db2795dbfbe392232c7a0f3dc41b98e92b38b42ba497c7/pywinpty-2.0.15-cp313-cp313t-win_amd64.whl", hash = "sha256:a4560ad8c01e537708d2790dbe7da7d986791de805d89dd0d3697ca59e9e4901", size = 1404151, upload_time = "2025-02-03T21:55:53.628Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload_time = "2024-08-06T20:33:50.674Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, - { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, - { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, - { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, - { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, - { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, - { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, - { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, - { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, - { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload_time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload_time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload_time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload_time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload_time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload_time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload_time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload_time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload_time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload_time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload_time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload_time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload_time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload_time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload_time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload_time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload_time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload_time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload_time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload_time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload_time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload_time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload_time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload_time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload_time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload_time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload_time = "2024-08-06T20:33:04.33Z" }, ] [[package]] @@ -1763,55 +1767,55 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "implementation_name == 'pypy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/30/5f/557d2032a2f471edbcc227da724c24a1c05887b5cda1e3ae53af98b9e0a5/pyzmq-27.0.1.tar.gz", hash = "sha256:45c549204bc20e7484ffd2555f6cf02e572440ecf2f3bdd60d4404b20fddf64b", size = 281158, upload-time = "2025-08-03T05:05:40.352Z" } +sdist = { url = "https://files.pythonhosted.org/packages/30/5f/557d2032a2f471edbcc227da724c24a1c05887b5cda1e3ae53af98b9e0a5/pyzmq-27.0.1.tar.gz", hash = "sha256:45c549204bc20e7484ffd2555f6cf02e572440ecf2f3bdd60d4404b20fddf64b", size = 281158, upload_time = "2025-08-03T05:05:40.352Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/18/a8e0da6ababbe9326116fb1c890bf1920eea880e8da621afb6bc0f39a262/pyzmq-27.0.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9729190bd770314f5fbba42476abf6abe79a746eeda11d1d68fd56dd70e5c296", size = 1332721, upload-time = "2025-08-03T05:03:15.237Z" }, - { url = "https://files.pythonhosted.org/packages/75/a4/9431ba598651d60ebd50dc25755402b770322cf8432adcc07d2906e53a54/pyzmq-27.0.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:696900ef6bc20bef6a242973943574f96c3f97d2183c1bd3da5eea4f559631b1", size = 908249, upload-time = "2025-08-03T05:03:16.933Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/e624e1793689e4e685d2ee21c40277dd4024d9d730af20446d88f69be838/pyzmq-27.0.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f96a63aecec22d3f7fdea3c6c98df9e42973f5856bb6812c3d8d78c262fee808", size = 668649, upload-time = "2025-08-03T05:03:18.49Z" }, - { url = "https://files.pythonhosted.org/packages/6c/29/0652a39d4e876e0d61379047ecf7752685414ad2e253434348246f7a2a39/pyzmq-27.0.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c512824360ea7490390566ce00bee880e19b526b312b25cc0bc30a0fe95cb67f", size = 856601, upload-time = "2025-08-03T05:03:20.194Z" }, - { url = "https://files.pythonhosted.org/packages/36/2d/8d5355d7fc55bb6e9c581dd74f58b64fa78c994079e3a0ea09b1b5627cde/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dfb2bb5e0f7198eaacfb6796fb0330afd28f36d985a770745fba554a5903595a", size = 1657750, upload-time = "2025-08-03T05:03:22.055Z" }, - { url = "https://files.pythonhosted.org/packages/ab/f4/cd032352d5d252dc6f5ee272a34b59718ba3af1639a8a4ef4654f9535cf5/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4f6886c59ba93ffde09b957d3e857e7950c8fe818bd5494d9b4287bc6d5bc7f1", size = 2034312, upload-time = "2025-08-03T05:03:23.578Z" }, - { url = "https://files.pythonhosted.org/packages/e4/1a/c050d8b6597200e97a4bd29b93c769d002fa0b03083858227e0376ad59bc/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b99ea9d330e86ce1ff7f2456b33f1bf81c43862a5590faf4ef4ed3a63504bdab", size = 1893632, upload-time = "2025-08-03T05:03:25.167Z" }, - { url = "https://files.pythonhosted.org/packages/6a/29/173ce21d5097e7fcf284a090e8beb64fc683c6582b1f00fa52b1b7e867ce/pyzmq-27.0.1-cp311-cp311-win32.whl", hash = "sha256:571f762aed89025ba8cdcbe355fea56889715ec06d0264fd8b6a3f3fa38154ed", size = 566587, upload-time = "2025-08-03T05:03:26.769Z" }, - { url = "https://files.pythonhosted.org/packages/53/ab/22bd33e7086f0a2cc03a5adabff4bde414288bb62a21a7820951ef86ec20/pyzmq-27.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee16906c8025fa464bea1e48128c048d02359fb40bebe5333103228528506530", size = 632873, upload-time = "2025-08-03T05:03:28.685Z" }, - { url = "https://files.pythonhosted.org/packages/90/14/3e59b4a28194285ceeff725eba9aa5ba8568d1cb78aed381dec1537c705a/pyzmq-27.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:ba068f28028849da725ff9185c24f832ccf9207a40f9b28ac46ab7c04994bd41", size = 558918, upload-time = "2025-08-03T05:03:30.085Z" }, - { url = "https://files.pythonhosted.org/packages/0e/9b/c0957041067c7724b310f22c398be46399297c12ed834c3bc42200a2756f/pyzmq-27.0.1-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:af7ebce2a1e7caf30c0bb64a845f63a69e76a2fadbc1cac47178f7bb6e657bdd", size = 1305432, upload-time = "2025-08-03T05:03:32.177Z" }, - { url = "https://files.pythonhosted.org/packages/8e/55/bd3a312790858f16b7def3897a0c3eb1804e974711bf7b9dcb5f47e7f82c/pyzmq-27.0.1-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8f617f60a8b609a13099b313e7e525e67f84ef4524b6acad396d9ff153f6e4cd", size = 895095, upload-time = "2025-08-03T05:03:33.918Z" }, - { url = "https://files.pythonhosted.org/packages/20/50/fc384631d8282809fb1029a4460d2fe90fa0370a0e866a8318ed75c8d3bb/pyzmq-27.0.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d59dad4173dc2a111f03e59315c7bd6e73da1a9d20a84a25cf08325b0582b1a", size = 651826, upload-time = "2025-08-03T05:03:35.818Z" }, - { url = "https://files.pythonhosted.org/packages/7e/0a/2356305c423a975000867de56888b79e44ec2192c690ff93c3109fd78081/pyzmq-27.0.1-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5b6133c8d313bde8bd0d123c169d22525300ff164c2189f849de495e1344577", size = 839751, upload-time = "2025-08-03T05:03:37.265Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1b/81e95ad256ca7e7ccd47f5294c1c6da6e2b64fbace65b84fe8a41470342e/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:58cca552567423f04d06a075f4b473e78ab5bdb906febe56bf4797633f54aa4e", size = 1641359, upload-time = "2025-08-03T05:03:38.799Z" }, - { url = "https://files.pythonhosted.org/packages/50/63/9f50ec965285f4e92c265c8f18344e46b12803666d8b73b65d254d441435/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:4b9d8e26fb600d0d69cc9933e20af08552e97cc868a183d38a5c0d661e40dfbb", size = 2020281, upload-time = "2025-08-03T05:03:40.338Z" }, - { url = "https://files.pythonhosted.org/packages/02/4a/19e3398d0dc66ad2b463e4afa1fc541d697d7bc090305f9dfb948d3dfa29/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2329f0c87f0466dce45bba32b63f47018dda5ca40a0085cc5c8558fea7d9fc55", size = 1877112, upload-time = "2025-08-03T05:03:42.012Z" }, - { url = "https://files.pythonhosted.org/packages/bf/42/c562e9151aa90ed1d70aac381ea22a929d6b3a2ce4e1d6e2e135d34fd9c6/pyzmq-27.0.1-cp312-abi3-win32.whl", hash = "sha256:57bb92abdb48467b89c2d21da1ab01a07d0745e536d62afd2e30d5acbd0092eb", size = 558177, upload-time = "2025-08-03T05:03:43.979Z" }, - { url = "https://files.pythonhosted.org/packages/40/96/5c50a7d2d2b05b19994bf7336b97db254299353dd9b49b565bb71b485f03/pyzmq-27.0.1-cp312-abi3-win_amd64.whl", hash = "sha256:ff3f8757570e45da7a5bedaa140489846510014f7a9d5ee9301c61f3f1b8a686", size = 618923, upload-time = "2025-08-03T05:03:45.438Z" }, - { url = "https://files.pythonhosted.org/packages/13/33/1ec89c8f21c89d21a2eaff7def3676e21d8248d2675705e72554fb5a6f3f/pyzmq-27.0.1-cp312-abi3-win_arm64.whl", hash = "sha256:df2c55c958d3766bdb3e9d858b911288acec09a9aab15883f384fc7180df5bed", size = 552358, upload-time = "2025-08-03T05:03:46.887Z" }, - { url = "https://files.pythonhosted.org/packages/6c/a0/f26e276211ec8090a4d11e4ec70eb8a8b15781e591c1d44ce62f372963a0/pyzmq-27.0.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:497bd8af534ae55dc4ef67eebd1c149ff2a0b0f1e146db73c8b5a53d83c1a5f5", size = 1122287, upload-time = "2025-08-03T05:03:48.838Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d8/af4b507e4f7eeea478cc8ee873995a6fd55582bfb99140593ed460e1db3c/pyzmq-27.0.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:a066ea6ad6218b4c233906adf0ae67830f451ed238419c0db609310dd781fbe7", size = 1155756, upload-time = "2025-08-03T05:03:50.907Z" }, - { url = "https://files.pythonhosted.org/packages/ac/55/37fae0013e11f88681da42698e550b08a316d608242551f65095cc99232a/pyzmq-27.0.1-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:72d235d6365ca73d8ce92f7425065d70f5c1e19baa458eb3f0d570e425b73a96", size = 1340826, upload-time = "2025-08-03T05:03:52.568Z" }, - { url = "https://files.pythonhosted.org/packages/f2/e4/3a87854c64b26fcf63a9d1b6f4382bd727d4797c772ceb334a97b7489be9/pyzmq-27.0.1-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:313a7b374e3dc64848644ca348a51004b41726f768b02e17e689f1322366a4d9", size = 897283, upload-time = "2025-08-03T05:03:54.167Z" }, - { url = "https://files.pythonhosted.org/packages/17/3e/4296c6b0ad2d07be11ae1395dccf9cae48a0a655cf9be1c3733ad2b591d1/pyzmq-27.0.1-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:119ce8590409702394f959c159d048002cbed2f3c0645ec9d6a88087fc70f0f1", size = 660565, upload-time = "2025-08-03T05:03:56.152Z" }, - { url = "https://files.pythonhosted.org/packages/72/41/a33ba3aa48b45b23c4cd4ac49aafde46f3e0f81939f2bfb3b6171a437122/pyzmq-27.0.1-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45c3e00ce16896ace2cd770ab9057a7cf97d4613ea5f2a13f815141d8b6894b9", size = 847680, upload-time = "2025-08-03T05:03:57.696Z" }, - { url = "https://files.pythonhosted.org/packages/3f/8c/bf2350bb25b3b58d2e5b5d2290ffab0e923f0cc6d02288d3fbf4baa6e4d1/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:678e50ec112bdc6df5a83ac259a55a4ba97a8b314c325ab26b3b5b071151bc61", size = 1650151, upload-time = "2025-08-03T05:03:59.387Z" }, - { url = "https://files.pythonhosted.org/packages/f7/1a/a5a07c54890891344a8ddc3d5ab320dd3c4e39febb6e4472546e456d5157/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d0b96c30be9f9387b18b18b6133c75a7b1b0065da64e150fe1feb5ebf31ece1c", size = 2023766, upload-time = "2025-08-03T05:04:01.883Z" }, - { url = "https://files.pythonhosted.org/packages/62/5e/514dcff08f02c6c8a45a6e23621901139cf853be7ac5ccd0b9407c3aa3de/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88dc92d9eb5ea4968123e74db146d770b0c8d48f0e2bfb1dbc6c50a8edb12d64", size = 1885195, upload-time = "2025-08-03T05:04:03.923Z" }, - { url = "https://files.pythonhosted.org/packages/c8/91/87f74f98a487fbef0b115f6025e4a295129fd56b2b633a03ba7d5816ecc2/pyzmq-27.0.1-cp313-cp313t-win32.whl", hash = "sha256:6dcbcb34f5c9b0cefdfc71ff745459241b7d3cda5b27c7ad69d45afc0821d1e1", size = 574213, upload-time = "2025-08-03T05:04:05.905Z" }, - { url = "https://files.pythonhosted.org/packages/e6/d7/07f7d0d7f4c81e08be7b60e52ff2591c557377c017f96204d33d5fca1b07/pyzmq-27.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9fd0fda730461f510cfd9a40fafa5355d65f5e3dbdd8d6dfa342b5b3f5d1949", size = 640202, upload-time = "2025-08-03T05:04:07.439Z" }, - { url = "https://files.pythonhosted.org/packages/ab/83/21d66bcef6fb803647a223cbde95111b099e2176277c0cbc8b099c485510/pyzmq-27.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:56a3b1853f3954ec1f0e91085f1350cc57d18f11205e4ab6e83e4b7c414120e0", size = 561514, upload-time = "2025-08-03T05:04:09.071Z" }, - { url = "https://files.pythonhosted.org/packages/5a/0b/d5ea75cf46b52cdce85a85200c963cb498932953df443892238be49b1a01/pyzmq-27.0.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:f98f6b7787bd2beb1f0dde03f23a0621a0c978edf673b7d8f5e7bc039cbe1b60", size = 1340836, upload-time = "2025-08-03T05:04:10.774Z" }, - { url = "https://files.pythonhosted.org/packages/be/4c/0dbce882550e17db6846b29e9dc242aea7590e7594e1ca5043e8e58fff2d/pyzmq-27.0.1-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:351bf5d8ca0788ca85327fda45843b6927593ff4c807faee368cc5aaf9f809c2", size = 897236, upload-time = "2025-08-03T05:04:13.221Z" }, - { url = "https://files.pythonhosted.org/packages/1b/22/461e131cf16b8814f3c356fa1ea0912697dbc4c64cddf01f7756ec704c1e/pyzmq-27.0.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5268a5a9177afff53dc6d70dffe63114ba2a6e7b20d9411cc3adeba09eeda403", size = 660374, upload-time = "2025-08-03T05:04:15.032Z" }, - { url = "https://files.pythonhosted.org/packages/3f/0c/bbd65a814395bf4fc3e57c6c13af27601c07e4009bdfb75ebcf500537bbd/pyzmq-27.0.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4aca06ba295aa78bec9b33ec028d1ca08744c36294338c41432b7171060c808", size = 847497, upload-time = "2025-08-03T05:04:16.967Z" }, - { url = "https://files.pythonhosted.org/packages/1e/df/3d1f4a03b561d824cbd491394f67591957e2f1acf6dc85d96f970312a76a/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1c363c6dc66352331d5ad64bb838765c6692766334a6a02fdb05e76bd408ae18", size = 1650028, upload-time = "2025-08-03T05:04:19.398Z" }, - { url = "https://files.pythonhosted.org/packages/41/c9/a3987540f59a412bdaae3f362f78e00e6769557a598c63b7e32956aade5a/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:87aebf4acd7249bdff8d3df03aed4f09e67078e6762cfe0aecf8d0748ff94cde", size = 2023808, upload-time = "2025-08-03T05:04:21.145Z" }, - { url = "https://files.pythonhosted.org/packages/b0/a5/c388f4cd80498a8eaef7535f2a8eaca0a35b82b87a0b47fa1856fc135004/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e4f22d67756518d71901edf73b38dc0eb4765cce22c8fe122cc81748d425262b", size = 1884970, upload-time = "2025-08-03T05:04:22.908Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ac/b2a89a1ed90526a1b9a260cdc5cd42f055fd44ee8d2a59902b5ac35ddeb1/pyzmq-27.0.1-cp314-cp314t-win32.whl", hash = "sha256:8c62297bc7aea2147b472ca5ca2b4389377ad82898c87cabab2a94aedd75e337", size = 586905, upload-time = "2025-08-03T05:04:24.492Z" }, - { url = "https://files.pythonhosted.org/packages/68/62/7aa5ea04e836f7a788b2a67405f83011cef59ca76d7bac91d1fc9a0476da/pyzmq-27.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:bee5248d5ec9223545f8cc4f368c2d571477ae828c99409125c3911511d98245", size = 660503, upload-time = "2025-08-03T05:04:26.382Z" }, - { url = "https://files.pythonhosted.org/packages/89/32/3836ed85947b06f1d67c07ce16c00b0cf8c053ab0b249d234f9f81ff95ff/pyzmq-27.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0fc24bf45e4a454e55ef99d7f5c8b8712539200ce98533af25a5bfa954b6b390", size = 575098, upload-time = "2025-08-03T05:04:27.974Z" }, - { url = "https://files.pythonhosted.org/packages/b4/1a/49f66fe0bc2b2568dd4280f1f520ac8fafd73f8d762140e278d48aeaf7b9/pyzmq-27.0.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7fb0ee35845bef1e8c4a152d766242164e138c239e3182f558ae15cb4a891f94", size = 835949, upload-time = "2025-08-03T05:05:13.798Z" }, - { url = "https://files.pythonhosted.org/packages/49/94/443c1984b397eab59b14dd7ae8bc2ac7e8f32dbc646474453afcaa6508c4/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f379f11e138dfd56c3f24a04164f871a08281194dd9ddf656a278d7d080c8ad0", size = 799875, upload-time = "2025-08-03T05:05:15.632Z" }, - { url = "https://files.pythonhosted.org/packages/30/f1/fd96138a0f152786a2ba517e9c6a8b1b3516719e412a90bb5d8eea6b660c/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b978c0678cffbe8860ec9edc91200e895c29ae1ac8a7085f947f8e8864c489fb", size = 567403, upload-time = "2025-08-03T05:05:17.326Z" }, - { url = "https://files.pythonhosted.org/packages/16/57/34e53ef2b55b1428dac5aabe3a974a16c8bda3bf20549ba500e3ff6cb426/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ebccf0d760bc92a4a7c751aeb2fef6626144aace76ee8f5a63abeb100cae87f", size = 747032, upload-time = "2025-08-03T05:05:19.074Z" }, - { url = "https://files.pythonhosted.org/packages/81/b7/769598c5ae336fdb657946950465569cf18803140fe89ce466d7f0a57c11/pyzmq-27.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:77fed80e30fa65708546c4119840a46691290efc231f6bfb2ac2a39b52e15811", size = 544566, upload-time = "2025-08-03T05:05:20.798Z" }, + { url = "https://files.pythonhosted.org/packages/ae/18/a8e0da6ababbe9326116fb1c890bf1920eea880e8da621afb6bc0f39a262/pyzmq-27.0.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9729190bd770314f5fbba42476abf6abe79a746eeda11d1d68fd56dd70e5c296", size = 1332721, upload_time = "2025-08-03T05:03:15.237Z" }, + { url = "https://files.pythonhosted.org/packages/75/a4/9431ba598651d60ebd50dc25755402b770322cf8432adcc07d2906e53a54/pyzmq-27.0.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:696900ef6bc20bef6a242973943574f96c3f97d2183c1bd3da5eea4f559631b1", size = 908249, upload_time = "2025-08-03T05:03:16.933Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/e624e1793689e4e685d2ee21c40277dd4024d9d730af20446d88f69be838/pyzmq-27.0.1-cp311-cp311-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f96a63aecec22d3f7fdea3c6c98df9e42973f5856bb6812c3d8d78c262fee808", size = 668649, upload_time = "2025-08-03T05:03:18.49Z" }, + { url = "https://files.pythonhosted.org/packages/6c/29/0652a39d4e876e0d61379047ecf7752685414ad2e253434348246f7a2a39/pyzmq-27.0.1-cp311-cp311-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c512824360ea7490390566ce00bee880e19b526b312b25cc0bc30a0fe95cb67f", size = 856601, upload_time = "2025-08-03T05:03:20.194Z" }, + { url = "https://files.pythonhosted.org/packages/36/2d/8d5355d7fc55bb6e9c581dd74f58b64fa78c994079e3a0ea09b1b5627cde/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dfb2bb5e0f7198eaacfb6796fb0330afd28f36d985a770745fba554a5903595a", size = 1657750, upload_time = "2025-08-03T05:03:22.055Z" }, + { url = "https://files.pythonhosted.org/packages/ab/f4/cd032352d5d252dc6f5ee272a34b59718ba3af1639a8a4ef4654f9535cf5/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4f6886c59ba93ffde09b957d3e857e7950c8fe818bd5494d9b4287bc6d5bc7f1", size = 2034312, upload_time = "2025-08-03T05:03:23.578Z" }, + { url = "https://files.pythonhosted.org/packages/e4/1a/c050d8b6597200e97a4bd29b93c769d002fa0b03083858227e0376ad59bc/pyzmq-27.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b99ea9d330e86ce1ff7f2456b33f1bf81c43862a5590faf4ef4ed3a63504bdab", size = 1893632, upload_time = "2025-08-03T05:03:25.167Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/173ce21d5097e7fcf284a090e8beb64fc683c6582b1f00fa52b1b7e867ce/pyzmq-27.0.1-cp311-cp311-win32.whl", hash = "sha256:571f762aed89025ba8cdcbe355fea56889715ec06d0264fd8b6a3f3fa38154ed", size = 566587, upload_time = "2025-08-03T05:03:26.769Z" }, + { url = "https://files.pythonhosted.org/packages/53/ab/22bd33e7086f0a2cc03a5adabff4bde414288bb62a21a7820951ef86ec20/pyzmq-27.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:ee16906c8025fa464bea1e48128c048d02359fb40bebe5333103228528506530", size = 632873, upload_time = "2025-08-03T05:03:28.685Z" }, + { url = "https://files.pythonhosted.org/packages/90/14/3e59b4a28194285ceeff725eba9aa5ba8568d1cb78aed381dec1537c705a/pyzmq-27.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:ba068f28028849da725ff9185c24f832ccf9207a40f9b28ac46ab7c04994bd41", size = 558918, upload_time = "2025-08-03T05:03:30.085Z" }, + { url = "https://files.pythonhosted.org/packages/0e/9b/c0957041067c7724b310f22c398be46399297c12ed834c3bc42200a2756f/pyzmq-27.0.1-cp312-abi3-macosx_10_15_universal2.whl", hash = "sha256:af7ebce2a1e7caf30c0bb64a845f63a69e76a2fadbc1cac47178f7bb6e657bdd", size = 1305432, upload_time = "2025-08-03T05:03:32.177Z" }, + { url = "https://files.pythonhosted.org/packages/8e/55/bd3a312790858f16b7def3897a0c3eb1804e974711bf7b9dcb5f47e7f82c/pyzmq-27.0.1-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:8f617f60a8b609a13099b313e7e525e67f84ef4524b6acad396d9ff153f6e4cd", size = 895095, upload_time = "2025-08-03T05:03:33.918Z" }, + { url = "https://files.pythonhosted.org/packages/20/50/fc384631d8282809fb1029a4460d2fe90fa0370a0e866a8318ed75c8d3bb/pyzmq-27.0.1-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d59dad4173dc2a111f03e59315c7bd6e73da1a9d20a84a25cf08325b0582b1a", size = 651826, upload_time = "2025-08-03T05:03:35.818Z" }, + { url = "https://files.pythonhosted.org/packages/7e/0a/2356305c423a975000867de56888b79e44ec2192c690ff93c3109fd78081/pyzmq-27.0.1-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f5b6133c8d313bde8bd0d123c169d22525300ff164c2189f849de495e1344577", size = 839751, upload_time = "2025-08-03T05:03:37.265Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1b/81e95ad256ca7e7ccd47f5294c1c6da6e2b64fbace65b84fe8a41470342e/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:58cca552567423f04d06a075f4b473e78ab5bdb906febe56bf4797633f54aa4e", size = 1641359, upload_time = "2025-08-03T05:03:38.799Z" }, + { url = "https://files.pythonhosted.org/packages/50/63/9f50ec965285f4e92c265c8f18344e46b12803666d8b73b65d254d441435/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:4b9d8e26fb600d0d69cc9933e20af08552e97cc868a183d38a5c0d661e40dfbb", size = 2020281, upload_time = "2025-08-03T05:03:40.338Z" }, + { url = "https://files.pythonhosted.org/packages/02/4a/19e3398d0dc66ad2b463e4afa1fc541d697d7bc090305f9dfb948d3dfa29/pyzmq-27.0.1-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2329f0c87f0466dce45bba32b63f47018dda5ca40a0085cc5c8558fea7d9fc55", size = 1877112, upload_time = "2025-08-03T05:03:42.012Z" }, + { url = "https://files.pythonhosted.org/packages/bf/42/c562e9151aa90ed1d70aac381ea22a929d6b3a2ce4e1d6e2e135d34fd9c6/pyzmq-27.0.1-cp312-abi3-win32.whl", hash = "sha256:57bb92abdb48467b89c2d21da1ab01a07d0745e536d62afd2e30d5acbd0092eb", size = 558177, upload_time = "2025-08-03T05:03:43.979Z" }, + { url = "https://files.pythonhosted.org/packages/40/96/5c50a7d2d2b05b19994bf7336b97db254299353dd9b49b565bb71b485f03/pyzmq-27.0.1-cp312-abi3-win_amd64.whl", hash = "sha256:ff3f8757570e45da7a5bedaa140489846510014f7a9d5ee9301c61f3f1b8a686", size = 618923, upload_time = "2025-08-03T05:03:45.438Z" }, + { url = "https://files.pythonhosted.org/packages/13/33/1ec89c8f21c89d21a2eaff7def3676e21d8248d2675705e72554fb5a6f3f/pyzmq-27.0.1-cp312-abi3-win_arm64.whl", hash = "sha256:df2c55c958d3766bdb3e9d858b911288acec09a9aab15883f384fc7180df5bed", size = 552358, upload_time = "2025-08-03T05:03:46.887Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/f26e276211ec8090a4d11e4ec70eb8a8b15781e591c1d44ce62f372963a0/pyzmq-27.0.1-cp313-cp313-android_24_arm64_v8a.whl", hash = "sha256:497bd8af534ae55dc4ef67eebd1c149ff2a0b0f1e146db73c8b5a53d83c1a5f5", size = 1122287, upload_time = "2025-08-03T05:03:48.838Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d8/af4b507e4f7eeea478cc8ee873995a6fd55582bfb99140593ed460e1db3c/pyzmq-27.0.1-cp313-cp313-android_24_x86_64.whl", hash = "sha256:a066ea6ad6218b4c233906adf0ae67830f451ed238419c0db609310dd781fbe7", size = 1155756, upload_time = "2025-08-03T05:03:50.907Z" }, + { url = "https://files.pythonhosted.org/packages/ac/55/37fae0013e11f88681da42698e550b08a316d608242551f65095cc99232a/pyzmq-27.0.1-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:72d235d6365ca73d8ce92f7425065d70f5c1e19baa458eb3f0d570e425b73a96", size = 1340826, upload_time = "2025-08-03T05:03:52.568Z" }, + { url = "https://files.pythonhosted.org/packages/f2/e4/3a87854c64b26fcf63a9d1b6f4382bd727d4797c772ceb334a97b7489be9/pyzmq-27.0.1-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:313a7b374e3dc64848644ca348a51004b41726f768b02e17e689f1322366a4d9", size = 897283, upload_time = "2025-08-03T05:03:54.167Z" }, + { url = "https://files.pythonhosted.org/packages/17/3e/4296c6b0ad2d07be11ae1395dccf9cae48a0a655cf9be1c3733ad2b591d1/pyzmq-27.0.1-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:119ce8590409702394f959c159d048002cbed2f3c0645ec9d6a88087fc70f0f1", size = 660565, upload_time = "2025-08-03T05:03:56.152Z" }, + { url = "https://files.pythonhosted.org/packages/72/41/a33ba3aa48b45b23c4cd4ac49aafde46f3e0f81939f2bfb3b6171a437122/pyzmq-27.0.1-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:45c3e00ce16896ace2cd770ab9057a7cf97d4613ea5f2a13f815141d8b6894b9", size = 847680, upload_time = "2025-08-03T05:03:57.696Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8c/bf2350bb25b3b58d2e5b5d2290ffab0e923f0cc6d02288d3fbf4baa6e4d1/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:678e50ec112bdc6df5a83ac259a55a4ba97a8b314c325ab26b3b5b071151bc61", size = 1650151, upload_time = "2025-08-03T05:03:59.387Z" }, + { url = "https://files.pythonhosted.org/packages/f7/1a/a5a07c54890891344a8ddc3d5ab320dd3c4e39febb6e4472546e456d5157/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d0b96c30be9f9387b18b18b6133c75a7b1b0065da64e150fe1feb5ebf31ece1c", size = 2023766, upload_time = "2025-08-03T05:04:01.883Z" }, + { url = "https://files.pythonhosted.org/packages/62/5e/514dcff08f02c6c8a45a6e23621901139cf853be7ac5ccd0b9407c3aa3de/pyzmq-27.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88dc92d9eb5ea4968123e74db146d770b0c8d48f0e2bfb1dbc6c50a8edb12d64", size = 1885195, upload_time = "2025-08-03T05:04:03.923Z" }, + { url = "https://files.pythonhosted.org/packages/c8/91/87f74f98a487fbef0b115f6025e4a295129fd56b2b633a03ba7d5816ecc2/pyzmq-27.0.1-cp313-cp313t-win32.whl", hash = "sha256:6dcbcb34f5c9b0cefdfc71ff745459241b7d3cda5b27c7ad69d45afc0821d1e1", size = 574213, upload_time = "2025-08-03T05:04:05.905Z" }, + { url = "https://files.pythonhosted.org/packages/e6/d7/07f7d0d7f4c81e08be7b60e52ff2591c557377c017f96204d33d5fca1b07/pyzmq-27.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9fd0fda730461f510cfd9a40fafa5355d65f5e3dbdd8d6dfa342b5b3f5d1949", size = 640202, upload_time = "2025-08-03T05:04:07.439Z" }, + { url = "https://files.pythonhosted.org/packages/ab/83/21d66bcef6fb803647a223cbde95111b099e2176277c0cbc8b099c485510/pyzmq-27.0.1-cp313-cp313t-win_arm64.whl", hash = "sha256:56a3b1853f3954ec1f0e91085f1350cc57d18f11205e4ab6e83e4b7c414120e0", size = 561514, upload_time = "2025-08-03T05:04:09.071Z" }, + { url = "https://files.pythonhosted.org/packages/5a/0b/d5ea75cf46b52cdce85a85200c963cb498932953df443892238be49b1a01/pyzmq-27.0.1-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:f98f6b7787bd2beb1f0dde03f23a0621a0c978edf673b7d8f5e7bc039cbe1b60", size = 1340836, upload_time = "2025-08-03T05:04:10.774Z" }, + { url = "https://files.pythonhosted.org/packages/be/4c/0dbce882550e17db6846b29e9dc242aea7590e7594e1ca5043e8e58fff2d/pyzmq-27.0.1-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:351bf5d8ca0788ca85327fda45843b6927593ff4c807faee368cc5aaf9f809c2", size = 897236, upload_time = "2025-08-03T05:04:13.221Z" }, + { url = "https://files.pythonhosted.org/packages/1b/22/461e131cf16b8814f3c356fa1ea0912697dbc4c64cddf01f7756ec704c1e/pyzmq-27.0.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5268a5a9177afff53dc6d70dffe63114ba2a6e7b20d9411cc3adeba09eeda403", size = 660374, upload_time = "2025-08-03T05:04:15.032Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0c/bbd65a814395bf4fc3e57c6c13af27601c07e4009bdfb75ebcf500537bbd/pyzmq-27.0.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4aca06ba295aa78bec9b33ec028d1ca08744c36294338c41432b7171060c808", size = 847497, upload_time = "2025-08-03T05:04:16.967Z" }, + { url = "https://files.pythonhosted.org/packages/1e/df/3d1f4a03b561d824cbd491394f67591957e2f1acf6dc85d96f970312a76a/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1c363c6dc66352331d5ad64bb838765c6692766334a6a02fdb05e76bd408ae18", size = 1650028, upload_time = "2025-08-03T05:04:19.398Z" }, + { url = "https://files.pythonhosted.org/packages/41/c9/a3987540f59a412bdaae3f362f78e00e6769557a598c63b7e32956aade5a/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:87aebf4acd7249bdff8d3df03aed4f09e67078e6762cfe0aecf8d0748ff94cde", size = 2023808, upload_time = "2025-08-03T05:04:21.145Z" }, + { url = "https://files.pythonhosted.org/packages/b0/a5/c388f4cd80498a8eaef7535f2a8eaca0a35b82b87a0b47fa1856fc135004/pyzmq-27.0.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e4f22d67756518d71901edf73b38dc0eb4765cce22c8fe122cc81748d425262b", size = 1884970, upload_time = "2025-08-03T05:04:22.908Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ac/b2a89a1ed90526a1b9a260cdc5cd42f055fd44ee8d2a59902b5ac35ddeb1/pyzmq-27.0.1-cp314-cp314t-win32.whl", hash = "sha256:8c62297bc7aea2147b472ca5ca2b4389377ad82898c87cabab2a94aedd75e337", size = 586905, upload_time = "2025-08-03T05:04:24.492Z" }, + { url = "https://files.pythonhosted.org/packages/68/62/7aa5ea04e836f7a788b2a67405f83011cef59ca76d7bac91d1fc9a0476da/pyzmq-27.0.1-cp314-cp314t-win_amd64.whl", hash = "sha256:bee5248d5ec9223545f8cc4f368c2d571477ae828c99409125c3911511d98245", size = 660503, upload_time = "2025-08-03T05:04:26.382Z" }, + { url = "https://files.pythonhosted.org/packages/89/32/3836ed85947b06f1d67c07ce16c00b0cf8c053ab0b249d234f9f81ff95ff/pyzmq-27.0.1-cp314-cp314t-win_arm64.whl", hash = "sha256:0fc24bf45e4a454e55ef99d7f5c8b8712539200ce98533af25a5bfa954b6b390", size = 575098, upload_time = "2025-08-03T05:04:27.974Z" }, + { url = "https://files.pythonhosted.org/packages/b4/1a/49f66fe0bc2b2568dd4280f1f520ac8fafd73f8d762140e278d48aeaf7b9/pyzmq-27.0.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7fb0ee35845bef1e8c4a152d766242164e138c239e3182f558ae15cb4a891f94", size = 835949, upload_time = "2025-08-03T05:05:13.798Z" }, + { url = "https://files.pythonhosted.org/packages/49/94/443c1984b397eab59b14dd7ae8bc2ac7e8f32dbc646474453afcaa6508c4/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f379f11e138dfd56c3f24a04164f871a08281194dd9ddf656a278d7d080c8ad0", size = 799875, upload_time = "2025-08-03T05:05:15.632Z" }, + { url = "https://files.pythonhosted.org/packages/30/f1/fd96138a0f152786a2ba517e9c6a8b1b3516719e412a90bb5d8eea6b660c/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b978c0678cffbe8860ec9edc91200e895c29ae1ac8a7085f947f8e8864c489fb", size = 567403, upload_time = "2025-08-03T05:05:17.326Z" }, + { url = "https://files.pythonhosted.org/packages/16/57/34e53ef2b55b1428dac5aabe3a974a16c8bda3bf20549ba500e3ff6cb426/pyzmq-27.0.1-pp311-pypy311_pp73-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ebccf0d760bc92a4a7c751aeb2fef6626144aace76ee8f5a63abeb100cae87f", size = 747032, upload_time = "2025-08-03T05:05:19.074Z" }, + { url = "https://files.pythonhosted.org/packages/81/b7/769598c5ae336fdb657946950465569cf18803140fe89ce466d7f0a57c11/pyzmq-27.0.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:77fed80e30fa65708546c4119840a46691290efc231f6bfb2ac2a39b52e15811", size = 544566, upload_time = "2025-08-03T05:05:20.798Z" }, ] [[package]] @@ -1823,9 +1827,9 @@ dependencies = [ { name = "rpds-py" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload_time = "2025-01-25T08:48:16.138Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload_time = "2025-01-25T08:48:14.241Z" }, ] [[package]] @@ -1838,9 +1842,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload-time = "2025-06-09T16:43:07.34Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e1/0a/929373653770d8a0d7ea76c37de6e41f11eb07559b103b1c02cafb3f7cf8/requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422", size = 135258, upload_time = "2025-06-09T16:43:07.34Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload_time = "2025-06-09T16:43:05.728Z" }, ] [[package]] @@ -1850,18 +1854,18 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload_time = "2021-05-12T16:37:54.178Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload_time = "2021-05-12T16:37:52.536Z" }, ] [[package]] name = "rfc3986-validator" version = "0.1.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload_time = "2019-10-28T16:00:19.144Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload_time = "2019-10-28T16:00:13.976Z" }, ] [[package]] @@ -1871,162 +1875,162 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "lark" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload_time = "2025-07-18T01:05:05.015Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload_time = "2025-07-18T01:05:03.843Z" }, ] [[package]] name = "rpds-py" version = "0.27.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/d9/991a0dee12d9fc53ed027e26a26a64b151d77252ac477e22666b9688bc16/rpds_py-0.27.0.tar.gz", hash = "sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f", size = 27420, upload-time = "2025-08-07T08:26:39.624Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/d9/991a0dee12d9fc53ed027e26a26a64b151d77252ac477e22666b9688bc16/rpds_py-0.27.0.tar.gz", hash = "sha256:8b23cf252f180cda89220b378d917180f29d313cd6a07b2431c0d3b776aae86f", size = 27420, upload_time = "2025-08-07T08:26:39.624Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/c1/49d515434c1752e40f5e35b985260cf27af052593378580a2f139a5be6b8/rpds_py-0.27.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622", size = 371577, upload-time = "2025-08-07T08:23:25.379Z" }, - { url = "https://files.pythonhosted.org/packages/e1/6d/bf2715b2fee5087fa13b752b5fd573f1a93e4134c74d275f709e38e54fe7/rpds_py-0.27.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5", size = 354959, upload-time = "2025-08-07T08:23:26.767Z" }, - { url = "https://files.pythonhosted.org/packages/a3/5c/e7762808c746dd19733a81373c10da43926f6a6adcf4920a21119697a60a/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4", size = 381485, upload-time = "2025-08-07T08:23:27.869Z" }, - { url = "https://files.pythonhosted.org/packages/40/51/0d308eb0b558309ca0598bcba4243f52c4cd20e15fe991b5bd75824f2e61/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f", size = 396816, upload-time = "2025-08-07T08:23:29.424Z" }, - { url = "https://files.pythonhosted.org/packages/5c/aa/2d585ec911d78f66458b2c91252134ca0c7c70f687a72c87283173dc0c96/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e", size = 514950, upload-time = "2025-08-07T08:23:30.576Z" }, - { url = "https://files.pythonhosted.org/packages/0b/ef/aced551cc1148179557aed84343073adadf252c91265263ee6203458a186/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1", size = 402132, upload-time = "2025-08-07T08:23:32.428Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ac/cf644803d8d417653fe2b3604186861d62ea6afaef1b2284045741baef17/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc", size = 383660, upload-time = "2025-08-07T08:23:33.829Z" }, - { url = "https://files.pythonhosted.org/packages/c9/ec/caf47c55ce02b76cbaeeb2d3b36a73da9ca2e14324e3d75cf72b59dcdac5/rpds_py-0.27.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85", size = 401730, upload-time = "2025-08-07T08:23:34.97Z" }, - { url = "https://files.pythonhosted.org/packages/0b/71/c1f355afdcd5b99ffc253422aa4bdcb04ccf1491dcd1bda3688a0c07fd61/rpds_py-0.27.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171", size = 416122, upload-time = "2025-08-07T08:23:36.062Z" }, - { url = "https://files.pythonhosted.org/packages/38/0f/f4b5b1eda724ed0e04d2b26d8911cdc131451a7ee4c4c020a1387e5c6ded/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d", size = 558771, upload-time = "2025-08-07T08:23:37.478Z" }, - { url = "https://files.pythonhosted.org/packages/93/c0/5f8b834db2289ab48d5cffbecbb75e35410103a77ac0b8da36bf9544ec1c/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626", size = 587876, upload-time = "2025-08-07T08:23:38.662Z" }, - { url = "https://files.pythonhosted.org/packages/d2/dd/1a1df02ab8eb970115cff2ae31a6f73916609b900dc86961dc382b8c2e5e/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e", size = 554359, upload-time = "2025-08-07T08:23:39.897Z" }, - { url = "https://files.pythonhosted.org/packages/a1/e4/95a014ab0d51ab6e3bebbdb476a42d992d2bbf9c489d24cff9fda998e925/rpds_py-0.27.0-cp311-cp311-win32.whl", hash = "sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7", size = 218084, upload-time = "2025-08-07T08:23:41.086Z" }, - { url = "https://files.pythonhosted.org/packages/49/78/f8d5b71ec65a0376b0de31efcbb5528ce17a9b7fdd19c3763303ccfdedec/rpds_py-0.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261", size = 230085, upload-time = "2025-08-07T08:23:42.143Z" }, - { url = "https://files.pythonhosted.org/packages/e7/d3/84429745184091e06b4cc70f8597408e314c2d2f7f5e13249af9ffab9e3d/rpds_py-0.27.0-cp311-cp311-win_arm64.whl", hash = "sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0", size = 222112, upload-time = "2025-08-07T08:23:43.233Z" }, - { url = "https://files.pythonhosted.org/packages/cd/17/e67309ca1ac993fa1888a0d9b2f5ccc1f67196ace32e76c9f8e1dbbbd50c/rpds_py-0.27.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4", size = 362611, upload-time = "2025-08-07T08:23:44.773Z" }, - { url = "https://files.pythonhosted.org/packages/93/2e/28c2fb84aa7aa5d75933d1862d0f7de6198ea22dfd9a0cca06e8a4e7509e/rpds_py-0.27.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b", size = 347680, upload-time = "2025-08-07T08:23:46.014Z" }, - { url = "https://files.pythonhosted.org/packages/44/3e/9834b4c8f4f5fe936b479e623832468aa4bd6beb8d014fecaee9eac6cdb1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e", size = 384600, upload-time = "2025-08-07T08:23:48Z" }, - { url = "https://files.pythonhosted.org/packages/19/78/744123c7b38865a965cd9e6f691fde7ef989a00a256fa8bf15b75240d12f/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34", size = 400697, upload-time = "2025-08-07T08:23:49.407Z" }, - { url = "https://files.pythonhosted.org/packages/32/97/3c3d32fe7daee0a1f1a678b6d4dfb8c4dcf88197fa2441f9da7cb54a8466/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8", size = 517781, upload-time = "2025-08-07T08:23:50.557Z" }, - { url = "https://files.pythonhosted.org/packages/b2/be/28f0e3e733680aa13ecec1212fc0f585928a206292f14f89c0b8a684cad1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726", size = 406449, upload-time = "2025-08-07T08:23:51.732Z" }, - { url = "https://files.pythonhosted.org/packages/95/ae/5d15c83e337c082d0367053baeb40bfba683f42459f6ebff63a2fd7e5518/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e", size = 386150, upload-time = "2025-08-07T08:23:52.822Z" }, - { url = "https://files.pythonhosted.org/packages/bf/65/944e95f95d5931112829e040912b25a77b2e7ed913ea5fe5746aa5c1ce75/rpds_py-0.27.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3", size = 406100, upload-time = "2025-08-07T08:23:54.339Z" }, - { url = "https://files.pythonhosted.org/packages/21/a4/1664b83fae02894533cd11dc0b9f91d673797c2185b7be0f7496107ed6c5/rpds_py-0.27.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e", size = 421345, upload-time = "2025-08-07T08:23:55.832Z" }, - { url = "https://files.pythonhosted.org/packages/7c/26/b7303941c2b0823bfb34c71378249f8beedce57301f400acb04bb345d025/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f", size = 561891, upload-time = "2025-08-07T08:23:56.951Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c8/48623d64d4a5a028fa99576c768a6159db49ab907230edddc0b8468b998b/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03", size = 591756, upload-time = "2025-08-07T08:23:58.146Z" }, - { url = "https://files.pythonhosted.org/packages/b3/51/18f62617e8e61cc66334c9fb44b1ad7baae3438662098efbc55fb3fda453/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374", size = 557088, upload-time = "2025-08-07T08:23:59.6Z" }, - { url = "https://files.pythonhosted.org/packages/bd/4c/e84c3a276e2496a93d245516be6b49e20499aa8ca1c94d59fada0d79addc/rpds_py-0.27.0-cp312-cp312-win32.whl", hash = "sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97", size = 221926, upload-time = "2025-08-07T08:24:00.695Z" }, - { url = "https://files.pythonhosted.org/packages/83/89/9d0fbcef64340db0605eb0a0044f258076f3ae0a3b108983b2c614d96212/rpds_py-0.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5", size = 233235, upload-time = "2025-08-07T08:24:01.846Z" }, - { url = "https://files.pythonhosted.org/packages/c9/b0/e177aa9f39cbab060f96de4a09df77d494f0279604dc2f509263e21b05f9/rpds_py-0.27.0-cp312-cp312-win_arm64.whl", hash = "sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9", size = 223315, upload-time = "2025-08-07T08:24:03.337Z" }, - { url = "https://files.pythonhosted.org/packages/81/d2/dfdfd42565a923b9e5a29f93501664f5b984a802967d48d49200ad71be36/rpds_py-0.27.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff", size = 362133, upload-time = "2025-08-07T08:24:04.508Z" }, - { url = "https://files.pythonhosted.org/packages/ac/4a/0a2e2460c4b66021d349ce9f6331df1d6c75d7eea90df9785d333a49df04/rpds_py-0.27.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367", size = 347128, upload-time = "2025-08-07T08:24:05.695Z" }, - { url = "https://files.pythonhosted.org/packages/35/8d/7d1e4390dfe09d4213b3175a3f5a817514355cb3524593380733204f20b9/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185", size = 384027, upload-time = "2025-08-07T08:24:06.841Z" }, - { url = "https://files.pythonhosted.org/packages/c1/65/78499d1a62172891c8cd45de737b2a4b84a414b6ad8315ab3ac4945a5b61/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc", size = 399973, upload-time = "2025-08-07T08:24:08.143Z" }, - { url = "https://files.pythonhosted.org/packages/10/a1/1c67c1d8cc889107b19570bb01f75cf49852068e95e6aee80d22915406fc/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe", size = 515295, upload-time = "2025-08-07T08:24:09.711Z" }, - { url = "https://files.pythonhosted.org/packages/df/27/700ec88e748436b6c7c4a2262d66e80f8c21ab585d5e98c45e02f13f21c0/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9", size = 406737, upload-time = "2025-08-07T08:24:11.182Z" }, - { url = "https://files.pythonhosted.org/packages/33/cc/6b0ee8f0ba3f2df2daac1beda17fde5cf10897a7d466f252bd184ef20162/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c", size = 385898, upload-time = "2025-08-07T08:24:12.798Z" }, - { url = "https://files.pythonhosted.org/packages/e8/7e/c927b37d7d33c0a0ebf249cc268dc2fcec52864c1b6309ecb960497f2285/rpds_py-0.27.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295", size = 405785, upload-time = "2025-08-07T08:24:14.906Z" }, - { url = "https://files.pythonhosted.org/packages/5b/d2/8ed50746d909dcf402af3fa58b83d5a590ed43e07251d6b08fad1a535ba6/rpds_py-0.27.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43", size = 419760, upload-time = "2025-08-07T08:24:16.129Z" }, - { url = "https://files.pythonhosted.org/packages/d3/60/2b2071aee781cb3bd49f94d5d35686990b925e9b9f3e3d149235a6f5d5c1/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432", size = 561201, upload-time = "2025-08-07T08:24:17.645Z" }, - { url = "https://files.pythonhosted.org/packages/98/1f/27b67304272521aaea02be293fecedce13fa351a4e41cdb9290576fc6d81/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b", size = 591021, upload-time = "2025-08-07T08:24:18.999Z" }, - { url = "https://files.pythonhosted.org/packages/db/9b/a2fadf823164dd085b1f894be6443b0762a54a7af6f36e98e8fcda69ee50/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d", size = 556368, upload-time = "2025-08-07T08:24:20.54Z" }, - { url = "https://files.pythonhosted.org/packages/24/f3/6d135d46a129cda2e3e6d4c5e91e2cc26ea0428c6cf152763f3f10b6dd05/rpds_py-0.27.0-cp313-cp313-win32.whl", hash = "sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd", size = 221236, upload-time = "2025-08-07T08:24:22.144Z" }, - { url = "https://files.pythonhosted.org/packages/c5/44/65d7494f5448ecc755b545d78b188440f81da98b50ea0447ab5ebfdf9bd6/rpds_py-0.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2", size = 232634, upload-time = "2025-08-07T08:24:23.642Z" }, - { url = "https://files.pythonhosted.org/packages/70/d9/23852410fadab2abb611733933401de42a1964ce6600a3badae35fbd573e/rpds_py-0.27.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac", size = 222783, upload-time = "2025-08-07T08:24:25.098Z" }, - { url = "https://files.pythonhosted.org/packages/15/75/03447917f78512b34463f4ef11066516067099a0c466545655503bed0c77/rpds_py-0.27.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774", size = 359154, upload-time = "2025-08-07T08:24:26.249Z" }, - { url = "https://files.pythonhosted.org/packages/6b/fc/4dac4fa756451f2122ddaf136e2c6aeb758dc6fdbe9ccc4bc95c98451d50/rpds_py-0.27.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b", size = 343909, upload-time = "2025-08-07T08:24:27.405Z" }, - { url = "https://files.pythonhosted.org/packages/7b/81/723c1ed8e6f57ed9d8c0c07578747a2d3d554aaefc1ab89f4e42cfeefa07/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd", size = 379340, upload-time = "2025-08-07T08:24:28.714Z" }, - { url = "https://files.pythonhosted.org/packages/98/16/7e3740413de71818ce1997df82ba5f94bae9fff90c0a578c0e24658e6201/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb", size = 391655, upload-time = "2025-08-07T08:24:30.223Z" }, - { url = "https://files.pythonhosted.org/packages/e0/63/2a9f510e124d80660f60ecce07953f3f2d5f0b96192c1365443859b9c87f/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433", size = 513017, upload-time = "2025-08-07T08:24:31.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/4e/cf6ff311d09776c53ea1b4f2e6700b9d43bb4e99551006817ade4bbd6f78/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615", size = 402058, upload-time = "2025-08-07T08:24:32.613Z" }, - { url = "https://files.pythonhosted.org/packages/88/11/5e36096d474cb10f2a2d68b22af60a3bc4164fd8db15078769a568d9d3ac/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8", size = 383474, upload-time = "2025-08-07T08:24:33.767Z" }, - { url = "https://files.pythonhosted.org/packages/db/a2/3dff02805b06058760b5eaa6d8cb8db3eb3e46c9e452453ad5fc5b5ad9fe/rpds_py-0.27.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858", size = 400067, upload-time = "2025-08-07T08:24:35.021Z" }, - { url = "https://files.pythonhosted.org/packages/67/87/eed7369b0b265518e21ea836456a4ed4a6744c8c12422ce05bce760bb3cf/rpds_py-0.27.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5", size = 412085, upload-time = "2025-08-07T08:24:36.267Z" }, - { url = "https://files.pythonhosted.org/packages/8b/48/f50b2ab2fbb422fbb389fe296e70b7a6b5ea31b263ada5c61377e710a924/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9", size = 555928, upload-time = "2025-08-07T08:24:37.573Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/b18eb51045d06887666c3560cd4bbb6819127b43d758f5adb82b5f56f7d1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79", size = 585527, upload-time = "2025-08-07T08:24:39.391Z" }, - { url = "https://files.pythonhosted.org/packages/be/03/a3dd6470fc76499959b00ae56295b76b4bdf7c6ffc60d62006b1217567e1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c", size = 554211, upload-time = "2025-08-07T08:24:40.6Z" }, - { url = "https://files.pythonhosted.org/packages/bf/d1/ee5fd1be395a07423ac4ca0bcc05280bf95db2b155d03adefeb47d5ebf7e/rpds_py-0.27.0-cp313-cp313t-win32.whl", hash = "sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23", size = 216624, upload-time = "2025-08-07T08:24:42.204Z" }, - { url = "https://files.pythonhosted.org/packages/1c/94/4814c4c858833bf46706f87349c37ca45e154da7dbbec9ff09f1abeb08cc/rpds_py-0.27.0-cp313-cp313t-win_amd64.whl", hash = "sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1", size = 230007, upload-time = "2025-08-07T08:24:43.329Z" }, - { url = "https://files.pythonhosted.org/packages/0e/a5/8fffe1c7dc7c055aa02df310f9fb71cfc693a4d5ccc5de2d3456ea5fb022/rpds_py-0.27.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb", size = 362595, upload-time = "2025-08-07T08:24:44.478Z" }, - { url = "https://files.pythonhosted.org/packages/bc/c7/4e4253fd2d4bb0edbc0b0b10d9f280612ca4f0f990e3c04c599000fe7d71/rpds_py-0.27.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f", size = 347252, upload-time = "2025-08-07T08:24:45.678Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c8/3d1a954d30f0174dd6baf18b57c215da03cf7846a9d6e0143304e784cddc/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64", size = 384886, upload-time = "2025-08-07T08:24:46.86Z" }, - { url = "https://files.pythonhosted.org/packages/e0/52/3c5835f2df389832b28f9276dd5395b5a965cea34226e7c88c8fbec2093c/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015", size = 399716, upload-time = "2025-08-07T08:24:48.174Z" }, - { url = "https://files.pythonhosted.org/packages/40/73/176e46992461a1749686a2a441e24df51ff86b99c2d34bf39f2a5273b987/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0", size = 517030, upload-time = "2025-08-07T08:24:49.52Z" }, - { url = "https://files.pythonhosted.org/packages/79/2a/7266c75840e8c6e70effeb0d38922a45720904f2cd695e68a0150e5407e2/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89", size = 408448, upload-time = "2025-08-07T08:24:50.727Z" }, - { url = "https://files.pythonhosted.org/packages/e6/5f/a7efc572b8e235093dc6cf39f4dbc8a7f08e65fdbcec7ff4daeb3585eef1/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d", size = 387320, upload-time = "2025-08-07T08:24:52.004Z" }, - { url = "https://files.pythonhosted.org/packages/a2/eb/9ff6bc92efe57cf5a2cb74dee20453ba444b6fdc85275d8c99e0d27239d1/rpds_py-0.27.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51", size = 407414, upload-time = "2025-08-07T08:24:53.664Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bd/3b9b19b00d5c6e1bd0f418c229ab0f8d3b110ddf7ec5d9d689ef783d0268/rpds_py-0.27.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c", size = 420766, upload-time = "2025-08-07T08:24:55.917Z" }, - { url = "https://files.pythonhosted.org/packages/17/6b/521a7b1079ce16258c70805166e3ac6ec4ee2139d023fe07954dc9b2d568/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4", size = 562409, upload-time = "2025-08-07T08:24:57.17Z" }, - { url = "https://files.pythonhosted.org/packages/8b/bf/65db5bfb14ccc55e39de8419a659d05a2a9cd232f0a699a516bb0991da7b/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e", size = 590793, upload-time = "2025-08-07T08:24:58.388Z" }, - { url = "https://files.pythonhosted.org/packages/db/b8/82d368b378325191ba7aae8f40f009b78057b598d4394d1f2cdabaf67b3f/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e", size = 558178, upload-time = "2025-08-07T08:24:59.756Z" }, - { url = "https://files.pythonhosted.org/packages/f6/ff/f270bddbfbc3812500f8131b1ebbd97afd014cd554b604a3f73f03133a36/rpds_py-0.27.0-cp314-cp314-win32.whl", hash = "sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6", size = 222355, upload-time = "2025-08-07T08:25:01.027Z" }, - { url = "https://files.pythonhosted.org/packages/bf/20/fdab055b1460c02ed356a0e0b0a78c1dd32dc64e82a544f7b31c9ac643dc/rpds_py-0.27.0-cp314-cp314-win_amd64.whl", hash = "sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a", size = 234007, upload-time = "2025-08-07T08:25:02.268Z" }, - { url = "https://files.pythonhosted.org/packages/4d/a8/694c060005421797a3be4943dab8347c76c2b429a9bef68fb2c87c9e70c7/rpds_py-0.27.0-cp314-cp314-win_arm64.whl", hash = "sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d", size = 223527, upload-time = "2025-08-07T08:25:03.45Z" }, - { url = "https://files.pythonhosted.org/packages/1e/f9/77f4c90f79d2c5ca8ce6ec6a76cb4734ee247de6b3a4f337e289e1f00372/rpds_py-0.27.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828", size = 359469, upload-time = "2025-08-07T08:25:04.648Z" }, - { url = "https://files.pythonhosted.org/packages/c0/22/b97878d2f1284286fef4172069e84b0b42b546ea7d053e5fb7adb9ac6494/rpds_py-0.27.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669", size = 343960, upload-time = "2025-08-07T08:25:05.863Z" }, - { url = "https://files.pythonhosted.org/packages/b1/b0/dfd55b5bb480eda0578ae94ef256d3061d20b19a0f5e18c482f03e65464f/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd", size = 380201, upload-time = "2025-08-07T08:25:07.513Z" }, - { url = "https://files.pythonhosted.org/packages/28/22/e1fa64e50d58ad2b2053077e3ec81a979147c43428de9e6de68ddf6aff4e/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec", size = 392111, upload-time = "2025-08-07T08:25:09.149Z" }, - { url = "https://files.pythonhosted.org/packages/49/f9/43ab7a43e97aedf6cea6af70fdcbe18abbbc41d4ae6cdec1bfc23bbad403/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303", size = 515863, upload-time = "2025-08-07T08:25:10.431Z" }, - { url = "https://files.pythonhosted.org/packages/38/9b/9bd59dcc636cd04d86a2d20ad967770bf348f5eb5922a8f29b547c074243/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b", size = 402398, upload-time = "2025-08-07T08:25:11.819Z" }, - { url = "https://files.pythonhosted.org/packages/71/bf/f099328c6c85667aba6b66fa5c35a8882db06dcd462ea214be72813a0dd2/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410", size = 384665, upload-time = "2025-08-07T08:25:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c5/9c1f03121ece6634818490bd3c8be2c82a70928a19de03467fb25a3ae2a8/rpds_py-0.27.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156", size = 400405, upload-time = "2025-08-07T08:25:14.417Z" }, - { url = "https://files.pythonhosted.org/packages/b5/b8/e25d54af3e63ac94f0c16d8fe143779fe71ff209445a0c00d0f6984b6b2c/rpds_py-0.27.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2", size = 413179, upload-time = "2025-08-07T08:25:15.664Z" }, - { url = "https://files.pythonhosted.org/packages/f9/d1/406b3316433fe49c3021546293a04bc33f1478e3ec7950215a7fce1a1208/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1", size = 556895, upload-time = "2025-08-07T08:25:17.061Z" }, - { url = "https://files.pythonhosted.org/packages/5f/bc/3697c0c21fcb9a54d46ae3b735eb2365eea0c2be076b8f770f98e07998de/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42", size = 585464, upload-time = "2025-08-07T08:25:18.406Z" }, - { url = "https://files.pythonhosted.org/packages/63/09/ee1bb5536f99f42c839b177d552f6114aa3142d82f49cef49261ed28dbe0/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae", size = 555090, upload-time = "2025-08-07T08:25:20.461Z" }, - { url = "https://files.pythonhosted.org/packages/7d/2c/363eada9e89f7059199d3724135a86c47082cbf72790d6ba2f336d146ddb/rpds_py-0.27.0-cp314-cp314t-win32.whl", hash = "sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5", size = 218001, upload-time = "2025-08-07T08:25:21.761Z" }, - { url = "https://files.pythonhosted.org/packages/e2/3f/d6c216ed5199c9ef79e2a33955601f454ed1e7420a93b89670133bca5ace/rpds_py-0.27.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391", size = 230993, upload-time = "2025-08-07T08:25:23.34Z" }, - { url = "https://files.pythonhosted.org/packages/59/64/72ab5b911fdcc48058359b0e786e5363e3fde885156116026f1a2ba9a5b5/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089", size = 371658, upload-time = "2025-08-07T08:26:02.369Z" }, - { url = "https://files.pythonhosted.org/packages/6c/4b/90ff04b4da055db53d8fea57640d8d5d55456343a1ec9a866c0ecfe10fd1/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d", size = 355529, upload-time = "2025-08-07T08:26:03.83Z" }, - { url = "https://files.pythonhosted.org/packages/a4/be/527491fb1afcd86fc5ce5812eb37bc70428ee017d77fee20de18155c3937/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424", size = 382822, upload-time = "2025-08-07T08:26:05.52Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a5/dcdb8725ce11e6d0913e6fcf782a13f4b8a517e8acc70946031830b98441/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8", size = 397233, upload-time = "2025-08-07T08:26:07.179Z" }, - { url = "https://files.pythonhosted.org/packages/33/f9/0947920d1927e9f144660590cc38cadb0795d78fe0d9aae0ef71c1513b7c/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859", size = 514892, upload-time = "2025-08-07T08:26:08.622Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ed/d1343398c1417c68f8daa1afce56ef6ce5cc587daaf98e29347b00a80ff2/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5", size = 402733, upload-time = "2025-08-07T08:26:10.433Z" }, - { url = "https://files.pythonhosted.org/packages/1d/0b/646f55442cd14014fb64d143428f25667a100f82092c90087b9ea7101c74/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14", size = 384447, upload-time = "2025-08-07T08:26:11.847Z" }, - { url = "https://files.pythonhosted.org/packages/4b/15/0596ef7529828e33a6c81ecf5013d1dd33a511a3e0be0561f83079cda227/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c", size = 402502, upload-time = "2025-08-07T08:26:13.537Z" }, - { url = "https://files.pythonhosted.org/packages/c3/8d/986af3c42f8454a6cafff8729d99fb178ae9b08a9816325ac7a8fa57c0c0/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60", size = 416651, upload-time = "2025-08-07T08:26:14.923Z" }, - { url = "https://files.pythonhosted.org/packages/e9/9a/b4ec3629b7b447e896eec574469159b5b60b7781d3711c914748bf32de05/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be", size = 559460, upload-time = "2025-08-07T08:26:16.295Z" }, - { url = "https://files.pythonhosted.org/packages/61/63/d1e127b40c3e4733b3a6f26ae7a063cdf2bc1caa5272c89075425c7d397a/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114", size = 588072, upload-time = "2025-08-07T08:26:17.776Z" }, - { url = "https://files.pythonhosted.org/packages/04/7e/8ffc71a8f6833d9c9fb999f5b0ee736b8b159fd66968e05c7afc2dbcd57e/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466", size = 555083, upload-time = "2025-08-07T08:26:19.301Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/49d515434c1752e40f5e35b985260cf27af052593378580a2f139a5be6b8/rpds_py-0.27.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:dbc2ab5d10544eb485baa76c63c501303b716a5c405ff2469a1d8ceffaabf622", size = 371577, upload_time = "2025-08-07T08:23:25.379Z" }, + { url = "https://files.pythonhosted.org/packages/e1/6d/bf2715b2fee5087fa13b752b5fd573f1a93e4134c74d275f709e38e54fe7/rpds_py-0.27.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7ec85994f96a58cf7ed288caa344b7fe31fd1d503bdf13d7331ead5f70ab60d5", size = 354959, upload_time = "2025-08-07T08:23:26.767Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5c/e7762808c746dd19733a81373c10da43926f6a6adcf4920a21119697a60a/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:190d7285cd3bb6d31d37a0534d7359c1ee191eb194c511c301f32a4afa5a1dd4", size = 381485, upload_time = "2025-08-07T08:23:27.869Z" }, + { url = "https://files.pythonhosted.org/packages/40/51/0d308eb0b558309ca0598bcba4243f52c4cd20e15fe991b5bd75824f2e61/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c10d92fb6d7fd827e44055fcd932ad93dac6a11e832d51534d77b97d1d85400f", size = 396816, upload_time = "2025-08-07T08:23:29.424Z" }, + { url = "https://files.pythonhosted.org/packages/5c/aa/2d585ec911d78f66458b2c91252134ca0c7c70f687a72c87283173dc0c96/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd2c1d27ebfe6a015cfa2005b7fe8c52d5019f7bbdd801bc6f7499aab9ae739e", size = 514950, upload_time = "2025-08-07T08:23:30.576Z" }, + { url = "https://files.pythonhosted.org/packages/0b/ef/aced551cc1148179557aed84343073adadf252c91265263ee6203458a186/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4790c9d5dd565ddb3e9f656092f57268951398cef52e364c405ed3112dc7c7c1", size = 402132, upload_time = "2025-08-07T08:23:32.428Z" }, + { url = "https://files.pythonhosted.org/packages/4b/ac/cf644803d8d417653fe2b3604186861d62ea6afaef1b2284045741baef17/rpds_py-0.27.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4300e15e7d03660f04be84a125d1bdd0e6b2f674bc0723bc0fd0122f1a4585dc", size = 383660, upload_time = "2025-08-07T08:23:33.829Z" }, + { url = "https://files.pythonhosted.org/packages/c9/ec/caf47c55ce02b76cbaeeb2d3b36a73da9ca2e14324e3d75cf72b59dcdac5/rpds_py-0.27.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:59195dc244fc183209cf8a93406889cadde47dfd2f0a6b137783aa9c56d67c85", size = 401730, upload_time = "2025-08-07T08:23:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/0b/71/c1f355afdcd5b99ffc253422aa4bdcb04ccf1491dcd1bda3688a0c07fd61/rpds_py-0.27.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fae4a01ef8c4cb2bbe92ef2063149596907dc4a881a8d26743b3f6b304713171", size = 416122, upload_time = "2025-08-07T08:23:36.062Z" }, + { url = "https://files.pythonhosted.org/packages/38/0f/f4b5b1eda724ed0e04d2b26d8911cdc131451a7ee4c4c020a1387e5c6ded/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e3dc8d4ede2dbae6c0fc2b6c958bf51ce9fd7e9b40c0f5b8835c3fde44f5807d", size = 558771, upload_time = "2025-08-07T08:23:37.478Z" }, + { url = "https://files.pythonhosted.org/packages/93/c0/5f8b834db2289ab48d5cffbecbb75e35410103a77ac0b8da36bf9544ec1c/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c3782fb753aa825b4ccabc04292e07897e2fd941448eabf666856c5530277626", size = 587876, upload_time = "2025-08-07T08:23:38.662Z" }, + { url = "https://files.pythonhosted.org/packages/d2/dd/1a1df02ab8eb970115cff2ae31a6f73916609b900dc86961dc382b8c2e5e/rpds_py-0.27.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:887ab1f12b0d227e9260558a4a2320024b20102207ada65c43e1ffc4546df72e", size = 554359, upload_time = "2025-08-07T08:23:39.897Z" }, + { url = "https://files.pythonhosted.org/packages/a1/e4/95a014ab0d51ab6e3bebbdb476a42d992d2bbf9c489d24cff9fda998e925/rpds_py-0.27.0-cp311-cp311-win32.whl", hash = "sha256:5d6790ff400254137b81b8053b34417e2c46921e302d655181d55ea46df58cf7", size = 218084, upload_time = "2025-08-07T08:23:41.086Z" }, + { url = "https://files.pythonhosted.org/packages/49/78/f8d5b71ec65a0376b0de31efcbb5528ce17a9b7fdd19c3763303ccfdedec/rpds_py-0.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:e24d8031a2c62f34853756d9208eeafa6b940a1efcbfe36e8f57d99d52bb7261", size = 230085, upload_time = "2025-08-07T08:23:42.143Z" }, + { url = "https://files.pythonhosted.org/packages/e7/d3/84429745184091e06b4cc70f8597408e314c2d2f7f5e13249af9ffab9e3d/rpds_py-0.27.0-cp311-cp311-win_arm64.whl", hash = "sha256:08680820d23df1df0a0260f714d12966bc6c42d02e8055a91d61e03f0c47dda0", size = 222112, upload_time = "2025-08-07T08:23:43.233Z" }, + { url = "https://files.pythonhosted.org/packages/cd/17/e67309ca1ac993fa1888a0d9b2f5ccc1f67196ace32e76c9f8e1dbbbd50c/rpds_py-0.27.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:19c990fdf5acecbf0623e906ae2e09ce1c58947197f9bced6bbd7482662231c4", size = 362611, upload_time = "2025-08-07T08:23:44.773Z" }, + { url = "https://files.pythonhosted.org/packages/93/2e/28c2fb84aa7aa5d75933d1862d0f7de6198ea22dfd9a0cca06e8a4e7509e/rpds_py-0.27.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6c27a7054b5224710fcfb1a626ec3ff4f28bcb89b899148c72873b18210e446b", size = 347680, upload_time = "2025-08-07T08:23:46.014Z" }, + { url = "https://files.pythonhosted.org/packages/44/3e/9834b4c8f4f5fe936b479e623832468aa4bd6beb8d014fecaee9eac6cdb1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09965b314091829b378b60607022048953e25f0b396c2b70e7c4c81bcecf932e", size = 384600, upload_time = "2025-08-07T08:23:48Z" }, + { url = "https://files.pythonhosted.org/packages/19/78/744123c7b38865a965cd9e6f691fde7ef989a00a256fa8bf15b75240d12f/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:14f028eb47f59e9169bfdf9f7ceafd29dd64902141840633683d0bad5b04ff34", size = 400697, upload_time = "2025-08-07T08:23:49.407Z" }, + { url = "https://files.pythonhosted.org/packages/32/97/3c3d32fe7daee0a1f1a678b6d4dfb8c4dcf88197fa2441f9da7cb54a8466/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6168af0be75bba990a39f9431cdfae5f0ad501f4af32ae62e8856307200517b8", size = 517781, upload_time = "2025-08-07T08:23:50.557Z" }, + { url = "https://files.pythonhosted.org/packages/b2/be/28f0e3e733680aa13ecec1212fc0f585928a206292f14f89c0b8a684cad1/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab47fe727c13c09d0e6f508e3a49e545008e23bf762a245b020391b621f5b726", size = 406449, upload_time = "2025-08-07T08:23:51.732Z" }, + { url = "https://files.pythonhosted.org/packages/95/ae/5d15c83e337c082d0367053baeb40bfba683f42459f6ebff63a2fd7e5518/rpds_py-0.27.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa01b3d5e3b7d97efab65bd3d88f164e289ec323a8c033c5c38e53ee25c007e", size = 386150, upload_time = "2025-08-07T08:23:52.822Z" }, + { url = "https://files.pythonhosted.org/packages/bf/65/944e95f95d5931112829e040912b25a77b2e7ed913ea5fe5746aa5c1ce75/rpds_py-0.27.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:6c135708e987f46053e0a1246a206f53717f9fadfba27174a9769ad4befba5c3", size = 406100, upload_time = "2025-08-07T08:23:54.339Z" }, + { url = "https://files.pythonhosted.org/packages/21/a4/1664b83fae02894533cd11dc0b9f91d673797c2185b7be0f7496107ed6c5/rpds_py-0.27.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc327f4497b7087d06204235199daf208fd01c82d80465dc5efa4ec9df1c5b4e", size = 421345, upload_time = "2025-08-07T08:23:55.832Z" }, + { url = "https://files.pythonhosted.org/packages/7c/26/b7303941c2b0823bfb34c71378249f8beedce57301f400acb04bb345d025/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e57906e38583a2cba67046a09c2637e23297618dc1f3caddbc493f2be97c93f", size = 561891, upload_time = "2025-08-07T08:23:56.951Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c8/48623d64d4a5a028fa99576c768a6159db49ab907230edddc0b8468b998b/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f4f69d7a4300fbf91efb1fb4916421bd57804c01ab938ab50ac9c4aa2212f03", size = 591756, upload_time = "2025-08-07T08:23:58.146Z" }, + { url = "https://files.pythonhosted.org/packages/b3/51/18f62617e8e61cc66334c9fb44b1ad7baae3438662098efbc55fb3fda453/rpds_py-0.27.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b4c4fbbcff474e1e5f38be1bf04511c03d492d42eec0babda5d03af3b5589374", size = 557088, upload_time = "2025-08-07T08:23:59.6Z" }, + { url = "https://files.pythonhosted.org/packages/bd/4c/e84c3a276e2496a93d245516be6b49e20499aa8ca1c94d59fada0d79addc/rpds_py-0.27.0-cp312-cp312-win32.whl", hash = "sha256:27bac29bbbf39601b2aab474daf99dbc8e7176ca3389237a23944b17f8913d97", size = 221926, upload_time = "2025-08-07T08:24:00.695Z" }, + { url = "https://files.pythonhosted.org/packages/83/89/9d0fbcef64340db0605eb0a0044f258076f3ae0a3b108983b2c614d96212/rpds_py-0.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:8a06aa1197ec0281eb1d7daf6073e199eb832fe591ffa329b88bae28f25f5fe5", size = 233235, upload_time = "2025-08-07T08:24:01.846Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b0/e177aa9f39cbab060f96de4a09df77d494f0279604dc2f509263e21b05f9/rpds_py-0.27.0-cp312-cp312-win_arm64.whl", hash = "sha256:e14aab02258cb776a108107bd15f5b5e4a1bbaa61ef33b36693dfab6f89d54f9", size = 223315, upload_time = "2025-08-07T08:24:03.337Z" }, + { url = "https://files.pythonhosted.org/packages/81/d2/dfdfd42565a923b9e5a29f93501664f5b984a802967d48d49200ad71be36/rpds_py-0.27.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:443d239d02d9ae55b74015234f2cd8eb09e59fbba30bf60baeb3123ad4c6d5ff", size = 362133, upload_time = "2025-08-07T08:24:04.508Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4a/0a2e2460c4b66021d349ce9f6331df1d6c75d7eea90df9785d333a49df04/rpds_py-0.27.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b8a7acf04fda1f30f1007f3cc96d29d8cf0a53e626e4e1655fdf4eabc082d367", size = 347128, upload_time = "2025-08-07T08:24:05.695Z" }, + { url = "https://files.pythonhosted.org/packages/35/8d/7d1e4390dfe09d4213b3175a3f5a817514355cb3524593380733204f20b9/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d0f92b78cfc3b74a42239fdd8c1266f4715b573204c234d2f9fc3fc7a24f185", size = 384027, upload_time = "2025-08-07T08:24:06.841Z" }, + { url = "https://files.pythonhosted.org/packages/c1/65/78499d1a62172891c8cd45de737b2a4b84a414b6ad8315ab3ac4945a5b61/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ce4ed8e0c7dbc5b19352b9c2c6131dd23b95fa8698b5cdd076307a33626b72dc", size = 399973, upload_time = "2025-08-07T08:24:08.143Z" }, + { url = "https://files.pythonhosted.org/packages/10/a1/1c67c1d8cc889107b19570bb01f75cf49852068e95e6aee80d22915406fc/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fde355b02934cc6b07200cc3b27ab0c15870a757d1a72fd401aa92e2ea3c6bfe", size = 515295, upload_time = "2025-08-07T08:24:09.711Z" }, + { url = "https://files.pythonhosted.org/packages/df/27/700ec88e748436b6c7c4a2262d66e80f8c21ab585d5e98c45e02f13f21c0/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:13bbc4846ae4c993f07c93feb21a24d8ec637573d567a924b1001e81c8ae80f9", size = 406737, upload_time = "2025-08-07T08:24:11.182Z" }, + { url = "https://files.pythonhosted.org/packages/33/cc/6b0ee8f0ba3f2df2daac1beda17fde5cf10897a7d466f252bd184ef20162/rpds_py-0.27.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be0744661afbc4099fef7f4e604e7f1ea1be1dd7284f357924af12a705cc7d5c", size = 385898, upload_time = "2025-08-07T08:24:12.798Z" }, + { url = "https://files.pythonhosted.org/packages/e8/7e/c927b37d7d33c0a0ebf249cc268dc2fcec52864c1b6309ecb960497f2285/rpds_py-0.27.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:069e0384a54f427bd65d7fda83b68a90606a3835901aaff42185fcd94f5a9295", size = 405785, upload_time = "2025-08-07T08:24:14.906Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/8ed50746d909dcf402af3fa58b83d5a590ed43e07251d6b08fad1a535ba6/rpds_py-0.27.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4bc262ace5a1a7dc3e2eac2fa97b8257ae795389f688b5adf22c5db1e2431c43", size = 419760, upload_time = "2025-08-07T08:24:16.129Z" }, + { url = "https://files.pythonhosted.org/packages/d3/60/2b2071aee781cb3bd49f94d5d35686990b925e9b9f3e3d149235a6f5d5c1/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2fe6e18e5c8581f0361b35ae575043c7029d0a92cb3429e6e596c2cdde251432", size = 561201, upload_time = "2025-08-07T08:24:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/98/1f/27b67304272521aaea02be293fecedce13fa351a4e41cdb9290576fc6d81/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d93ebdb82363d2e7bec64eecdc3632b59e84bd270d74fe5be1659f7787052f9b", size = 591021, upload_time = "2025-08-07T08:24:18.999Z" }, + { url = "https://files.pythonhosted.org/packages/db/9b/a2fadf823164dd085b1f894be6443b0762a54a7af6f36e98e8fcda69ee50/rpds_py-0.27.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0954e3a92e1d62e83a54ea7b3fdc9efa5d61acef8488a8a3d31fdafbfb00460d", size = 556368, upload_time = "2025-08-07T08:24:20.54Z" }, + { url = "https://files.pythonhosted.org/packages/24/f3/6d135d46a129cda2e3e6d4c5e91e2cc26ea0428c6cf152763f3f10b6dd05/rpds_py-0.27.0-cp313-cp313-win32.whl", hash = "sha256:2cff9bdd6c7b906cc562a505c04a57d92e82d37200027e8d362518df427f96cd", size = 221236, upload_time = "2025-08-07T08:24:22.144Z" }, + { url = "https://files.pythonhosted.org/packages/c5/44/65d7494f5448ecc755b545d78b188440f81da98b50ea0447ab5ebfdf9bd6/rpds_py-0.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc79d192fb76fc0c84f2c58672c17bbbc383fd26c3cdc29daae16ce3d927e8b2", size = 232634, upload_time = "2025-08-07T08:24:23.642Z" }, + { url = "https://files.pythonhosted.org/packages/70/d9/23852410fadab2abb611733933401de42a1964ce6600a3badae35fbd573e/rpds_py-0.27.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b3a5c8089eed498a3af23ce87a80805ff98f6ef8f7bdb70bd1b7dae5105f6ac", size = 222783, upload_time = "2025-08-07T08:24:25.098Z" }, + { url = "https://files.pythonhosted.org/packages/15/75/03447917f78512b34463f4ef11066516067099a0c466545655503bed0c77/rpds_py-0.27.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:90fb790138c1a89a2e58c9282fe1089638401f2f3b8dddd758499041bc6e0774", size = 359154, upload_time = "2025-08-07T08:24:26.249Z" }, + { url = "https://files.pythonhosted.org/packages/6b/fc/4dac4fa756451f2122ddaf136e2c6aeb758dc6fdbe9ccc4bc95c98451d50/rpds_py-0.27.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:010c4843a3b92b54373e3d2291a7447d6c3fc29f591772cc2ea0e9f5c1da434b", size = 343909, upload_time = "2025-08-07T08:24:27.405Z" }, + { url = "https://files.pythonhosted.org/packages/7b/81/723c1ed8e6f57ed9d8c0c07578747a2d3d554aaefc1ab89f4e42cfeefa07/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9ce7a9e967afc0a2af7caa0d15a3e9c1054815f73d6a8cb9225b61921b419bd", size = 379340, upload_time = "2025-08-07T08:24:28.714Z" }, + { url = "https://files.pythonhosted.org/packages/98/16/7e3740413de71818ce1997df82ba5f94bae9fff90c0a578c0e24658e6201/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aa0bf113d15e8abdfee92aa4db86761b709a09954083afcb5bf0f952d6065fdb", size = 391655, upload_time = "2025-08-07T08:24:30.223Z" }, + { url = "https://files.pythonhosted.org/packages/e0/63/2a9f510e124d80660f60ecce07953f3f2d5f0b96192c1365443859b9c87f/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb91d252b35004a84670dfeafadb042528b19842a0080d8b53e5ec1128e8f433", size = 513017, upload_time = "2025-08-07T08:24:31.446Z" }, + { url = "https://files.pythonhosted.org/packages/2c/4e/cf6ff311d09776c53ea1b4f2e6700b9d43bb4e99551006817ade4bbd6f78/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:db8a6313dbac934193fc17fe7610f70cd8181c542a91382531bef5ed785e5615", size = 402058, upload_time = "2025-08-07T08:24:32.613Z" }, + { url = "https://files.pythonhosted.org/packages/88/11/5e36096d474cb10f2a2d68b22af60a3bc4164fd8db15078769a568d9d3ac/rpds_py-0.27.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce96ab0bdfcef1b8c371ada2100767ace6804ea35aacce0aef3aeb4f3f499ca8", size = 383474, upload_time = "2025-08-07T08:24:33.767Z" }, + { url = "https://files.pythonhosted.org/packages/db/a2/3dff02805b06058760b5eaa6d8cb8db3eb3e46c9e452453ad5fc5b5ad9fe/rpds_py-0.27.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:7451ede3560086abe1aa27dcdcf55cd15c96b56f543fb12e5826eee6f721f858", size = 400067, upload_time = "2025-08-07T08:24:35.021Z" }, + { url = "https://files.pythonhosted.org/packages/67/87/eed7369b0b265518e21ea836456a4ed4a6744c8c12422ce05bce760bb3cf/rpds_py-0.27.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:32196b5a99821476537b3f7732432d64d93a58d680a52c5e12a190ee0135d8b5", size = 412085, upload_time = "2025-08-07T08:24:36.267Z" }, + { url = "https://files.pythonhosted.org/packages/8b/48/f50b2ab2fbb422fbb389fe296e70b7a6b5ea31b263ada5c61377e710a924/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a029be818059870664157194e46ce0e995082ac49926f1423c1f058534d2aaa9", size = 555928, upload_time = "2025-08-07T08:24:37.573Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/b18eb51045d06887666c3560cd4bbb6819127b43d758f5adb82b5f56f7d1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3841f66c1ffdc6cebce8aed64e36db71466f1dc23c0d9a5592e2a782a3042c79", size = 585527, upload_time = "2025-08-07T08:24:39.391Z" }, + { url = "https://files.pythonhosted.org/packages/be/03/a3dd6470fc76499959b00ae56295b76b4bdf7c6ffc60d62006b1217567e1/rpds_py-0.27.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:42894616da0fc0dcb2ec08a77896c3f56e9cb2f4b66acd76fc8992c3557ceb1c", size = 554211, upload_time = "2025-08-07T08:24:40.6Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d1/ee5fd1be395a07423ac4ca0bcc05280bf95db2b155d03adefeb47d5ebf7e/rpds_py-0.27.0-cp313-cp313t-win32.whl", hash = "sha256:b1fef1f13c842a39a03409e30ca0bf87b39a1e2a305a9924deadb75a43105d23", size = 216624, upload_time = "2025-08-07T08:24:42.204Z" }, + { url = "https://files.pythonhosted.org/packages/1c/94/4814c4c858833bf46706f87349c37ca45e154da7dbbec9ff09f1abeb08cc/rpds_py-0.27.0-cp313-cp313t-win_amd64.whl", hash = "sha256:183f5e221ba3e283cd36fdfbe311d95cd87699a083330b4f792543987167eff1", size = 230007, upload_time = "2025-08-07T08:24:43.329Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a5/8fffe1c7dc7c055aa02df310f9fb71cfc693a4d5ccc5de2d3456ea5fb022/rpds_py-0.27.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:f3cd110e02c5bf17d8fb562f6c9df5c20e73029d587cf8602a2da6c5ef1e32cb", size = 362595, upload_time = "2025-08-07T08:24:44.478Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c7/4e4253fd2d4bb0edbc0b0b10d9f280612ca4f0f990e3c04c599000fe7d71/rpds_py-0.27.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8d0e09cf4863c74106b5265c2c310f36146e2b445ff7b3018a56799f28f39f6f", size = 347252, upload_time = "2025-08-07T08:24:45.678Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c8/3d1a954d30f0174dd6baf18b57c215da03cf7846a9d6e0143304e784cddc/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64f689ab822f9b5eb6dfc69893b4b9366db1d2420f7db1f6a2adf2a9ca15ad64", size = 384886, upload_time = "2025-08-07T08:24:46.86Z" }, + { url = "https://files.pythonhosted.org/packages/e0/52/3c5835f2df389832b28f9276dd5395b5a965cea34226e7c88c8fbec2093c/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e36c80c49853b3ffda7aa1831bf175c13356b210c73128c861f3aa93c3cc4015", size = 399716, upload_time = "2025-08-07T08:24:48.174Z" }, + { url = "https://files.pythonhosted.org/packages/40/73/176e46992461a1749686a2a441e24df51ff86b99c2d34bf39f2a5273b987/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6de6a7f622860af0146cb9ee148682ff4d0cea0b8fd3ad51ce4d40efb2f061d0", size = 517030, upload_time = "2025-08-07T08:24:49.52Z" }, + { url = "https://files.pythonhosted.org/packages/79/2a/7266c75840e8c6e70effeb0d38922a45720904f2cd695e68a0150e5407e2/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4045e2fc4b37ec4b48e8907a5819bdd3380708c139d7cc358f03a3653abedb89", size = 408448, upload_time = "2025-08-07T08:24:50.727Z" }, + { url = "https://files.pythonhosted.org/packages/e6/5f/a7efc572b8e235093dc6cf39f4dbc8a7f08e65fdbcec7ff4daeb3585eef1/rpds_py-0.27.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da162b718b12c4219eeeeb68a5b7552fbc7aadedf2efee440f88b9c0e54b45d", size = 387320, upload_time = "2025-08-07T08:24:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/a2/eb/9ff6bc92efe57cf5a2cb74dee20453ba444b6fdc85275d8c99e0d27239d1/rpds_py-0.27.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:0665be515767dc727ffa5f74bd2ef60b0ff85dad6bb8f50d91eaa6b5fb226f51", size = 407414, upload_time = "2025-08-07T08:24:53.664Z" }, + { url = "https://files.pythonhosted.org/packages/fb/bd/3b9b19b00d5c6e1bd0f418c229ab0f8d3b110ddf7ec5d9d689ef783d0268/rpds_py-0.27.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:203f581accef67300a942e49a37d74c12ceeef4514874c7cede21b012613ca2c", size = 420766, upload_time = "2025-08-07T08:24:55.917Z" }, + { url = "https://files.pythonhosted.org/packages/17/6b/521a7b1079ce16258c70805166e3ac6ec4ee2139d023fe07954dc9b2d568/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7873b65686a6471c0037139aa000d23fe94628e0daaa27b6e40607c90e3f5ec4", size = 562409, upload_time = "2025-08-07T08:24:57.17Z" }, + { url = "https://files.pythonhosted.org/packages/8b/bf/65db5bfb14ccc55e39de8419a659d05a2a9cd232f0a699a516bb0991da7b/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:249ab91ceaa6b41abc5f19513cb95b45c6f956f6b89f1fe3d99c81255a849f9e", size = 590793, upload_time = "2025-08-07T08:24:58.388Z" }, + { url = "https://files.pythonhosted.org/packages/db/b8/82d368b378325191ba7aae8f40f009b78057b598d4394d1f2cdabaf67b3f/rpds_py-0.27.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d2f184336bc1d6abfaaa1262ed42739c3789b1e3a65a29916a615307d22ffd2e", size = 558178, upload_time = "2025-08-07T08:24:59.756Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ff/f270bddbfbc3812500f8131b1ebbd97afd014cd554b604a3f73f03133a36/rpds_py-0.27.0-cp314-cp314-win32.whl", hash = "sha256:d3c622c39f04d5751408f5b801ecb527e6e0a471b367f420a877f7a660d583f6", size = 222355, upload_time = "2025-08-07T08:25:01.027Z" }, + { url = "https://files.pythonhosted.org/packages/bf/20/fdab055b1460c02ed356a0e0b0a78c1dd32dc64e82a544f7b31c9ac643dc/rpds_py-0.27.0-cp314-cp314-win_amd64.whl", hash = "sha256:cf824aceaeffff029ccfba0da637d432ca71ab21f13e7f6f5179cd88ebc77a8a", size = 234007, upload_time = "2025-08-07T08:25:02.268Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a8/694c060005421797a3be4943dab8347c76c2b429a9bef68fb2c87c9e70c7/rpds_py-0.27.0-cp314-cp314-win_arm64.whl", hash = "sha256:86aca1616922b40d8ac1b3073a1ead4255a2f13405e5700c01f7c8d29a03972d", size = 223527, upload_time = "2025-08-07T08:25:03.45Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f9/77f4c90f79d2c5ca8ce6ec6a76cb4734ee247de6b3a4f337e289e1f00372/rpds_py-0.27.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:341d8acb6724c0c17bdf714319c393bb27f6d23d39bc74f94221b3e59fc31828", size = 359469, upload_time = "2025-08-07T08:25:04.648Z" }, + { url = "https://files.pythonhosted.org/packages/c0/22/b97878d2f1284286fef4172069e84b0b42b546ea7d053e5fb7adb9ac6494/rpds_py-0.27.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6b96b0b784fe5fd03beffff2b1533dc0d85e92bab8d1b2c24ef3a5dc8fac5669", size = 343960, upload_time = "2025-08-07T08:25:05.863Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b0/dfd55b5bb480eda0578ae94ef256d3061d20b19a0f5e18c482f03e65464f/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c431bfb91478d7cbe368d0a699978050d3b112d7f1d440a41e90faa325557fd", size = 380201, upload_time = "2025-08-07T08:25:07.513Z" }, + { url = "https://files.pythonhosted.org/packages/28/22/e1fa64e50d58ad2b2053077e3ec81a979147c43428de9e6de68ddf6aff4e/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e222a44ae9f507d0f2678ee3dd0c45ec1e930f6875d99b8459631c24058aec", size = 392111, upload_time = "2025-08-07T08:25:09.149Z" }, + { url = "https://files.pythonhosted.org/packages/49/f9/43ab7a43e97aedf6cea6af70fdcbe18abbbc41d4ae6cdec1bfc23bbad403/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:184f0d7b342967f6cda94a07d0e1fae177d11d0b8f17d73e06e36ac02889f303", size = 515863, upload_time = "2025-08-07T08:25:10.431Z" }, + { url = "https://files.pythonhosted.org/packages/38/9b/9bd59dcc636cd04d86a2d20ad967770bf348f5eb5922a8f29b547c074243/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a00c91104c173c9043bc46f7b30ee5e6d2f6b1149f11f545580f5d6fdff42c0b", size = 402398, upload_time = "2025-08-07T08:25:11.819Z" }, + { url = "https://files.pythonhosted.org/packages/71/bf/f099328c6c85667aba6b66fa5c35a8882db06dcd462ea214be72813a0dd2/rpds_py-0.27.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7a37dd208f0d658e0487522078b1ed68cd6bce20ef4b5a915d2809b9094b410", size = 384665, upload_time = "2025-08-07T08:25:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c5/9c1f03121ece6634818490bd3c8be2c82a70928a19de03467fb25a3ae2a8/rpds_py-0.27.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:92f3b3ec3e6008a1fe00b7c0946a170f161ac00645cde35e3c9a68c2475e8156", size = 400405, upload_time = "2025-08-07T08:25:14.417Z" }, + { url = "https://files.pythonhosted.org/packages/b5/b8/e25d54af3e63ac94f0c16d8fe143779fe71ff209445a0c00d0f6984b6b2c/rpds_py-0.27.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1b3db5fae5cbce2131b7420a3f83553d4d89514c03d67804ced36161fe8b6b2", size = 413179, upload_time = "2025-08-07T08:25:15.664Z" }, + { url = "https://files.pythonhosted.org/packages/f9/d1/406b3316433fe49c3021546293a04bc33f1478e3ec7950215a7fce1a1208/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5355527adaa713ab693cbce7c1e0ec71682f599f61b128cf19d07e5c13c9b1f1", size = 556895, upload_time = "2025-08-07T08:25:17.061Z" }, + { url = "https://files.pythonhosted.org/packages/5f/bc/3697c0c21fcb9a54d46ae3b735eb2365eea0c2be076b8f770f98e07998de/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:fcc01c57ce6e70b728af02b2401c5bc853a9e14eb07deda30624374f0aebfe42", size = 585464, upload_time = "2025-08-07T08:25:18.406Z" }, + { url = "https://files.pythonhosted.org/packages/63/09/ee1bb5536f99f42c839b177d552f6114aa3142d82f49cef49261ed28dbe0/rpds_py-0.27.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3001013dae10f806380ba739d40dee11db1ecb91684febb8406a87c2ded23dae", size = 555090, upload_time = "2025-08-07T08:25:20.461Z" }, + { url = "https://files.pythonhosted.org/packages/7d/2c/363eada9e89f7059199d3724135a86c47082cbf72790d6ba2f336d146ddb/rpds_py-0.27.0-cp314-cp314t-win32.whl", hash = "sha256:0f401c369186a5743694dd9fc08cba66cf70908757552e1f714bfc5219c655b5", size = 218001, upload_time = "2025-08-07T08:25:21.761Z" }, + { url = "https://files.pythonhosted.org/packages/e2/3f/d6c216ed5199c9ef79e2a33955601f454ed1e7420a93b89670133bca5ace/rpds_py-0.27.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8a1dca5507fa1337f75dcd5070218b20bc68cf8844271c923c1b79dfcbc20391", size = 230993, upload_time = "2025-08-07T08:25:23.34Z" }, + { url = "https://files.pythonhosted.org/packages/59/64/72ab5b911fdcc48058359b0e786e5363e3fde885156116026f1a2ba9a5b5/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e6491658dd2569f05860bad645569145c8626ac231877b0fb2d5f9bcb7054089", size = 371658, upload_time = "2025-08-07T08:26:02.369Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4b/90ff04b4da055db53d8fea57640d8d5d55456343a1ec9a866c0ecfe10fd1/rpds_py-0.27.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:bec77545d188f8bdd29d42bccb9191682a46fb2e655e3d1fb446d47c55ac3b8d", size = 355529, upload_time = "2025-08-07T08:26:03.83Z" }, + { url = "https://files.pythonhosted.org/packages/a4/be/527491fb1afcd86fc5ce5812eb37bc70428ee017d77fee20de18155c3937/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25a4aebf8ca02bbb90a9b3e7a463bbf3bee02ab1c446840ca07b1695a68ce424", size = 382822, upload_time = "2025-08-07T08:26:05.52Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a5/dcdb8725ce11e6d0913e6fcf782a13f4b8a517e8acc70946031830b98441/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44524b96481a4c9b8e6c46d6afe43fa1fb485c261e359fbe32b63ff60e3884d8", size = 397233, upload_time = "2025-08-07T08:26:07.179Z" }, + { url = "https://files.pythonhosted.org/packages/33/f9/0947920d1927e9f144660590cc38cadb0795d78fe0d9aae0ef71c1513b7c/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45d04a73c54b6a5fd2bab91a4b5bc8b426949586e61340e212a8484919183859", size = 514892, upload_time = "2025-08-07T08:26:08.622Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ed/d1343398c1417c68f8daa1afce56ef6ce5cc587daaf98e29347b00a80ff2/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:343cf24de9ed6c728abefc5d5c851d5de06497caa7ac37e5e65dd572921ed1b5", size = 402733, upload_time = "2025-08-07T08:26:10.433Z" }, + { url = "https://files.pythonhosted.org/packages/1d/0b/646f55442cd14014fb64d143428f25667a100f82092c90087b9ea7101c74/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aed8118ae20515974650d08eb724150dc2e20c2814bcc307089569995e88a14", size = 384447, upload_time = "2025-08-07T08:26:11.847Z" }, + { url = "https://files.pythonhosted.org/packages/4b/15/0596ef7529828e33a6c81ecf5013d1dd33a511a3e0be0561f83079cda227/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:af9d4fd79ee1cc8e7caf693ee02737daabfc0fcf2773ca0a4735b356c8ad6f7c", size = 402502, upload_time = "2025-08-07T08:26:13.537Z" }, + { url = "https://files.pythonhosted.org/packages/c3/8d/986af3c42f8454a6cafff8729d99fb178ae9b08a9816325ac7a8fa57c0c0/rpds_py-0.27.0-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f0396e894bd1e66c74ecbc08b4f6a03dc331140942c4b1d345dd131b68574a60", size = 416651, upload_time = "2025-08-07T08:26:14.923Z" }, + { url = "https://files.pythonhosted.org/packages/e9/9a/b4ec3629b7b447e896eec574469159b5b60b7781d3711c914748bf32de05/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:59714ab0a5af25d723d8e9816638faf7f4254234decb7d212715c1aa71eee7be", size = 559460, upload_time = "2025-08-07T08:26:16.295Z" }, + { url = "https://files.pythonhosted.org/packages/61/63/d1e127b40c3e4733b3a6f26ae7a063cdf2bc1caa5272c89075425c7d397a/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:88051c3b7d5325409f433c5a40328fcb0685fc04e5db49ff936e910901d10114", size = 588072, upload_time = "2025-08-07T08:26:17.776Z" }, + { url = "https://files.pythonhosted.org/packages/04/7e/8ffc71a8f6833d9c9fb999f5b0ee736b8b159fd66968e05c7afc2dbcd57e/rpds_py-0.27.0-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:181bc29e59e5e5e6e9d63b143ff4d5191224d355e246b5a48c88ce6b35c4e466", size = 555083, upload_time = "2025-08-07T08:26:19.301Z" }, ] [[package]] name = "send2trash" version = "1.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394, upload-time = "2024-04-07T00:01:09.267Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394, upload_time = "2024-04-07T00:01:09.267Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072, upload-time = "2024-04-07T00:01:07.438Z" }, + { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072, upload_time = "2024-04-07T00:01:07.438Z" }, ] [[package]] name = "setuptools" version = "80.9.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload_time = "2025-05-27T00:56:51.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload_time = "2025-05-27T00:56:49.664Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload_time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload_time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload_time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload_time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "soupsieve" version = "2.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload_time = "2025-04-20T18:50:08.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload_time = "2025-04-20T18:50:07.196Z" }, ] [[package]] @@ -2038,9 +2042,9 @@ dependencies = [ { name = "executing" }, { name = "pure-eval" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload_time = "2023-09-30T13:58:05.479Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload_time = "2023-09-30T13:58:03.53Z" }, ] [[package]] @@ -2052,9 +2056,9 @@ dependencies = [ { name = "pywinpty", marker = "os_name == 'nt'" }, { name = "tornado" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload-time = "2024-03-12T14:34:39.026Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload_time = "2024-03-12T14:34:39.026Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload-time = "2024-03-12T14:34:36.569Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload_time = "2024-03-12T14:34:36.569Z" }, ] [[package]] @@ -2064,28 +2068,28 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "webencodings" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload-time = "2024-10-24T14:58:29.895Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085, upload_time = "2024-10-24T14:58:29.895Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload-time = "2024-10-24T14:58:28.029Z" }, + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610, upload_time = "2024-10-24T14:58:28.029Z" }, ] [[package]] name = "tornado" version = "6.5.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload-time = "2025-08-08T18:27:00.78Z" } +sdist = { url = "https://files.pythonhosted.org/packages/09/ce/1eb500eae19f4648281bb2186927bb062d2438c2e5093d1360391afd2f90/tornado-6.5.2.tar.gz", hash = "sha256:ab53c8f9a0fa351e2c0741284e06c7a45da86afb544133201c5cc8578eb076a0", size = 510821, upload_time = "2025-08-08T18:27:00.78Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload-time = "2025-08-08T18:26:42.945Z" }, - { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload-time = "2025-08-08T18:26:44.473Z" }, - { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload-time = "2025-08-08T18:26:46.021Z" }, - { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload-time = "2025-08-08T18:26:47.625Z" }, - { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload-time = "2025-08-08T18:26:50.599Z" }, - { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload-time = "2025-08-08T18:26:51.864Z" }, - { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload-time = "2025-08-08T18:26:53.625Z" }, - { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload-time = "2025-08-08T18:26:55.072Z" }, - { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload-time = "2025-08-08T18:26:56.677Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload-time = "2025-08-08T18:26:57.91Z" }, - { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload-time = "2025-08-08T18:26:59.207Z" }, + { url = "https://files.pythonhosted.org/packages/f6/48/6a7529df2c9cc12efd2e8f5dd219516184d703b34c06786809670df5b3bd/tornado-6.5.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:2436822940d37cde62771cff8774f4f00b3c8024fe482e16ca8387b8a2724db6", size = 442563, upload_time = "2025-08-08T18:26:42.945Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b5/9b575a0ed3e50b00c40b08cbce82eb618229091d09f6d14bce80fc01cb0b/tornado-6.5.2-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:583a52c7aa94ee046854ba81d9ebb6c81ec0fd30386d96f7640c96dad45a03ef", size = 440729, upload_time = "2025-08-08T18:26:44.473Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4e/619174f52b120efcf23633c817fd3fed867c30bff785e2cd5a53a70e483c/tornado-6.5.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0fe179f28d597deab2842b86ed4060deec7388f1fd9c1b4a41adf8af058907e", size = 444295, upload_time = "2025-08-08T18:26:46.021Z" }, + { url = "https://files.pythonhosted.org/packages/95/fa/87b41709552bbd393c85dd18e4e3499dcd8983f66e7972926db8d96aa065/tornado-6.5.2-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b186e85d1e3536d69583d2298423744740986018e393d0321df7340e71898882", size = 443644, upload_time = "2025-08-08T18:26:47.625Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/fb15f06e33d7430ca89420283a8762a4e6b8025b800ea51796ab5e6d9559/tornado-6.5.2-cp39-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e792706668c87709709c18b353da1f7662317b563ff69f00bab83595940c7108", size = 443878, upload_time = "2025-08-08T18:26:50.599Z" }, + { url = "https://files.pythonhosted.org/packages/11/92/fe6d57da897776ad2e01e279170ea8ae726755b045fe5ac73b75357a5a3f/tornado-6.5.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:06ceb1300fd70cb20e43b1ad8aaee0266e69e7ced38fa910ad2e03285009ce7c", size = 444549, upload_time = "2025-08-08T18:26:51.864Z" }, + { url = "https://files.pythonhosted.org/packages/9b/02/c8f4f6c9204526daf3d760f4aa555a7a33ad0e60843eac025ccfd6ff4a93/tornado-6.5.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:74db443e0f5251be86cbf37929f84d8c20c27a355dd452a5cfa2aada0d001ec4", size = 443973, upload_time = "2025-08-08T18:26:53.625Z" }, + { url = "https://files.pythonhosted.org/packages/ae/2d/f5f5707b655ce2317190183868cd0f6822a1121b4baeae509ceb9590d0bd/tornado-6.5.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b5e735ab2889d7ed33b32a459cac490eda71a1ba6857b0118de476ab6c366c04", size = 443954, upload_time = "2025-08-08T18:26:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/e8/59/593bd0f40f7355806bf6573b47b8c22f8e1374c9b6fd03114bd6b7a3dcfd/tornado-6.5.2-cp39-abi3-win32.whl", hash = "sha256:c6f29e94d9b37a95013bb669616352ddb82e3bfe8326fccee50583caebc8a5f0", size = 445023, upload_time = "2025-08-08T18:26:56.677Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/f609b420c2f564a748a2d80ebfb2ee02a73ca80223af712fca591386cafb/tornado-6.5.2-cp39-abi3-win_amd64.whl", hash = "sha256:e56a5af51cc30dd2cae649429af65ca2f6571da29504a07995175df14c18f35f", size = 445427, upload_time = "2025-08-08T18:26:57.91Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4f/e1f65e8f8c76d73658b33d33b81eed4322fb5085350e4328d5c956f0c8f9/tornado-6.5.2-cp39-abi3-win_arm64.whl", hash = "sha256:d6c33dc3672e3a1f3618eb63b7ef4683a7688e7b9e6e8f0d9aa5726360a004af", size = 444456, upload_time = "2025-08-08T18:26:59.207Z" }, ] [[package]] @@ -2095,115 +2099,106 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload_time = "2024-11-24T20:12:22.481Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload_time = "2024-11-24T20:12:19.698Z" }, ] [[package]] name = "traitlets" version = "5.14.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload-time = "2024-04-19T11:11:49.746Z" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621, upload_time = "2024-04-19T11:11:49.746Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload-time = "2024-04-19T11:11:46.763Z" }, + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359, upload_time = "2024-04-19T11:11:46.763Z" }, ] [[package]] name = "types-python-dateutil" version = "2.9.0.20250809" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a3/53/07dac71db45fb6b3c71c2fd29a87cada2239eac7ecfb318e6ebc7da00a3b/types_python_dateutil-2.9.0.20250809.tar.gz", hash = "sha256:69cbf8d15ef7a75c3801d65d63466e46ac25a0baa678d89d0a137fc31a608cc1", size = 15820, upload-time = "2025-08-09T03:14:14.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/53/07dac71db45fb6b3c71c2fd29a87cada2239eac7ecfb318e6ebc7da00a3b/types_python_dateutil-2.9.0.20250809.tar.gz", hash = "sha256:69cbf8d15ef7a75c3801d65d63466e46ac25a0baa678d89d0a137fc31a608cc1", size = 15820, upload_time = "2025-08-09T03:14:14.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/5e/67312e679f612218d07fcdbd14017e6d571ce240a5ba1ad734f15a8523cc/types_python_dateutil-2.9.0.20250809-py3-none-any.whl", hash = "sha256:768890cac4f2d7fd9e0feb6f3217fce2abbfdfc0cadd38d11fba325a815e4b9f", size = 17707, upload-time = "2025-08-09T03:14:13.314Z" }, -] - -[[package]] -name = "types-pytz" -version = "2025.2.0.20250809" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/07/e2/c774f754de26848f53f05defff5bb21dd9375a059d1ba5b5ea943cf8206e/types_pytz-2025.2.0.20250809.tar.gz", hash = "sha256:222e32e6a29bb28871f8834e8785e3801f2dc4441c715cd2082b271eecbe21e5", size = 10876, upload-time = "2025-08-09T03:14:17.453Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/d0/91c24fe54e565f2344d7a6821e6c6bb099841ef09007ea6321a0bac0f808/types_pytz-2025.2.0.20250809-py3-none-any.whl", hash = "sha256:4f55ed1b43e925cf851a756fe1707e0f5deeb1976e15bf844bcaa025e8fbd0db", size = 10095, upload-time = "2025-08-09T03:14:16.674Z" }, + { url = "https://files.pythonhosted.org/packages/43/5e/67312e679f612218d07fcdbd14017e6d571ce240a5ba1ad734f15a8523cc/types_python_dateutil-2.9.0.20250809-py3-none-any.whl", hash = "sha256:768890cac4f2d7fd9e0feb6f3217fce2abbfdfc0cadd38d11fba325a815e4b9f", size = 17707, upload_time = "2025-08-09T03:14:13.314Z" }, ] [[package]] name = "typing-extensions" version = "4.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload_time = "2025-07-04T13:28:34.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload_time = "2025-07-04T13:28:32.743Z" }, ] [[package]] name = "tzdata" version = "2025.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload_time = "2025-03-23T13:54:43.652Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload_time = "2025-03-23T13:54:41.845Z" }, ] [[package]] name = "uri-template" version = "1.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload_time = "2023-06-21T01:49:05.374Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload_time = "2023-06-21T01:49:03.467Z" }, ] [[package]] name = "urllib3" version = "2.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload_time = "2025-06-18T14:07:41.644Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload_time = "2025-06-18T14:07:40.39Z" }, ] [[package]] name = "wcwidth" version = "0.2.13" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload-time = "2024-01-06T02:10:57.829Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301, upload_time = "2024-01-06T02:10:57.829Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload_time = "2024-01-06T02:10:55.763Z" }, ] [[package]] name = "webcolors" version = "24.11.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload_time = "2024-11-11T07:43:24.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" }, + { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload_time = "2024-11-11T07:43:22.529Z" }, ] [[package]] name = "webencodings" version = "0.5.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload_time = "2017-04-05T20:21:34.189Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload_time = "2017-04-05T20:21:32.581Z" }, ] [[package]] name = "websocket-client" version = "1.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload-time = "2024-04-23T22:16:16.976Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648, upload_time = "2024-04-23T22:16:16.976Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload-time = "2024-04-23T22:16:14.422Z" }, + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826, upload_time = "2024-04-23T22:16:14.422Z" }, ] [[package]] name = "widgetsnbextension" version = "4.0.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/41/53/2e0253c5efd69c9656b1843892052a31c36d37ad42812b5da45c62191f7e/widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af", size = 1097428, upload-time = "2025-04-10T13:01:25.628Z" } +sdist = { url = "https://files.pythonhosted.org/packages/41/53/2e0253c5efd69c9656b1843892052a31c36d37ad42812b5da45c62191f7e/widgetsnbextension-4.0.14.tar.gz", hash = "sha256:a3629b04e3edb893212df862038c7232f62973373869db5084aed739b437b5af", size = 1097428, upload_time = "2025-04-10T13:01:25.628Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575", size = 2196503, upload-time = "2025-04-10T13:01:23.086Z" }, + { url = "https://files.pythonhosted.org/packages/ca/51/5447876806d1088a0f8f71e16542bf350918128d0a69437df26047c8e46f/widgetsnbextension-4.0.14-py3-none-any.whl", hash = "sha256:4875a9eaf72fbf5079dc372a51a9f268fc38d46f767cbf85c43a36da5cb9b575", size = 2196503, upload_time = "2025-04-10T13:01:23.086Z" }, ]