code: def _create_lagged_data_by_moving_window(
      target_series: Optional[TimeSeries],
      output_chunk_length: int,
      past_covariates: Optional[TimeSeries],
      future_covariates: Optional[TimeSeries],
      lags: Optional[Union[Sequence[int], Dict[str, List[int]]]],
      lags_past_covariates: Optional[
          Union[Sequence[int], Dict[str, List[int]]]
      ],
      lags_future_covariates: Optional[
          Union[Sequence[int], Dict[str, List[int]]]
      ],
      max_samples_per_ts: Optional[int],
      multi_models: bool,
      check_inputs: bool,
      is_training: bool,
  ) -> Tuple[np.ndarray, np.ndarray, pd.Index]:
      """
      Helper function called by `create_lagged_data` that computes `X`, `y`, and `times` by
      extracting 'moving windows' from each series using the `strided_moving_window`
      function. More specifically, to extract the features of a particular series for an
      arbitrary time `t`, a 'window' between times `t - max_lag` and `t - min_lag` is
      extracted, where `max_lag` and `min_lag` are the largest and smallest magnitude lags
      requested for that particular series. After extracting this window, the requested lag
      values between these two minimum and maximum lag values can be extracted. Similarly,
      the labels for time `t` are formed simply by extracting a window between times `t`
      and `t + output_chunk_length - 1` from the target series. In both cases, the extracted
      windows can then be reshaped into the correct shape. This approach can only be used if
      we *can* assume that the specified series are all of the same frequency.
      """
      feature_times, min_lags, max_lags = _get_feature_times(
          target_series,
          past_covariates,
          future_covariates,
          lags,
          lags_past_covariates,
          lags_future_covariates,
          output_chunk_length,
          is_training=is_training,
          return_min_and_max_lags=True,
          check_inputs=check_inputs,
      )
      if check_inputs:
          series_and_lags_not_specified = [
              max_lag is None for max_lag in max_lags
          ]
          raise_if(
              all(series_and_lags_not_specified),
              "Must specify at least one series-lags pair.",
          )
      time_bounds = get_shared_times_bounds(*feature_times)
      raise_if(
          time_bounds is None,
          "Specified series do not share any common times for which features can be created.",
      )
      freq = _get_freqs(
          target_series, past_covariates, future_covariates
      )[0]
      if isinstance(time_bounds[0], int):
          # `stop` is exclusive, so need `+ freq` to include end-point:
          times = pd.RangeIndex(
              start=time_bounds[0],
              stop=time_bounds[1] + freq,
              step=freq,
          )
      else:
          times = pd.date_range(
              start=time_bounds[0], end=time_bounds[1], freq=freq
          )
      num_samples = len(times)
      if num_samples > max_samples_per_ts:
          times = times[-max_samples_per_ts:]
          num_samples = max_samples_per_ts
      # Time index of 'earliest' constructed observation:
      start_time = times[0]
      # Construct features array X:
      X = []
      start_time_idx = None
      target_start_time_idx = None
      for i, (series_i, lags_i, min_lag_i, max_lag_i) in enumerate(
          zip(
              [target_series, past_covariates, future_covariates],
              [lags, lags_past_covariates, lags_future_covariates],
              min_lags,
              max_lags,
          )
      ):
          series_and_lags_specified = min_lag_i is not None
          is_target_series = is_training and (i == 0)
          if is_target_series or series_and_lags_specified:
              time_index_i = series_i.time_index
              # If lags are sufficiently large, `series_i` may not contain all
              # feature times. For example, if `lags_past_covariates = [-50]`,
              # then we can construct features for time `51` using the value
              # of `past_covariates` at time `1`, but `past_covariates` may
              # only go up to time `30`. This does *not* occur when considering
              # the target series, however, since this series must have values
              # for all feature times - these values will become labels.
              # If `start_time` not included in `time_index_i`, can 'manually' calculate
              # what its index *would* be if `time_index_i` were extended to include that time:
              if not is_target_series and (
                  time_index_i[-1] < start_time
              ):
                  # Series frequency represents a non-ambiguous timedelta value (not ‘M’, ‘Y’ or ‘y’)
                  if (
                      pd.to_timedelta(series_i.freq, errors="coerce")
                      is not pd.NaT
                  ):
                      start_time_idx = (
                          len(time_index_i)
                          - 1
                          + (start_time - time_index_i[-1])
                          // series_i.freq
                      )
                  else:
                      # Create a temporary DatetimeIndex to extract the actual start index.
                      start_time_idx = (
                          len(time_index_i)
                          - 1
                          + len(
                              pd.date_range(
                                  start=time_index_i[-1]
                                  + series_i.freq,
                                  end=start_time,
                                  freq=series_i.freq,
                              )
                          )
                      )
              elif not is_target_series and (
                  time_index_i[0] >= start_time
              ):
                  start_time_idx = max_lag_i
              # If `start_time` *is* included in `time_index_i`, need to binary search `time_index_i`
              # for its position:
              else:
                  start_time_idx = np.searchsorted(
                      time_index_i, start_time
                  )
          if series_and_lags_specified:
              # Windows taken between times `t - max_lag_i` and `t - min_lag_i`
              window_len = max_lag_i - min_lag_i + 1
              first_window_start_idx = start_time_idx - max_lag_i
              first_window_end_idx = first_window_start_idx + window_len
              # Other windows are formed by sequentially shifting first window forward
              # by 1 index position each time; to create `(num_samples - 1)` more windows
              # in addition to the first window, need to take `(num_samples - 1)` values
              # after `first_window_end_idx`:
              vals = series_i.all_values(copy=False)[
                  first_window_start_idx : first_window_end_idx
                  + num_samples
                  - 1,
                  :,
                  :,
              ]
              windows = strided_moving_window(
                  vals, window_len, stride=1, axis=0, check_inputs=False
              )
              # Within each window, the `-1` indexed value (i.e. the value at the very end of
              # the window) corresponds to time `t - min_lag_i`. The negative index of the time
              # `t + lag_i` within this window is, therefore, `-1 + lag_i + min_lag_i`:
              if isinstance(lags_i, list):
                  lags_to_extract = (
                      np.array(lags_i, dtype=int) + min_lag_i - 1
                  )
              else:
                  # Lags are grouped by component, extracted from the same window
                  lags_to_extract = [
                      np.array(comp_lags, dtype=int) + min_lag_i - 1
                      for comp_lags in lags_i.values()
                  ]
              lagged_vals = _extract_lagged_vals_from_windows(
                  windows, lags_to_extract
              )
              X.append(lagged_vals)
          # Cache `start_time_idx` for label creation:
          if is_target_series:
              target_start_time_idx = start_time_idx
      X = np.concatenate(X, axis=1)
      # Construct labels array `y`:
      if is_training:
          # All values between times `t` and `t + output_chunk_length` used as labels:
          # Window taken between times `t` and `t + output_chunk_length - 1`:
          first_window_start_idx = target_start_time_idx
          # Add `+ 1` since end index is exclusive in Python:
          first_window_end_idx = (
              target_start_time_idx + output_chunk_length
          )
          # To create `(num_samples - 1)` other windows in addition to first window,
          # must take `(num_samples - 1)` values ahead of `first_window_end_idx`
          vals = target_series.all_values(copy=False)[
              first_window_start_idx : first_window_end_idx
              + num_samples
              - 1,
              :,
              :,
          ]
          windows = strided_moving_window(
              vals,
              window_len=output_chunk_length,
              stride=1,
              axis=0,
              check_inputs=False,
          )
          lags_to_extract = (
              None if multi_models else -np.ones((1,), dtype=int)
          )
          y = _extract_lagged_vals_from_windows(
              windows, lags_to_extract
          )
          # Only values at times `t + output_chunk_length - 1` used as labels:
      else:
          y = None
      return X, y, times
  
imports: import warnings
  from functools import reduce
  from math import inf
  from typing import Dict, List, Optional, Sequence, Tuple, Union
  from itertools import chain
  import numpy
  import pandas
  from numpy.lib.stride_tricks import as_strided
  from darts.logging import get_logger, raise_if, raise_if_not, raise_log
  from darts.timeseries import TimeSeries
  from darts.utils.utils import get_single_series, series2seq
label_desc: Use image node_id 6 for calling a global function with example usage: _create_lagged_data_by_moving_window(target_series, output_chunk_length, past_covariates, future_covariates, lags, lags_past_covariates, lags_future_covariates, max_samples_per_ts, multi_models, check_inputs, is_training) and returns: X,  y,  times