sahiapi 0.3.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {sahiapi-0.3.0 → sahiapi-0.4.0}/CHANGELOG.md +7 -0
  2. {sahiapi-0.3.0 → sahiapi-0.4.0}/PKG-INFO +1 -1
  3. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/feed.py +3 -0
  4. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/marketdata.py +2 -1
  5. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/proto/marketdata.proto +3 -0
  6. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/proto/marketdata_pb2.py +10 -10
  7. {sahiapi-0.3.0 → sahiapi-0.4.0}/.gitignore +0 -0
  8. {sahiapi-0.3.0 → sahiapi-0.4.0}/LICENSE +0 -0
  9. {sahiapi-0.3.0 → sahiapi-0.4.0}/README.md +0 -0
  10. {sahiapi-0.3.0 → sahiapi-0.4.0}/pyproject.toml +0 -0
  11. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/__init__.py +0 -0
  12. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/py.typed +0 -0
  13. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/__init__.py +0 -0
  14. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/account.py +0 -0
  15. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/auth.py +0 -0
  16. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/base.py +0 -0
  17. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/client.py +0 -0
  18. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/constants.py +0 -0
  19. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/env.py +0 -0
  20. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/exceptions.py +0 -0
  21. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/funds.py +0 -0
  22. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/http.py +0 -0
  23. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/instruments.py +0 -0
  24. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/orders.py +0 -0
  25. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/portfolio.py +0 -0
  26. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/proto/__init__.py +0 -0
  27. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/proto/codec.py +0 -0
  28. {sahiapi-0.3.0 → sahiapi-0.4.0}/src/sahiapi/sahi/ws_client.py +0 -0
@@ -6,6 +6,13 @@ follow [Semantic Versioning](https://semver.org/) once it reaches `1.0.0`.
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.4.0] - 2026-11-13
10
+
11
+ ### Added
12
+ - Depth ticks (`subscribe_depth`, `last_depth`) carry `total_buy_qty` and
13
+ `total_sell_qty`, the pending quantity in the full order book. `get_quotes`
14
+ returns the same two fields.
15
+
9
16
  ## [0.3.0] - 2026-10-28
10
17
 
11
18
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sahiapi
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: The official Python client library for the Sahi APIs.
5
5
  Project-URL: Homepage, https://docs.sahi.com/
6
6
  Project-URL: Documentation, https://docs.sahi.com/sdk/python/
@@ -218,6 +218,9 @@ class SahiFeed:
218
218
  ) -> None:
219
219
  """Subscribe these instruments for depth ticks (quote plus market depth).
220
220
 
221
+ ``total_buy_qty`` and ``total_sell_qty`` are the pending quantity in the
222
+ full order book, not only the levels in ``best_buys`` and ``best_sells``.
223
+
221
224
  See :meth:`subscribe_ltp` for the shared-callback and connection behaviour
222
225
  of ``on_data_received``.
223
226
  """
@@ -80,7 +80,8 @@ class _MarketData(EndpointGroup):
80
80
 
81
81
  Returns:
82
82
  ``{"data": {"<id>": {...}}}`` — the REST equivalent of the tick
83
- stream's depth tick: price, volume, DPR band, open interest and depth.
83
+ stream's depth tick: price, volume, DPR band, open interest, depth and
84
+ the order book's total buy and sell quantity.
84
85
 
85
86
  Raises:
86
87
  ValueError: If no ids are given.
@@ -129,6 +129,9 @@ message DepthTick {
129
129
  // 5 or 20 levels per side depending on the instrument's feed type (L2 vs L3).
130
130
  repeated DepthLevel best_buys = 11;
131
131
  repeated DepthLevel best_sells = 12;
132
+ // Pending quantity in the full order book, not only the levels above.
133
+ int64 total_buy_qty = 13;
134
+ int64 total_sell_qty = 14;
132
135
  }
133
136
 
