          """ :class:`tkinter.BooleanVar`:  ``True`` if the training graph should be refreshed
          otherwise ``False`` """
          return self._refresh_graph
  
      @property
      def update_preview(self) -> tk.BooleanVar:
          """ :class:`tkinter.BooleanVar`:  ``True`` if the preview should be refreshed
          otherwise ``False`` """
          return self._update_preview
  
      @property
      def analysis_folder(self) -> tk.StringVar:
          """ :class:`tkinter.StringVar`: Full path the analysis folder"""
          return self._analysis_folder
  
 
</s> remove             The size of the thumbnail that the placeholder should replicate
 </s> add             The size of each thumbnail that should be created
        frame_dims: tuple
            The (width (`int`), height (`int`)) of the display panel that will display the preview

        Returns
        -------
        bool
            ``True`` if a preview was succesfully loaded otherwise ``False`` </s> remove     @classmethod
    def _output_helptext(cls) -> None:
 </s> add     @property
    def master_frame(self) -> tk.Frame:
        """ :class:`tkinter.Frame`: The master frame that holds the preview window """
        return self._master_frame

    def pack(self, *args, **kwargs):
        """ Redirect calls to pack the widget to pack the actual :attr:`_master_frame`.

        Takes standard :class:`tkinter.Frame` pack arguments
        """
        logger.debug("Packing master frame: (args: %s, kwargs: %s)", args, kwargs)
        self._master_frame.pack(*args, **kwargs)

    def save(self, location: str) -> None:
        """ Save action to be performed when save button pressed from the GUI.

        location: str
            Full path to the folder to save the preview image to
        """
        self._image.save_preview(location)

    def remove_option_controls(self) -> None:
        """ Remove the taskbar options controls when the preview is disabled in the GUI """
        self._taskbar.destroy_widgets()

    def _output_helptext(self) -> None: </s> remove     def __init__(self) -> None:
        logger.debug("Initializing %s", self.__class__.__name__)
        self._pathpreview = os.path.join(PATHCACHE, "preview")
        self._pathoutput: Optional[str] = None
        self._batch_mode = False
        self._previewoutput: Optional[Tuple[Image.Image, ImageTk.PhotoImage]] = None
        self._previewtrain: Dict[str, List[Union[Image.Image,
                                                 ImageTk.PhotoImage,
                                                 None,
                                                 float]]] = {}
        self._previewcache: Dict[str, Union[None, float, np.ndarray, List[str]]] = dict(
            modified=None,  # cache for extract and convert
            images=None,
            filenames=[],
            placeholder=None)
        self._errcount = 0
        self._icons = self._load_icons()
 </s> add     logger.debug("Getting images: '%s'", image_path)
    if not os.path.isdir(image_path):
        logger.debug("Folder does not exist")
        return []
    files = [os.path.join(image_path, f)
             for f in os.listdir(image_path) if f.lower().endswith((".png", ".jpg"))]
    logger.debug("Image files: %s", files)
    return files


class PreviewTrain():
    """ Handles the loading of the training preview image(s) and adding to the display buffer

    Parameters
    ----------
    cache_path: str
        Full path to the cache folder that contains the preview images
    """
    def __init__(self, cache_path: str) -> None:
        logger.debug("Initializing %s: (cache_path: '%s')", self.__class__.__name__, cache_path)
        self._buffer = PreviewBuffer()
        self._cache_path = cache_path
        self._modified: float = 0.0
        self._error_count: int = 0 </s> remove     is_standalone: bool
        ``True`` if preview is a pop-up window otherwise ``False``
 </s> add     taskbar: :class:`tkinter.ttk.Frame` or ``None``
        None if preview is a pop-up window otherwise ttk.Frame if taskbar is managed by the GUI </s> remove     def read_stdout(self):
        """ Read stdout from the subprocess. If training, pass the loss
        values to Queue """
 </s> add     def _process_progress_stdout(self, output: str) -> bool:
        """ Process stdout for any faceswap processes that update the status/progress bar(s)

        Parameters
        ----------
        output: str
            The output line read from stdout

        Returns
        -------
        bool
            ``True`` if all actions have been completed on the output line otherwise ``False``
        """
        if self.command == "train" and self.capture_loss(output):
            return True

        if self.command == "effmpeg" and self.capture_ffmpeg(output):
            return True

        if self.command not in ("train", "effmpeg") and self.capture_tqdm(output):
            return True

        return False

    def _process_training_stdout(self, output: str) -> None:
        """ Process any triggers that are required to update the GUI when Faceswap is running a
        training session.

        Parameters
        ----------
        output: str
            The output line read from stdout
        """
        if self.command != "train" or not self.wrapper.tk_vars.is_training.get():
            return

        if "[saved models]" not in output.strip().lower():
            return

        logger.debug("Trigger GUI Training update")
        logger.trace("tk_vars: %s", {itm: var.get()  # type:ignore
                                     for itm, var in self.wrapper.tk_vars.__dict__.items()})
        if not Session.is_training:
            # Don't initialize session until after the first save as state file must exist first
            logger.debug("Initializing curret training session")
            Session.initialize_session(self._session_info["model_folder"],
                                       self._session_info["model_name"],
                                       is_training=True)
        self.wrapper.tk_vars.refresh_graph.set(True)

    def read_stdout(self) -> None:
        """ Read stdout from the subprocess. """
          """ :class:`tkinter.BooleanVar`:  ``True`` if the training graph should be refreshed
          otherwise ``False`` """
          return self._refresh_graph
  






      @property
      def analysis_folder(self) -> tk.StringVar:
          """ :class:`tkinter.StringVar`: Full path the analysis folder"""
          return self._analysis_folder
  
keep keep keep keep replace replace replace replace replace replace keep keep keep keep keep
 GUI - Preview updates
  - Training preview. Embed preview pop-out window
  - Bugfix - convert/extract previews 
lib/gui/utils/config.py