FLTK - FLTK1.4.1 - demo - animgifimage
文章目录
- FLTK - FLTK1.4.1 - demo - animgifimage
- 概述
- 笔记
- END
FLTK - FLTK1.4.1 - demo - animgifimage
概述
知识点:
注册图像文件类型判断回调
FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg
事件回调的注册
GIF图像显示为图片或动画的标志设置
// 超时回调的设置和移除, 超时回调是一次性的,如果还需要同一个超时回调,需要再次设置超时回调
// 文件选择器UI的调用和返回
// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型
// fltk窗口的遍历
// fltk窗口 背景颜色设置 Fl_Color
// fltk窗口退出回调的设置
// 图像数据载入成功和图像数据有效的判断
// 图像关键数据(长,宽,帧数)的取得
// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据
// fltk图像类禁用缓存
// fltk窗体禁止响应快捷键的窗体size缩放
// 等待当前窗体正常结束
// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。
笔记
// FLTK - FLTK1.4.1 - demo - animgifimage
/*
知识点:注册图像文件类型判断回调FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg事件回调的注册GIF图像显示为图片或动画的标志设置// 超时回调的设置和移除, 超时回调是一次性的,如果还需要同一个超时回调,需要再次设置超时回调// 文件选择器UI的调用和返回// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型// fltk窗口的遍历// fltk窗口 背景颜色设置 Fl_Color// fltk窗口退出回调的设置// 图像数据载入成功和图像数据有效的判断// 图像关键数据(长,宽,帧数)的取得// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据// fltk图像类禁用缓存// fltk窗体禁止响应快捷键的窗体size缩放// 等待当前窗体正常结束// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。
*/#include "fltk_test.h"// 如果要将fl demo的实现搬过来测试,就注释掉下面的宏
// #define DONT_USE_FL_DEMO#ifdef DONT_USE_FL_DEMO
int fl_demo_main(int argc, char** argv)
{return 0;
}#else#endif // TEST_FL_DEMO//
// Test program for displaying animated GIF files using the
// Fl_Anim_GIF_Image class.
//
#include <FL/Fl_Anim_GIF_Image.H>#include <FL/Fl_Double_Window.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_Tiled_Image.H>
#include <stdlib.h>static int g_good_count = 0, g_bad_count = 0, g_frame_count = 0;static const Fl_Color BackGroundColor = FL_GRAY; // use e.g. FL_RED to see// transparent parts better
static const double RedrawDelay = 30 /* 1. / 20*/ ; // interval [sec] for forced redrawstatic void quit_cb(Fl_Widget* w_, void*) {exit(0);
}static void set_title(Fl_Window* win, Fl_Anim_GIF_Image* animgif) {char buf[200];snprintf(buf, sizeof(buf), "%s (%d frames) %2.2fx", fl_filename_name(animgif->name()),animgif->frames(), animgif->speed());if (animgif->frame_uncache())strcat(buf, " U");// fltk窗口类的copy_x()是复制了一份数据,并不是指向原始数据win->copy_label(buf);win->copy_tooltip(buf);
}static void cb_forced_redraw(void* d) {// fltk窗口的遍历Fl_Window* win = Fl::first_window();while (win) {if (!win->menu_window())win->redraw();win = Fl::next_window(win);}if (Fl::first_window())Fl::repeat_timeout(RedrawDelay, cb_forced_redraw);
}Fl_Window* openFile(const char* name, char* flags, bool close = false) {// determine test options from 'flags'bool uncache = strchr(flags, 'u');char* d = flags - 1;int debug = 0;while ((d = strchr(++d, 'd'))) debug++;bool optimize_mem = strchr(flags, 'm');bool desaturate = strchr(flags, 'D');bool average = strchr(flags, 'A');bool test_tiles = strchr(flags, 'T');bool test_forced_redraw = strchr(flags, 'f');char* r = strchr(flags, 'r');bool resizable = r && !test_tiles;double scale = 1.0;if (r && resizable) scale = atof(r + 1);if (scale <= 0.1 || scale > 5)scale = resizable ? 0.7 : 1.0;// setup windowFl::remove_timeout(cb_forced_redraw);Fl_Double_Window* win = new Fl_Double_Window(300, 300);// fltk窗口 背景颜色设置 Fl_Colorwin->color(BackGroundColor);if (close){// fltk窗口退出回调的设置win->callback(quit_cb);}printf("Loading '%s'%s%s ... ", name,uncache ? " (uncached)" : "",optimize_mem ? " (optimized)" : "");// create a canvas for the animationFl_Box* canvas = test_tiles ? 0 : new Fl_Box(0, 0, 0, 0); // canvas will be resized by animationFl_Box* canvas2 = 0;unsigned short gif_flags = debug ? Fl_Anim_GIF_Image::LOG_FLAG : 0;if (debug > 1)gif_flags |= Fl_Anim_GIF_Image::DEBUG_FLAG;if (optimize_mem)gif_flags |= Fl_Anim_GIF_Image::OPTIMIZE_MEMORY;// create animation, specifying this canvas as display widget// fltk类的构造函数是通过弹窗来报错的(e.g. 图像文件格式错), 这个报错信息不是API调用者能控制的。Fl_Anim_GIF_Image* animgif = new Fl_Anim_GIF_Image(name, canvas, gif_flags);// 图像数据载入成功和图像数据有效的判断bool good(animgif->ld() == 0 && animgif->valid());// 图像关键数据(长,宽,帧数)的取得printf("%s: %d x %d (%d frames) %s\n",animgif->name(), animgif->w(), animgif->h(), animgif->frames(), good ? "OK" : "ERROR");// for the statistics (when run on testsuite):g_good_count += good;g_bad_count += !good;g_frame_count += animgif->frames();// 设置窗体的用户数据win->user_data(animgif); // store address of image (see note in main())// exercise the optional tests on the animation// fltk图像类禁用缓存animgif->frame_uncache(uncache);if (scale != 1.0) {animgif->resize(scale);printf("TEST: resized %s by %.2f to %d x %d\n", animgif->name(), scale, animgif->w(), animgif->h());}if (average) {printf("TEST: color_average %s\n", animgif->name());animgif->color_average(FL_GREEN, 0.5); // currently hardcoded}if (desaturate) {printf("TEST: desaturate %s\n", animgif->name());animgif->desaturate();}int W = animgif->w();int H = animgif->h();if (animgif->frames()) {if (test_tiles) {// demonstrate a way how to use the animation with Fl_Tiled_Imageprintf("TEST: use %s as tiles\n", animgif->name());W *= 2;H *= 2;Fl_Tiled_Image* tiled_image = new Fl_Tiled_Image(animgif);Fl_Group* group = new Fl_Group(0, 0, win->w(), win->h());group->image(tiled_image);group->align(FL_ALIGN_INSIDE);animgif->canvas(group, Fl_Anim_GIF_Image::DONT_RESIZE_CANVAS | Fl_Anim_GIF_Image::DONT_SET_AS_IMAGE);win->resizable(group);}else {// demonstrate a way how to use same animation in another canvas simultaneously:// as the current implementation allows only automatic redraw of one canvas..if (test_forced_redraw) {if (W < 400) {printf("TEST: open %s in another animation with application redraw\n", animgif->name());canvas2 = new Fl_Box(W, 0, animgif->w(), animgif->h()); // another canvas for animationcanvas2->image(animgif); // is set to same animation!W *= 2;Fl::add_timeout(RedrawDelay, cb_forced_redraw); // force periodic redraw}}}// make window resizable (must be done before show())if (resizable && canvas && !test_tiles) {win->resizable(win);}win->size(W, H); // change to actual size of canvas// start the animationwin->end();win->show();win->wait_for_expose();set_title(win, animgif);if (resizable && !test_tiles) {// need to reposition the widgets (have been moved by setting resizable())if (canvas && canvas2) {canvas->resize(0, 0, W / 2, canvas->h());canvas2->resize(W / 2, 0, W / 2, canvas2->h());}else if (canvas) {canvas->resize(0, 0, animgif->canvas_w(), animgif->canvas_h());}}// fltk窗体禁止响应快捷键的窗体size缩放win->init_sizes(); // IMPORTANT: otherwise weird things happen at Ctrl+/- scaling}else {delete win;return 0;}if (debug >= 3) {// open each frame in a separate windowfor (int i = 0; i < animgif->frames(); i++) {char buf[200];snprintf(buf, sizeof(buf), "Frame #%d", i + 1);Fl_Double_Window* win = new Fl_Double_Window(animgif->w(), animgif->h());win->copy_tooltip(buf);win->copy_label(buf);win->color(BackGroundColor);int w = animgif->image(i)->w();int h = animgif->image(i)->h();// in 'optimize_mem' mode frames must be offsetted to canvasint x = (w == animgif->w() && h == animgif->h()) ? 0 : animgif->frame_x(i);int y = (w == animgif->w() && h == animgif->h()) ? 0 : animgif->frame_y(i);Fl_Box* b = new Fl_Box(x, y, w, h);// get the frame imageb->image(animgif->image(i));win->end();win->show();}}return win;
}#include <FL/filename.H>
bool openDirectory(const char* dir, char* flags) {dirent** list;int nbr_of_files = fl_filename_list(dir, &list, fl_alphasort);if (nbr_of_files <= 0)return false;int cnt = 0;for (int i = 0; i < nbr_of_files; i++) {char buf[512];const char* name = list[i]->d_name;if (!strcmp(name, ".") || !strcmp(name, "..")) continue;const char* p = strstr(name, ".gif");if (!p) p = strstr(name, ".GIF");if (!p) continue;if (*(p + 4)) continue; // is no extension!snprintf(buf, sizeof(buf), "%s/%s", dir, name);if (strstr(name, "debug")) // hack: when name contains 'debug' open single framesstrcat(flags, "d");if (openFile(buf, flags, cnt == 0))cnt++;}return cnt != 0;
}static void change_speed(double delta) {Fl_Widget* below = Fl::belowmouse();if (below && below->image()) {Fl_Anim_GIF_Image* animgif = 0;// Q: is there a way to determine Fl_Tiled_Image without using dynamic cast?Fl_Tiled_Image* tiled = dynamic_cast<Fl_Tiled_Image*>(below->image());animgif = tiled ?dynamic_cast<Fl_Anim_GIF_Image*>(tiled->image()) :dynamic_cast<Fl_Anim_GIF_Image*>(below->image());if (animgif && animgif->playing()) {double speed = animgif->speed();if (!delta) speed = 1.;else speed += delta;if (speed < 0.1) speed = 0.1;if (speed > 10) speed = 10;animgif->speed(speed);set_title(below->window(), animgif);}}
}static int events(int event) {if (event == FL_SHORTCUT) {if (Fl::event_key() == '+')change_speed(0.1);else if (Fl::event_key() == '-')change_speed(-0.1);else if (Fl::event_key() == '0')change_speed(0);elsereturn 0;return 1;}return 0;
}static const char testsuite[] = "testsuite";int fl_demo_main(int argc, char* argv[]) {// 注册图像文件类型判断回调fl_register_images();// 事件回调的注册Fl::add_handler(events);char* openFlags = (char*)calloc(1024, 1);if (argc > 1) {// started with argumemtsif (strstr(argv[1], "-h")) {printf("Usage:\n"" -t [directory] [-{flags}] open all files in directory (default name: %s) [with options]\n"" filename [-{flags}] open single file [with options] \n"" No arguments open a fileselector\n"" {flags} can be: d=debug mode, u=uncached, D=desaturated, A=color averaged, T=tiled\n"" m=minimal update, r[scale factor]=resize by 'scale factor'\n"" Use keys '+'/'-/0' to change speed of the active image (belowmouse).\n", testsuite);exit(1);}for (int i = 1; i < argc; i++) {if (argv[i][0] == '-')strcat(openFlags, &argv[i][1]);}if (strchr(openFlags, 't')) { // open all GIF-files in a given directoryconst char* dir = testsuite;for (int i = 2; i < argc; i++)if (argv[i][0] != '-')dir = argv[i];openDirectory(dir, openFlags);printf("Summary: good=%d, bad=%d, frames=%d\n", g_good_count, g_bad_count, g_frame_count);}else { // open given file(s)for (int i = 1; i < argc; i++)if (argv[i][0] != '-')openFile(argv[i], openFlags, strchr(openFlags, 'd'));}}else {// started without arguments: choose file// GIF图像显示为图片或动画的标志设置Fl_GIF_Image::animate = true; // create animated shared .GIF images (e.g. file chooser)while (1) {Fl::add_timeout(RedrawDelay, cb_forced_redraw); // animate images in chooser// 文件选择器UI的调用和返回// 用户选择通过文件选择器选择的文件,有可能不是指定尾缀的文件类型const char* filename = fl_file_chooser("Select a GIF image file", "*.{gif,GIF}", NULL);// 超时回调的移除Fl::remove_timeout(cb_forced_redraw);if (!filename)break;Fl_Window* win = openFile(filename, openFlags);// 等待当前窗体正常结束Fl::run();// delete last window (which is now just hidden) to test destructors// NOTE: it is essential that *before* doing this also the// animated image is destroyed, otherwise it will crash// because it's canvas will be gone.// In order to keep this demo simple, the adress of the// Fl_Anim_GIF_Image has been stored in the window's user_data.// In a real-life application you will probably store// it somewhere in the window's or canvas' object and destroy// the image in the window's or canvas' destructor.if (win && win->user_data())delete ((Fl_Anim_GIF_Image*)win->user_data());delete win;}}return Fl::run();
}
END
相关文章:
FLTK - FLTK1.4.1 - demo - animgifimage
文章目录 FLTK - FLTK1.4.1 - demo - animgifimage概述笔记END FLTK - FLTK1.4.1 - demo - animgifimage 概述 知识点: 注册图像文件类型判断回调 FLTK支持的图像格式 GIF, BMP, ICO, PNM, PNG, jpg, svg 事件回调的注册 GIF图像显示为图片或动画的标志设置 // 超时回调的设置…...
目前市场主流的AI PC对于大模型本地部署的支持情况分析-Deepseek
以下是目前市场主流AI PC对**大模型本地部署支持情况**的综合分析,结合硬件能力、软件生态及厂商动态进行总结: --- ### **一、硬件配置与算力支持** 1. **核心处理器架构** - **异构计算方案(CPUGPUNPU)**:主流…...
1.2 基于深度学习的底层视觉技术
文章目录 高层视觉任务与底层视觉任务深度神经网络相对于传统方法的优势 高层视觉任务与底层视觉任务 计算机视觉中的任务包含高层视觉任务,底层视觉任务。高层视觉任务是处理语义级别相关的任务,例如图像分类、目标检测、图像分割等。底层视觉任务处理与…...
HTML 标题
HTML 标题 引言 HTML(超文本标记语言)是构建网页的基础,而标题则是网页中不可或缺的元素。标题不仅能够帮助用户快速了解网页内容,还能够对搜索引擎优化(SEO)产生重要影响。本文将详细介绍HTML标题的用法…...
SOME/IP--协议英文原文讲解3
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 Note: Thi…...
Microsoft Visual Studio 2022 主题修改(补充)
Microsoft Visual Studio 2022 透明背景修改这方面已经有很多佬介绍过了,今天闲来无事就补充几点细节。 具体的修改可以参考:Microsoft Visual Studio 2022 透明背景修改(快捷方法)_material studio怎么把背景弄成透明-CSDN博客文…...
UE(UltraEdit) 配置简易C/C++编译运行环境
该类型其他帖子 EmEditor 配置简易C/C 编译运行环境_emeditor 代码运行-CSDN博客 RJ TextEd 配置简易C/C 编译运行环境-CSDN博客 这种配置适合ACM竞赛,即要求不使用现代IDE,又想用一个比较好用、至少支持代码高亮的编辑器。 前提条件 1.Mingw GCC 已…...
使用 MSYS2 qemu 尝鲜Arm64架构国产Linux系统
近期,我的师弟咨询我关于Arm64架构的国产CPU国产OS开发工具链问题。他们公司因为接手了一个国企的单子,需要在这类环境下开发程序。说实在的我也没有用过这个平台,但是基于常识,推测只要基于C和Qt,应该问题不大。 1. …...
python Flask-Redis 连接远程redis
当使用Flask-Redis连接远程Redis时,首先需要安装Flask-Redis库。可以通过以下命令进行安装: pip install Flask-Redis然后,你可以使用以下示例代码连接远程Redis: from flask import Flask from flask_redis import FlaskRedisa…...
在Windows系统中本地部署属于自己的大语言模型(Ollama + open-webui + deepseek-r1)
文章目录 1 在Windows系统中安装Ollama,并成功启动;2 非docker方式安装open-webui3下载并部署模型deepseek-r1 Ollama Ollama 是一个命令行工具,用于管理和运行机器学习模型。它简化了模型的下载与部署,支持跨平台使用,…...
Haproxy入门学习二
一、Haproxy的算法 1.haproxy通过固定参数balance指明对后端服务器的调度算法,其中balance参数可以配置在listen或backend选项中 2.haproxy的调度算法分为静态和动态调度算法,其中有些算法可以根据参数在静态和动态算法中相互转换 3.静态算法:…...
Git图形化工具【lazygit】
简要介绍一下偶然发现的Git图形化工具——「lazygit」 概述 Lazygit 是一个用 Go 语言编写的 Git 命令行界面(TUI)工具,它让 Git 操作变得更加直观和高效。 Github地址:https://github.com/jesseduffield/lazygit 主要特点 主要…...
node 爬虫开发内存处理 zp_stoken 作为案例分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 前言 主要说3种我们补环境过后如果用…...
基于Langchain-Chatchat + ChatGLM 本地部署知识库
一、相关环境 参考链接: Github:https://github.com/chatchat-space/Langchain-Chatchat Langchain-chatchat版本:v0.3.1 安装环境:Ubuntu:22.04,CUDA:12.1 二、搭建过程 2.1 环境配置 2.1.1 创建chatchat虚拟环…...
【C语言】main函数解析
一、前言 在学习编程的过程中,我们很早就接触到了main函数。在Linux系统中,当你运行一个可执行文件(例如 ./a.out)时,如果需要传入参数,就需要了解main函数的用法。本文将详细解析main函数的参数ÿ…...
【QT】- QUdpSocket
QUdpSocket 是 Qt 自带的一个类,属于 Qt 网络模块,用于进行 UDP(用户数据报协议) 通信。它提供了简便的接口来发送和接收 UDP 数据报(datagrams)。 UDP 是一种无连接的协议,适用于那些不需要确…...
性能测试丨分布式性能监控系统 SkyWalking
软件测试领域,分布式系统的复杂性不断增加,如何保证应用程序的高可用性与高性能,这是每一个软件测试工程师所面临的重大挑战。幸运的是,现在有了一些强大的工具来帮助我们应对这些挑战,其中之一便是Apache SkyWalking。…...
SQL GROUP BY 详解
SQL GROUP BY 详解 引言 在数据库查询中,GROUP BY 子句是一个非常有用的工具,它允许我们对查询结果进行分组,并基于这些分组进行聚合计算。本文将详细介绍 GROUP BY 的用法、注意事项以及在实际应用中的场景。 什么是 GROUP BY? GROUP BY 子句用于对查询结果进行分组。…...
C语言中string.h头文件功能介绍
在C语言的世界里,string.h头文件提供了许多用于处理字符串和内存操作的函数。今天,我们就来深入探讨string.h头文件的功能、使用注意事项以及一些拓展应用。 一、功能介绍 string.h头文件定义了一系列用于操作字符串和内存的函数。这些函数可以分为几个…...
从规则到神经网络:机器翻译技术的演进与未来展望
从规则到神经网络:机器翻译技术的演进与未来展望 引言 还记得早些年用翻译软件翻译一句简单的英文句子,却发现翻译结果让人啼笑皆非的日子吗?从“我喜欢吃苹果”被翻译成“我喜欢吃苹果电脑”,到今天的神经网络机器翻译(Neural Machine Translation, NMT)能够生成语义流…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