134
137
  message DepthLevel {
@@ -14,7 +14,7 @@ _sym_db = _symbol_database.Default()
14
14
 
15
15
 
16
16
  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
17
- b'\n\x10marketdata.proto\x12\x19sahi.direct.marketdata.v1"\xd2\x01\n\rClientMessage\x12\x39\n\tsubscribe\x18\x01 \x01(\x0b\x32$.sahi.direct.marketdata.v1.SubscribeH\x00\x12=\n\x0bunsubscribe\x18\x02 \x01(\x0b\x32&.sahi.direct.marketdata.v1.UnsubscribeH\x00\x12<\n\x0bmode_change\x18\x03 \x01(\x0b\x32%.sahi.direct.marketdata.v1.ModeChangeH\x00\x42\t\n\x07payload"R\n\tSubscribe\x12-\n\x04mode\x18\x01 \x01(\x0e\x32\x1f.sahi.direct.marketdata.v1.Mode\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"%\n\x0bUnsubscribe\x12\x16\n\x0einstrument_ids\x18\x01 \x03(\x03"S\n\nModeChange\x12-\n\x04mode\x18\x01 \x01(\x0e\x32\x1f.sahi.direct.marketdata.v1.Mode\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"\xb2\x02\n\rServerMessage\x12-\n\x03\x61\x63k\x18\x01 \x01(\x0b\x32\x1e.sahi.direct.marketdata.v1.AckH\x00\x12\x36\n\x08ltp_tick\x18\x02 \x01(\x0b\x32".sahi.direct.marketdata.v1.LtpTickH\x00\x12:\n\nquote_tick\x18\x03 \x01(\x0b\x32$.sahi.direct.marketdata.v1.QuoteTickH\x00\x12:\n\ndepth_tick\x18\x04 \x01(\x0b\x32$.sahi.direct.marketdata.v1.DepthTickH\x00\x12\x37\n\x05\x65rror\x18\x05 \x01(\x0b\x32&.sahi.direct.marketdata.v1.StreamErrorH\x00\x42\t\n\x07payload"\xb8\x01\n\x03\x41\x63k\x12\x35\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32%.sahi.direct.marketdata.v1.Ack.Action\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"b\n\x06\x41\x63tion\x12\x12\n\x0e\x41\x43TION_INVALID\x10\x00\x12\x14\n\x10\x41\x43TION_SUBSCRIBE\x10\x01\x12\x16\n\x12\x41\x43TION_UNSUBSCRIBE\x10\x02\x12\x16\n\x12\x41\x43TION_MODE_CHANGE\x10\x03",\n\x0bStreamError\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t"\xf6\x01\n\x07LtpTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x42\x12\n\x10_last_trade_time"\x9a\x03\n\tQuoteTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x12\x14\n\x0cvolume_today\x18\x06 \x01(\x03\x12\x11\n\tdpr_upper\x18\x07 \x01(\x03\x12\x11\n\tdpr_lower\x18\x08 \x01(\x03\x12\x1f\n\x12prev_open_interest\x18\t \x01(\x03H\x01\x88\x01\x01\x12\x1a\n\ropen_interest\x18\n \x01(\x03H\x02\x88\x01\x01\x42\x12\n\x10_last_trade_timeB\x15\n\x13_prev_open_interestB\x10\n\x0e_open_interest"\x8f\x04\n\tDepthTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x12\x14\n\x0cvolume_today\x18\x06 \x01(\x03\x12\x11\n\tdpr_upper\x18\x07 \x01(\x03\x12\x11\n\tdpr_lower\x18\x08 \x01(\x03\x12\x1f\n\x12prev_open_interest\x18\t \x01(\x03H\x01\x88\x01\x01\x12\x1a\n\ropen_interest\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x38\n\tbest_buys\x18\x0b \x03(\x0b\x32%.sahi.direct.marketdata.v1.DepthLevel\x12\x39\n\nbest_sells\x18\x0c \x03(\x0b\x32%.sahi.direct.marketdata.v1.DepthLevelB\x12\n\x10_last_trade_timeB\x15\n\x13_prev_open_interestB\x10\n\x0e_open_interest"<\n\nDepthLevel\x12\r\n\x05price\x18\x01 \x01(\x03\x12\x0b\n\x03qty\x18\x02 \x01(\x03\x12\x12\n\nnum_orders\x18\x03 \x01(\x03*\x97\x01\n\x0f\x45xchangeSegment\x12\x1c\n\x18\x45XCHANGE_SEGMENT_INVALID\x10\x00\x12\x18\n\x14\x45XCHANGE_SEGMENT_NSE\x10\x01\x12\x18\n\x14\x45XCHANGE_SEGMENT_BSE\x10\x02\x12\x18\n\x14\x45XCHANGE_SEGMENT_NFO\x10\x03\x12\x18\n\x14\x45XCHANGE_SEGMENT_BFO\x10\x04*\xc2\x02\n\x0eInstrumentType\x12\x1b\n\x17INSTRUMENT_TYPE_INVALID\x10\x00\x12\x19\n\x15INSTRUMENT_TYPE_INDEX\x10\x01\x12\x19\n\x15INSTRUMENT_TYPE_STOCK\x10\x02\x12\x17\n\x13INSTRUMENT_TYPE_ETF\x10\x03\x12\x1d\n\x19INSTRUMENT_TYPE_INDEX_FUT\x10\x04\x12 \n\x1cINSTRUMENT_TYPE_INDEX_OPT_CE\x10\x05\x12 \n\x1cINSTRUMENT_TYPE_INDEX_OPT_PE\x10\x06\x12\x1d\n\x19INSTRUMENT_TYPE_STOCK_FUT\x10\x07\x12 \n\x1cINSTRUMENT_TYPE_STOCK_OPT_CE\x10\x08\x12 \n\x1cINSTRUMENT_TYPE_STOCK_OPT_PE\x10\t*F\n\x04Mode\x12\x10\n\x0cMODE_INVALID\x10\x00\x12\x0c\n\x08MODE_LTP\x10\x01\x12\x0e\n\nMODE_QUOTE\x10\x02\x12\x0e\n\nMODE_DEPTH\x10\x03\x62\x06proto3'
17
+ b'\n\x10marketdata.proto\x12\x19sahi.direct.marketdata.v1"\xd2\x01\n\rClientMessage\x12\x39\n\tsubscribe\x18\x01 \x01(\x0b\x32$.sahi.direct.marketdata.v1.SubscribeH\x00\x12=\n\x0bunsubscribe\x18\x02 \x01(\x0b\x32&.sahi.direct.marketdata.v1.UnsubscribeH\x00\x12<\n\x0bmode_change\x18\x03 \x01(\x0b\x32%.sahi.direct.marketdata.v1.ModeChangeH\x00\x42\t\n\x07payload"R\n\tSubscribe\x12-\n\x04mode\x18\x01 \x01(\x0e\x32\x1f.sahi.direct.marketdata.v1.Mode\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"%\n\x0bUnsubscribe\x12\x16\n\x0einstrument_ids\x18\x01 \x03(\x03"S\n\nModeChange\x12-\n\x04mode\x18\x01 \x01(\x0e\x32\x1f.sahi.direct.marketdata.v1.Mode\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"\xb2\x02\n\rServerMessage\x12-\n\x03\x61\x63k\x18\x01 \x01(\x0b\x32\x1e.sahi.direct.marketdata.v1.AckH\x00\x12\x36\n\x08ltp_tick\x18\x02 \x01(\x0b\x32".sahi.direct.marketdata.v1.LtpTickH\x00\x12:\n\nquote_tick\x18\x03 \x01(\x0b\x32$.sahi.direct.marketdata.v1.QuoteTickH\x00\x12:\n\ndepth_tick\x18\x04 \x01(\x0b\x32$.sahi.direct.marketdata.v1.DepthTickH\x00\x12\x37\n\x05\x65rror\x18\x05 \x01(\x0b\x32&.sahi.direct.marketdata.v1.StreamErrorH\x00\x42\t\n\x07payload"\xb8\x01\n\x03\x41\x63k\x12\x35\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32%.sahi.direct.marketdata.v1.Ack.Action\x12\x16\n\x0einstrument_ids\x18\x02 \x03(\x03"b\n\x06\x41\x63tion\x12\x12\n\x0e\x41\x43TION_INVALID\x10\x00\x12\x14\n\x10\x41\x43TION_SUBSCRIBE\x10\x01\x12\x16\n\x12\x41\x43TION_UNSUBSCRIBE\x10\x02\x12\x16\n\x12\x41\x43TION_MODE_CHANGE\x10\x03",\n\x0bStreamError\x12\x0c\n\x04\x63ode\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t"\xf6\x01\n\x07LtpTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x42\x12\n\x10_last_trade_time"\x9a\x03\n\tQuoteTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x12\x14\n\x0cvolume_today\x18\x06 \x01(\x03\x12\x11\n\tdpr_upper\x18\x07 \x01(\x03\x12\x11\n\tdpr_lower\x18\x08 \x01(\x03\x12\x1f\n\x12prev_open_interest\x18\t \x01(\x03H\x01\x88\x01\x01\x12\x1a\n\ropen_interest\x18\n \x01(\x03H\x02\x88\x01\x01\x42\x12\n\x10_last_trade_timeB\x15\n\x13_prev_open_interestB\x10\n\x0e_open_interest"\xbe\x04\n\tDepthTick\x12\x15\n\rinstrument_id\x18\x01 \x01(\x03\x12\x44\n\x10\x65xchange_segment\x18\x02 \x01(\x0e\x32*.sahi.direct.marketdata.v1.ExchangeSegment\x12\x42\n\x0finstrument_type\x18\x03 \x01(\x0e\x32).sahi.direct.marketdata.v1.InstrumentType\x12\x18\n\x10last_trade_price\x18\x04 \x01(\x03\x12\x1c\n\x0flast_trade_time\x18\x05 \x01(\x03H\x00\x88\x01\x01\x12\x14\n\x0cvolume_today\x18\x06 \x01(\x03\x12\x11\n\tdpr_upper\x18\x07 \x01(\x03\x12\x11\n\tdpr_lower\x18\x08 \x01(\x03\x12\x1f\n\x12prev_open_interest\x18\t \x01(\x03H\x01\x88\x01\x01\x12\x1a\n\ropen_interest\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x38\n\tbest_buys\x18\x0b \x03(\x0b\x32%.sahi.direct.marketdata.v1.DepthLevel\x12\x39\n\nbest_sells\x18\x0c \x03(\x0b\x32%.sahi.direct.marketdata.v1.DepthLevel\x12\x15\n\rtotal_buy_qty\x18\r \x01(\x03\x12\x16\n\x0etotal_sell_qty\x18\x0e \x01(\x03\x42\x12\n\x10_last_trade_timeB\x15\n\x13_prev_open_interestB\x10\n\x0e_open_interest"<\n\nDepthLevel\x12\r\n\x05price\x18\x01 \x01(\x03\x12\x0b\n\x03qty\x18\x02 \x01(\x03\x12\x12\n\nnum_orders\x18\x03 \x01(\x03*\x97\x01\n\x0f\x45xchangeSegment\x12\x1c\n\x18\x45XCHANGE_SEGMENT_INVALID\x10\x00\x12\x18\n\x14\x45XCHANGE_SEGMENT_NSE\x10\x01\x12\x18\n\x14\x45XCHANGE_SEGMENT_BSE\x10\x02\x12\x18\n\x14\x45XCHANGE_SEGMENT_NFO\x10\x03\x12\x18\n\x14\x45XCHANGE_SEGMENT_BFO\x10\x04*\xc2\x02\n\x0eInstrumentType\x12\x1b\n\x17INSTRUMENT_TYPE_INVALID\x10\x00\x12\x19\n\x15INSTRUMENT_TYPE_INDEX\x10\x01\x12\x19\n\x15INSTRUMENT_TYPE_STOCK\x10\x02\x12\x17\n\x13INSTRUMENT_TYPE_ETF\x10\x03\x12\x1d\n\x19INSTRUMENT_TYPE_INDEX_FUT\x10\x04\x12 \n\x1cINSTRUMENT_TYPE_INDEX_OPT_CE\x10\x05\x12 \n\x1cINSTRUMENT_TYPE_INDEX_OPT_PE\x10\x06\x12\x1d\n\x19INSTRUMENT_TYPE_STOCK_FUT\x10\x07\x12 \n\x1cINSTRUMENT_TYPE_STOCK_OPT_CE\x10\x08\x12 \n\x1cINSTRUMENT_TYPE_STOCK_OPT_PE\x10\t*F\n\x04Mode\x12\x10\n\x0cMODE_INVALID\x10\x00\x12\x0c\n\x08MODE_LTP\x10\x01\x12\x0e\n\nMODE_QUOTE\x10\x02\x12\x0e\n\nMODE_DEPTH\x10\x03\x62\x06proto3'
18
18
  )
