<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Mélian Fruchart</title><link>https://www.melianfruchart.fr/</link><description>Recent content on Mélian Fruchart</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 15 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.melianfruchart.fr/index.xml" rel="self" type="application/rss+xml"/><item><title>WikiGraph</title><link>https://www.melianfruchart.fr/posts/projects/wikigraph/</link><pubDate>Tue, 15 Sep 2026 00:00:00 +0000</pubDate><guid>https://www.melianfruchart.fr/posts/projects/wikigraph/</guid><description>&lt;p&gt;Web-based real-time multiplayer game, where players navigate through Wikipedia pages by clicking on internal links in order to reach one or more target pages.&lt;/p&gt;
&lt;p&gt;WikiGraph was hosted at &lt;a href="https://wikigraph.fr" target="_blank"&gt;wikigraph.fr&lt;/a&gt;, but is no longer available since October 7th 2026. It will be brought up again in the future.&lt;/p&gt;
&lt;h2 id="image-gallery"&gt;Image gallery&lt;/h2&gt;
&lt;p&gt;WikiGraph menus.
&lt;style&gt;
.carousel-indicators img[data-bs-target] {
width: 60px !important;
height: 40px !important;
object-fit: cover;
cursor: pointer;
margin: 0 4px;
border: 2px solid transparent !important;
border-radius: 4px;
opacity: 0.5;
transition: opacity 0.2s;
flex-shrink: 0 !important;
min-width: 60px !important;
box-shadow: 0 0 3px rgba(0,0,0,0.5);
text-indent: 0;
}
.carousel-indicators img[data-bs-target].active {
border-color: #fff !important;
opacity: 1;
}
.carousel-control-prev-icon,
.carousel-control-next-icon {
filter: drop-shadow(0px 0px 2px rgb(0, 0, 0));
}
.carousel-item img.inline-img {
cursor: zoom-in;
}
.modal-carousel-bg {
background-color: rgba(0,0,0,0.4);
}
.carousel-control-prev,
.carousel-control-next {
width: 5% !important;
}
.carousel-item {
transition: transform 0.15s ease-in-out !important;
}
.carousel-indicators {
flex-wrap: nowrap !important;
overflow-x: auto;
gap: 8px;
justify-content: flex-start !important;
padding: 0 !important;
-ms-overflow-style: none;
scrollbar-width: none;
}
.carousel-indicators::-webkit-scrollbar {
display: none;
}
.carousel-indicators::before,
.carousel-indicators::after {
content: "";
flex: 0 0 calc(50% - 30px);
}
.carousel-indicators-inline {
position: absolute !important;
bottom: 1rem;
margin: 0 !important;
left: 0;
right: 0;
z-index: 15;
}
.carousel-indicators-modal {
position: relative !important;
margin-top: 1rem !important;
margin-bottom: 1rem !important;
}
&lt;/style&gt;
&lt;div id="carousel-gallery_menus" class="carousel slide mb-5"&gt;
&lt;div class="carousel-inner rounded shadow-sm"&gt;
&lt;div class="carousel-item active"&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/0.webp" class="d-block w-100 inline-img" alt="Gallery Image"
data-bs-toggle="modal" data-bs-target="#modal-carousel-gallery_menus"
onclick="document.getElementById('modal-thumb-carousel-gallery_menus-0').click()"&gt;
&lt;/div&gt;
&lt;div class="carousel-item "&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/1.webp" class="d-block w-100 inline-img" alt="Gallery Image"
data-bs-toggle="modal" data-bs-target="#modal-carousel-gallery_menus"
onclick="document.getElementById('modal-thumb-carousel-gallery_menus-1').click()"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="carousel-indicators carousel-indicators-inline"&gt;
&lt;img id="modal-thumb-carousel-gallery_menus-0"
src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/0.webp"
data-bs-target="#carousel-gallery_menus"
data-bs-slide-to="0"
class="active" aria-current="true"
aria-label="Slide 1"&gt;
&lt;img id="modal-thumb-carousel-gallery_menus-1"
src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/1.webp"
data-bs-target="#carousel-gallery_menus"
data-bs-slide-to="1"
aria-label="Slide 2"&gt;
&lt;/div&gt;
&lt;button class="carousel-control-prev" type="button" data-bs-target="#carousel-gallery_menus" data-bs-slide="prev"&gt;
&lt;span class="carousel-control-prev-icon" aria-hidden="true"&gt;&lt;/span&gt;
&lt;span class="visually-hidden"&gt;Previous&lt;/span&gt;
&lt;/button&gt;
&lt;button class="carousel-control-next" type="button" data-bs-target="#carousel-gallery_menus" data-bs-slide="next"&gt;
&lt;span class="carousel-control-next-icon" aria-hidden="true"&gt;&lt;/span&gt;
&lt;span class="visually-hidden"&gt;Next&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;div class="modal fade" id="modal-carousel-gallery_menus" tabindex="-1" aria-hidden="true"&gt;
&lt;div class="modal-dialog modal-dialog-centered" style="max-width: 90vw;"&gt;
&lt;div class="modal-content bg-transparent border-0"&gt;
&lt;button type="button" class="btn-close btn-close-white position-absolute top-0 end-0 m-2" data-bs-dismiss="modal" aria-label="Close" style="z-index: 1055; filter: drop-shadow(0px 0px 4px rgba(0,0,0,0.9));"&gt;&lt;/button&gt;
&lt;div class="modal-body p-0"&gt;
&lt;div id="modal-carousel-carousel-gallery_menus" class="carousel slide" data-bs-keyboard="true"&gt;
&lt;div class="carousel-inner rounded shadow-lg modal-carousel-bg"&gt;
&lt;div class="carousel-item active"&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/0.webp" class="d-block w-100" alt="Enlarged Gallery Image" style="max-height: 70vh; object-fit: contain;"&gt;
&lt;/div&gt;
&lt;div class="carousel-item "&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/1.webp" class="d-block w-100" alt="Enlarged Gallery Image" style="max-height: 70vh; object-fit: contain;"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="carousel-indicators carousel-indicators-modal"&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/0.webp"
data-bs-target="#modal-carousel-carousel-gallery_menus"
data-bs-slide-to="0"
class="active" aria-current="true"
aria-label="Slide 1"&gt;
&lt;img src="https://www.melianfruchart.fr/posts/projects/wikigraph/gallery_menus/1.webp"
data-bs-target="#modal-carousel-carousel-gallery_menus"
data-bs-slide-to="1"
aria-label="Slide 2"&gt;
&lt;/div&gt;
&lt;button class="carousel-control-prev" type="button" data-bs-target="#modal-carousel-carousel-gallery_menus" data-bs-slide="prev"&gt;
&lt;span class="carousel-control-prev-icon" aria-hidden="true"&gt;&lt;/span&gt;
&lt;span class="visually-hidden"&gt;Previous&lt;/span&gt;
&lt;/button&gt;
&lt;button class="carousel-control-next" type="button" data-bs-target="#modal-carousel-carousel-gallery_menus" data-bs-slide="next"&gt;
&lt;span class="carousel-control-next-icon" aria-hidden="true"&gt;&lt;/span&gt;
&lt;span class="visually-hidden"&gt;Next&lt;/span&gt;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;script&gt;
document.addEventListener("DOMContentLoaded", function() {
if (!window.hasCarouselKeyboardListener) {
window.hasCarouselKeyboardListener = true;
document.addEventListener('keydown', function(event) {
if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {
const activeModal = document.querySelector('.modal.show');
if (activeModal) {
const arrowSelector = event.key === 'ArrowLeft' ? '.carousel-control-prev' : '.carousel-control-next';
const arrowButton = activeModal.querySelector(arrowSelector);
if (arrowButton) {
arrowButton.click();
}
}
}
});
}
function centerThumb(container, thumb, behavior) {
if (!container || !thumb) return;
const scrollLeft = thumb.offsetLeft + (thumb.offsetWidth / 2) - (container.clientWidth / 2);
container.scrollTo({ left: scrollLeft, behavior: behavior });
}
document.querySelectorAll('.carousel').forEach(function(carousel) {
carousel.addEventListener('slide.bs.carousel', function(event) {
const container = carousel.querySelector('.carousel-indicators');
if (container &amp;&amp; container.clientWidth &gt; 0) {
centerThumb(container, container.children[event.to], 'smooth');
}
});
});
document.querySelectorAll('.modal').forEach(function(modal) {
modal.addEventListener('shown.bs.modal', function () {
const container = modal.querySelector('.carousel-indicators');
const activeThumb = container ? container.querySelector('.active') : null;
if (container &amp;&amp; activeThumb) {
centerThumb(container, activeThumb, 'instant');
}
});
});
});
&lt;/script&gt;&lt;/p&gt;</description></item><item><title>Space Charity: a real-time web auction application</title><link>https://www.melianfruchart.fr/posts/projects/space_charity/</link><pubDate>Thu, 20 Jan 2022 00:00:00 +0000</pubDate><guid>https://www.melianfruchart.fr/posts/projects/space_charity/</guid><description>&lt;p&gt;Space-charity is a (fake) real-time auction application. It was developed as an academical project in the 2nd year of my bachelor&amp;rsquo;s degree.&lt;/p&gt;
&lt;h2 id="project-instructions"&gt;Project instructions&lt;/h2&gt;
&lt;p&gt;Develop a collaborative, real-time client-server auction application for individuals (B2C or C2C). Auctions may involve personal property or real estate.&lt;/p&gt;
&lt;p&gt;Some more details:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There are different auction mechanisms. We needed to explore them, choose one, and
analyze the specific features that would impact our requirements.&lt;/li&gt;
&lt;li&gt;We also needed to clearly define the type of assets that would be put into auction, and verify that there are no restrictive regulations applying to them&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="why-space-charity"&gt;Why &amp;ldquo;Space Charity&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;We had the idea of using objects that should not be able to be put to auction: &lt;strong&gt;planets and stars&lt;/strong&gt;.&lt;/p&gt;</description></item></channel></rss>