Pride Month, better MobiPocket performance and progress in Chessament
Welcome to a new issue of "This Week in KDE Apps"! Every week we cover as much as possible of what's happening in the world of KDE apps.
This week issue is a bit special as it is also covering the past week as last Sunday some other contributors and me were busy at the KDE booth at the Umweltfestival in Berlin.
Additionally, as it is the beginning of Pride Month, I would like to take this opportunity to celebrate and acknowledge the invaluable contributions of LGBTQIA+ members within the KDE community. Their work, creativity, and dedication continue to enrich our project and foster a more inclusive and diverse environment for all.
This celebration is especially important at a time when many large tech corporations are rolling back their visible support for the LGBTQIA+ community. KDE and other grass roots organisations have your back!
Getting back to all that's new in the KDE App scene, let's dig in!
Stefan Brüns speed up the parsing of MobiPocket files considerably (25.08.0 - link 1, link 2 and link 3) and also fixed some parsing issues (link1 and link 2). These changes were implemented in QMobiPocket and improve the rendering speed in Okular for MobiPocket documents but also speed up Baloo indexing of these files and the creation of thumbnails in Dolphin.
Carl Schwan did some further improvements and reduced the number of temporary allocations (link 1, link 2 and link 3)
Carl Schwan fixed the detection of HTML inside mobipocket files (25.04.3 - link).
Sune Vuorela improved the scaling of stamps for annotations (25.08.0 - link). Now, when using a non-default sized stamp, the stamp won't appear pixelated anymore.
Volker added a departure details dialog. This dialog contains service alerts, occupancy information, vehicle amenities and the operator information when available (link), and published his bi-monthly blog post about all the changes in Itinerary, KTrip, Transitous and co.
Johannes Krattenmacher added ticket extractors for Stena, Viking and IHG (link).
Victor Blanchard added an off-by-default setting to automatically switch to icons view mode in folders with a lot of image or video files (25.08.0 - link).
Kai Uwe Broulik simplified how locations in window and tab titles for search results pages are displayed (25.08.0 - link).
Vladislav Kachegov fixed an incorrect view reset when unmounting similarly-named devices (link).
Joshua Goins made it possible to boost your own private post (25.04.03 - link), improved the tooltips for disabled polls and attachment buttons (25.08.0 - link) and did some small improvements to the multi account handling (link).
Joshua also limited the number of poll choice using the limit defined by the server (25.08.0 - link) and fixed a crash when clicking on "Mark as Read" on the notifications page (25.04.3 - link).
Anyone familiar with my blog will know that I like to write about incense. A reader wrote to me some time ago asking about what sticks I’ve been enjoying lately, and it occurred to me that it might be a nice thing to have a “now listening” type feature on my website, so that fellow incense heads could get a sense of the types of incense I like. After all, while I write plenty of incense reviews, they represent only a small percentage of the sticks, cones, powders, woods, and resins I’m burning or heating from day to day. (If you’re here for my incense content, feel free to skip this one and head to /now-burning to see the new feature!)
While it would have been simple enough for me to build a microblogging feature into my Eleventy website, the trouble was wanting to use it after it was built. Unlike using a CMS such as WordPress to make a website, I knew of no nice interface for Eleventy, or for that matter any SSG, that would help me create a post and publish it online without opening an IDE[1] and using the command line. Instead, the process looks something like this:
I don’t necessarily want to feel like a hackerman every time I decide to make a tiny status update. Also, I just noticed that I totally screwed up the frontmatter for that post.
As big of a nerd as I am, I’m just not going to want to do that multiple times a day for what amounts to a status post. This lead me to scour the internet looking for a solution: something that I could run on my own desktop or laptop that could build my site locally and push changes to my website, hosted the old fashioned way: as a bunch of text files sitting on a server accessible via SFTP. No needless complexity like running Eleventy on the server, or using a host like Netlify.[2] Surely there’d be something, right? Surely, the realm of SSGs can’t be without at least one nice, local user interface that people can use without being a web developer?
In the end, I did find one answer to the problem: Publii. Publii seems to be made predominantly with end-users in mind, however. It’s not just a local[3] CMS, it’s an SSG in its own right, which does me no good as I can’t make it work with my website[4]. So after coming up with nothing I could use, I gave the idea a rest for a while until I had the epiphany that I could solve the problem with a simple script using KDE’s KDialog to provide a rudimentary UI. So that’s what I did.
The idea was simple: a wizard-like experience that guides the user through the creation of a microblog / status post. Post types and the data they collect should be customized by the user via a JSON configuration file. After the post data is collected from the user, the script should execute a user-defined build command as well as a user-defined command to sync the static files to the server.
For some reason, I decided to write my script in Ruby, a language for which I once completed a course before promptly forgetting everything I knew about it. I would have had a much easier time using JavaScript and Node, which I am much more familiar with and have successfully used for similar purposes. Why I did not is anyone’s guess. All this to say: please do not make (too much) fun of my shitty little script, which I have dubbed “Poaster.”
I started with the JSON configuration file, /Poaster/config/config.json:
Here, the user can specify as many post types as they like, each with their own output directory. Each post type can also collect as many pieces of frontmatter as the user cares to specify.
The first thing the script needed to do was ask the user which post type they want to create, so I referenced the KDialog tutorial and wrote a method to handle that /Poaster/lib/spawn_radio_list.rb:
I wrote a few more methods in /Poaster/lib to spawn toast notifications, input boxes, create directories if they don’t exist, and write files:
/Poaster/lib/spawn_toast.rb:
defensure_dir_exists(directory_path)unlessDir.exist?(directory_path)
FileUtils.mkdir_p(directory_path)
spawn_toast 'Directory Created',%(Poaster created #{directory_path}.),10endend
/Poaster/lib/write_file.rb:
defwrite_file(directory, name, extension, content)
post_file =File.new(%(#{directory}/#{name}.#{extension}),'w+')
post_file.syswrite(content)
post_file.close
end
All I had to do then was tie it all together in /Poaster/poaster.rb:
#!/usr/bin/env rubyrequire'json'require'fileutils'require'./lib/spawn_input_box'require'./lib/spawn_radio_list'require'./lib/spawn_toast'require'./lib/ensure_dir_exists'require'./lib/write_file'
config_data =JSON.parse(File.read('./config/config.json'))
dialog_title_prefix ='Poaster'# Populate types_arr with post types
post_types_arr =[]
config_data['postTypes'].eachdo|type|
post_types_arr.push(type['name'])end# Display post list dialog to user
post_type = config_data['postTypes'][Integer(spawn_radio_list(dialog_title_prefix,'Select a post type:', post_types_arr))]# Set the word we will use to refer to the post
post_unit = post_type['postUnitName']# Collect frontmatter from user
frontmatter =[]
post_type['frontMatter'].eachdo|item|
frontmatter.push({ item['name']=> spawn_input_box(%(#{dialog_title_prefix} - Enter Frontmatter'),%(Enter #{post_unit}#{item['name']}:))})end# Collect post content from user
post_content = spawn_input_box %(#{dialog_title_prefix} - Enter Content),%(Enter #{post_unit} content:)# Make sure the output folder exists
post_directory = post_type['postDirectory']
ensure_dir_exists(post_directory)# Create post string
post =%(---\n)
post_id =''
frontmatter.each_with_index do|item, i|
post +=%(#{item.keys[0]}: #{item[item.keys[0]]})
post_id +=%(#{item[item.keys[0]].chomp}#{i == frontmatter.length -1?'':'_'})end
post +=%(---\n#{post_content})# Write post string to file and notify user
post_file_name =%(#{post_type['name']}_#{post_id.chomp})
post_extension ='md'
write_file post_directory, post_file_name, post_extension, post
spawn_toast 'File Created',%(Poaster created #{post_file_name}#{post_extension} at #{post_directory}.),10# Run build and upload commands`cd #{config_data['siteDirectory']} && #{config_data['buildCommand']} && #{config_data['uploadCommand']}`
There is a lot that this script should do that it doesn’t, but for now, it’s still a handy wee utility for SSG users on GNU/Linux systems running KDE who want to make creating quick status-type posts a little less painful. Just make sure KDialog is installed (as well as Ruby, naturally), clone the repo, create /Poaster/config/config.json to meet your needs using the example as a reference and you’re off to the races! I’ve even made a silly little toaster icon using assets from some of the KDE MimeType icons that you can use if you want to make a .desktop file so that you can click an icon on your app launcher to start the script.
Isn’t that nice?
My poaster.desktop file looks something like this:
[Desktop Entry]Exec=/path/to/poaster.rb
GenericName[en_US]=Create a post with Poaster.
GenericName=Create a post with Poaster.
Icon=/path/to/poaster_icon.svg
Name=Poaster
NoDisplay=false
Path=/path/to/repo/
StartupNotify=true
Terminal=false
Type=Application
Here’s the script in action:
The ease! The convenience!
To build the new “now burning” incense microblog feature, I created two new pages. /now-burning shows the latest entry:
---
layout: layouts/base.njk
title: "Nathan Upchurch | Now Burning: What incense I'm burning at the moment."
structuredData: none
postlistHeaderText: "What I've been burning:"
---
{% set burning = collections.nowBurning | last %}
<h1>Now Burning:</h1><articleclass="post microblog-post"><imgclass="microblog-icon"src="/img/censer.svg"><divclass="microblog-status"><h2class="">{{ burning.data.title }}{% if burning.data.manufacturer %}, {{ burning.data.manufacturer }}{% endif %}, {{ burning.date | niceDate }}, {{ burning.data.time }}</h2>
{% if burning.content %}
<divclass="microblog-comment">
{{ burning.content | safe }}
</div>
{% endif %}
</div></article><ahref="/once-burned/"><buttontype="button">Previous Entries »</button></a>
---
layout: layouts/base.njk
title: "Nathan Upchurch | Once Burned: Incense I've burning in the past."
structuredData: none
---
{% set burning = collections.nowBurning | last %}
<h1>Previous “Now Burning” Entries:</h1>
{% set postsCount = collections.nowBurning | removeMostRecent | length %}
{% if postsCount > 0 %}
{% set postslist = collections.nowBurning | removeMostRecent %}
{% set showPostListHeader = false %}
{% include "incenseList.njk" %}
{% else %}
<p>Nothing’s here yet!</p>
{% endif %}
<ahref="/now-burning/"><buttontype="button">Latest »</button></a>
…using a post-listing include built specifically for microblogging:
<sectionclass="postlist microblog-list">
{% if postlistHeaderText %}<h2>{{ postlistHeaderText }}</h2>{% endif %}
<divclass="postlist-item-container">
{% for post in postslist | reverse %}
<articleclass="postlist-item"><divclass="post-copy"><h3>
{% if post.data.title %}{{ post.data.title | safe }}{% else %}?{% endif %}{% if post.data.manufacturer %}, {{ post.data.manufacturer | safe }}{% endif %}
</h3><divclass="post-metadata"><divclass="post-metadata-copy"><p><timedatetime="{{ post.date | htmlDateString }}">{{ post.date | niceDate }}{% if post.data.time %}—{{ post.data.time }}{% endif %}</time></p></div></div>
{% if post.content %}
<divclass="microblog-comment">
{{ post.content | safe }}
</div>
{% endif %}
</div></article><hr>
{% endfor %}
</div></section>
And that’s about it! There’s a lot to do to make the script a little less fragile, such as passing along build / upload error messages, allowing for data validation via regex, et cetera. I’m sure I’ll get to it at some point. If Poaster is useful to you, however, and you’d like to submit a patch to improve it, please do let me know.
Yes, I am aware that Kate isn’t technically
an IDE. ↩︎
At risk of sounding crabbit and behind the times, I don’t know why web
development has to be so damned complicated these days. Like, an entire fancy
for-profit infrastructural platform that exists just to host static websites?
It seems nuts to me. ↩︎
Thank christ. Why does everything need to run in the cloud when we
already have computers at home? ↩︎
I did however use it to very quickly set up a nice looking blog site for
my partner. ↩︎
The first week of my Google Summer of Code journey with the KDE community has nearly come to an end, and it’s been an exciting start. As a quick reminder, my project — “Merkuro – Porting Away from QtWidgets” — focuses on making Akonadi components leaner by decoupling their UI from core logic and reducing dependencies on QtWidgets.
Choosing Where to Begin
Originally, I planned to begin with the KMail agents. However, after discussing it with one of my mentors, Claudio, we realized that these agents may benefit from more than just UI decoupling — they are prime candidates to be moved into the kdepim-runtime repository. This would help consolidate Akonadi agents and resources for better maintainability and cohesion.
Because this is a larger architectural change, we agreed it would be more effective to tackle it later in the project.
Refocusing on Resources Within kdepim-runtime
I shifted my focus to the agents and resources already in kdepim-runtime. I was pleased to see that some groundwork for decoupling had already been laid for resources like DAV, Google, and IMAP, giving me a solid reference to work from.
With a clear direction, I chose the EteSync resource as my first decoupling target.
Decoupling the EteSync Resource
This week, I carried out three main tasks:
Refactoring the Core Code I modified etesyncresource.cpp/.h and etesyncclientstate.cpp/.h to remove all UI-related logic previously embedded in the core functionality.
Updating the Build System I adjusted the CMakeLists.txt to ensure the resource no longer compiles or links against any QtWidgets-based code.
Creating the UI Plugin I created a dedicated configuration plugin consisting of etesyncconfig.cpp and its corresponding .json metadata file. All UI-related code now lives in this separate plugin.
Testing with Akonadi Console
To verify my changes, I’ve been using the Akonadi Console, a powerful tool that lets developers inspect and manage Akonadi agents and resources in real time. My goal is to ensure the refactored EteSync resource functions correctly in Merkuro, Kontact, and any other application that uses Akonadi.
What’s Next?
Before submitting a merge request, I plan to carry out thorough initial testing to ensure everything is stable and there are no regressions. Once the EteSync resource is confirmed to work cleanly with the plugin, I’ll move on to the next target in the decoupling process.
It’s been a productive first week, and I’m looking forward to building on this momentum in the weeks to come!
Hi all! My name is Ross Rosales. I am a self-taught Software Engineer and former Registered Nurse with a background in the Emergency Deparment. Through the great community of KDE and Open Source I gained so much valuable experience that I apply in my everyday career and life. As I continue learning everyday, I want to share what I'll be working on over the next 12 weeks.
About Krita
Krita is an amazing open source and free painting program with countless growing features. Although I may not paint or draw very well myself, I've always admired how artists are able to create anything they can put their mind to with the tools at their disposal. My goal is to contribute to Krita and support all artists by helping their ideas become reality.
Proposal
To make artists' workflow easier, this GSoC I plan to create a floating toolbar that will contain common selection actions artists frequently switch between. The idea is to improve accessibility to tools that may not be intuitive to new or experienced users. Link to my proposal
Plans
In addition to sharing my progress on the Selection Action Bar for GSoC, I also plan to write about how new contributors can join the KDE community and reduce the barrier to entry for Krita. I’ll do this through personal walkthroughs covering environment setup, writing code for the first time, engaging with the community, and providing quick links to helpful resources—all in one place.
Special Thanks
Thank you to the KDE and Krita communities for giving me the opportunity to join such an amazing group of individuals. Special thanks to Dmitry, Emmet, Halla, Tiar, Wolthera, and everyone I interact with in Krita Chat!
Contact
To anyone reading this, please feel free to reach out to me. I’m always open to suggestions and thoughts on how to improve as a developer and as a person. Email: ross.erosales@gmail.com Matrix: @rossr:matrix.org
For the June Art Challenge, @Mythmaker has passed the honor of choosing the topic to regular participant @Corentin, who has chosen "Wrath of the Sun" as the theme. Interpret this title however you want, optionally include some sort of decorative design, and have fun with the sun!
Take a look at the nominations for next month, and suggest your favorite latest artworks to be featured. Don't forget to vote when the poll opens on June 11th!
Ways to Help Krita
Krita is Free and Open Source Software developed by an international team of sponsored developers and volunteer contributors. That means anyone can help make Krita better!
Support Krita financially by making a one-time or monthly monetary donation. Or donate your time and Get Involved with testing, development, translation, documentation, and more. Last but not least, you can spread the word! Share your Krita artworks, resources, and tips with others, and show the world what Krita can do.
Other Notable Changes
Other notable changes in Krita's development builds from May 8 - June 6, 2025.
Stable branch (5.2.10-prealpha):
General: Fix a crash when autosaving heavy images with lots of compositions and an adjustment layer with vector selection. (Change, by Dmitry Kazakov)
File Formats: TIFF: Fix TIFF file size bloating after each overwrite. (Change, by Igor Danilets)
General: Change Resize Canvas's 'Constrain proportions' toggle to not reset the canvas size. (bug report) (Change, by Halla Rempt)
Linux: Upgrade AppImage base to Ubuntu 2204. (Change, by Dmitry Kazakov)
Unstable branch (5.3.0-prealpha):
Bug fixes:
Android: Fix the Text Properties Docker being blank. (bug report) (Change, by Dmitry Kazakov)
General: Fix floating toolbars disappearing on restart. (bug 504463) (Change, by Freya Lupen)
Python Plugins: Workflow Buttons Docker: Fix Pan and Text Tool buttons. (bug report) (Change, by Freya Lupen)
Features:
Text Properties Docker: Allow configuring when each property should be shown in the list; always, never, when set, or when relevant (inherited or set). (Change, by Wolthera van Hövell)
Text Properties Docker: Add Text Rendering property, for antialiasing/hinting options. (Change, by Wolthera van Hövell)
SVG: Handle SVG title and desc metadata. (Change, by Wolthera van Hövell)
Shortcuts/Toolbars: Add Force Palette Colors action to limit color selection to colors in the palette. (Change, by Halla Rempt)
Python Plugins/Scripting: Add and use FileDialog class, which uses Krita's wrapper around QFileDialog in order to respect Krita's "Don't use native file dialogs" setting. (bug report, bug report) (Change, by Freya Lupen)
Nightly Builds
Pre-release versions of Krita are built every day for testing new changes.
I’ve written a small Neovim plugin which might be useful to people
who often work on several projects in parallel.
It activates a specific theme based on the project you are working on
(the current directory you start Neovim from).
It allows you to define which themes should be used for which
projects. The configuration is simple and allows specifying patterns for
matching project names (not full regex, but what Lua supports).
My configuration looks something like this (this is in Fennel, for
the Lua version, check out the readme):
Since that time you can install it easily from here and the store will allow you to keep our application updated.
Kate is not the only KDE application there, other stuff uploaded under the KDE e.V. umbrella can be found here, this includes KDE Connect and Okular.
We have now better documentation and tooling for store submissions, the last update of Kate to 25.04 was, beside the local testing of the build if it is not broken in normal use, the press of one button.
Compared to my old guide from my first submission, that is really awesome, thanks a lot to all people that worked on that!
What if I don't like the Microsoft Store?
Naturally you don’t have to use the store (which implies some account you might not want and telemetry that you might want even less).
Alternate downloads are on our normal download page.
Or, if you want to be even more in control, and perhaps even willing to contribute, build it from source yourself, Craft makes that easy.
The Microsoft Store submissions are just a way to reach a larger audience.
Some people might even not be able to install stuff from other sources, depending how locked down their Windows installation is.
Current Statistics
Below the current statistics of the published applications sorted by acquisitions, that means more or less means individual user installs.
Not that bad, over half a million installs for KDE Connect, close to half a million for Okular and a quarter million for Kate.
Current Ratings
The internal statistics of the store allow to see the ratings over the whole publishing time.
They look good, too.
KDE Connect Ratings
Okular Ratings
Kate Ratings
The Future?
We will need to update the versions in the store, Kate is now on 25.04, more to follow hopefully.
We need help with fixing Windows only bugs, too.
Just a random one for Kate can be found here.
Comments?
A matching thread for this can be found here on KDE Social or r/KDE.
A few years ago, I was among those who found Wayland too painful to use every day. Over time, I gave Wayland a try now and then. It finally got usable enough for me to switch to as my default a couple of years ago.
Recently, during the soft freeze before the Plasma 6.4 Beta was released, I used mainly X11 on both my laptops - for science! And by science, I mean regression testing. I was curious what the experience was like compared to what I've become accustomed to with Wayland.
In short, Wayland supports multiple displays and color so much better. It was painful using X11 again.
My setup for daily work
I was using two laptops and two external monitors. Both were running Plasma built from git-master.
Main: Dell XPS laptop, plugged into a dock. This is connected to 2 ultrawide monitors - one via Displayport, the other via HDMI.
Secondary: Lenovo Flex laptop, usually just using its built-in screen. Sometimes I swap the right hand monitor over to it, for testing display shenanigans.
Initial impression - so limited
I fired up the XPS, did updates, and booted into an X11 session. Next, to Display Configuration to re-enable the right hand monitor (disabled the night before). Immediately, I was struck by how bare the settings window looks compared to Wayland. Here are screenshots of the settings for same HDR monitor on 6.3.5.
Wayland:
X11:
Second thoughts and hello, Dr Konqi
Time to enable the display. For reference, this takes moments in Wayland. It was just a wee bit longer and more fraught with X11.
After enabling the monitor and clicking Apply, all 3 screens went dark. After about 20s the laptop display came on. After about another minute, the right hand display finally got output before all 3 displays were dark again. I unplugged the laptop from the dock. It came up to the login screen. After logging in I saw the good Dr Konqi telling me there was a crash in plasmashell. We were off to a great start.
Like a good tester, I sent the crash report off. With some trepidation, I plugged the docking cable back in, as similar struggles from years past came back to haunt me. All three displays were black, although I could move the cursor around in them. It took a good couple of minutes for plasmashell to display everything, along with window decorations and panel contents. It was faster later, but wow, was this a noticeably worse experience than Wayland.
Other observations, or third thoughts
Wayland advantages
Fractional scaling - the ability to have a screen at, say, 110% zoom. See that lovely screenshot, above. When paired with how easy it is to change font face and style, this is great for accessibility. Being able to read the text on any display at whatever resolution can't be overstated. When I have to use Windows, where you can't adjust text separately from resolution, I have sadness. I also have eyestrain trying to read tiny text in dialogs.
Scaling per display - so my laptop's high resolution display can be at 150% and my external displays at 100% to make things readable on all of them. Another plus for accessibility.
HDR and color profile (ICC) support. This is important for getting the mos out of my monitor with games and more. Also... preeeetty.
Snappier overall performance (on my systems).
The ability to send a window to multiple desktops, or just one. In X11, you can ....THNG
The most annoying problem for me is with LibreOffice, since I use Calc almost daily. There's a bug (on their tracker) where, with multiple monitors with different scale factors, UI elements are too big.
Lack of a robust, easy to use text expander with a GUI - that actually works out of the box. Autokey has been on my installs for many years, used for work and personal stuff. While it launches, and I have access to my phrases, there's no actual text expansion. There's an open issue for Wayland support (that pre-dates the Pandemic) but it hasn't gotten much traction. I've been keeping an eye out for years for a decent replacement, and have tried a few things but not found what I'm looking for, yet.
Copy and paste to and from VMs
I use VMs a lot for testing things on different Linux distros. My workaround for this is to have text files saved in a directory that's shared from host to guest.
It took time and a few forks to get KVM software that was reliably developed and worked with Wayland.1 I had been using barrier on X11. A few software forks and experiments later, I've settled on deskflow.
X11 Advantages
Remembering window positions across reboots.
Working text expansion.
X11 pain points
Drawing the screen is slower after logging in or restarting plasmashell, for example, with the same hardware and open applications.
Floating panels and adaptive opacity are known to cause performance issues with X11 with an NVIDIA GPU.
Lack of scaling per-monitor. Text on my XPS's screen is too small to be readable if the external monitors are at a comfortable scale. I had to move any window I needed to read text on (most of them) to the external monitors.
The HDMI monitor was set to the wrong resolution and refresh rate if I connected it to the second laptop. I had to manually correct it.
After enabling HDR on that monitor with the Flex in Wayland, and switching to an X11 session, the monitor enabled HDR but the colors were over-saturated.
After working with a few windows, fonts in Firefox became badly hinted. This made characters look weirdly colored instead of white / black, and made reading things difficult.
Final thoughts
Once upon a time, Wayland was too painful for me to use as a daily driver. It didn't support some of my utilities and it wasn't stable enough with my multi-monitor setup.
These days, Wayland is so much more usable and stable with multiple displays that it makes using X11 painful by comparison. While there are still those few issues I mentioned, I feel Wayland's advantages outweigh them.
The KVM software journey... The first one I used was Synergy, which was amazing to me. Being able to use the same keyboard and mouse on both a Linux laptop and Windows desktop at the same time was magic. Unfortunately, Synergy took their UI in directions I didn't like. An open source fork named barrier emerged, which aimed to restore the simplicity I was looking for, so I switched to it. This served me for a long time, but development stopped in 2021. With the advent of Wayland, barrier was forked to input-leap which implemented Wayland support. Sadly, development seems to have languished. There is yet another project, deskflow, which is also free and open source. It's sponsored by the Synergy folks. We end where we began. ↩︎