19
19
 
20
20
  _globals = globals()
@@ -22,12 +22,12 @@ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
22
22
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, "marketdata_pb2", _globals)
23
23
  if _descriptor._USE_C_DESCRIPTORS == False:
24
24
  DESCRIPTOR._options = None
25
- _globals["_EXCHANGESEGMENT"]._serialized_start = 2265
26
- _globals["_EXCHANGESEGMENT"]._serialized_end = 2416
27
- _globals["_INSTRUMENTTYPE"]._serialized_start = 2419
28
- _globals["_INSTRUMENTTYPE"]._serialized_end = 2741
29
- _globals["_MODE"]._serialized_start = 2743
30
- _globals["_MODE"]._serialized_end = 2813
25
+ _globals["_EXCHANGESEGMENT"]._serialized_start = 2312
26
+ _globals["_EXCHANGESEGMENT"]._serialized_end = 2463
27
+ _globals["_INSTRUMENTTYPE"]._serialized_start = 2466
28
+ _globals["_INSTRUMENTTYPE"]._serialized_end = 2788
29
+ _globals["_MODE"]._serialized_start = 2790
30
+ _globals["_MODE"]._serialized_end = 2860
31
31
  _globals["_CLIENTMESSAGE"]._serialized_start = 48
32
32
  _globals["_CLIENTMESSAGE"]._serialized_end = 258
33
33
  _globals["_SUBSCRIBE"]._serialized_start = 260
@@ -49,7 +49,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
49
49
  _globals["_QUOTETICK"]._serialized_start = 1260
50
50
  _globals["_QUOTETICK"]._serialized_end = 1670
51
51
  _globals["_DEPTHTICK"]._serialized_start = 1673
52
- _globals["_DEPTHTICK"]._serialized_end = 2200
53
- _globals["_DEPTHLEVEL"]._serialized_start = 2202
54
- _globals["_DEPTHLEVEL"]._serialized_end = 2262
52
+ _globals["_DEPTHTICK"]._serialized_end = 2247
53
+ _globals["_DEPTHLEVEL"]._serialized_start = 2249
54
+ _globals["_DEPTHLEVEL"]._serialized_end = 2309
55
55
  # @@protoc_insertion_point(module_scope)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes