0 Votes

Changes for page Conditioning

Last modified by Ryan C on 2025/09/15 10:19

From version 62.1
edited by Ryan C
on 2025/09/15 10:19
Change comment: There is no comment for this version
To version 3.1
edited by XWikiGuest
on 2025/04/25 22:58
Change comment: There is no comment for this version

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.AdminAngriff
1 +XWiki.XWikiGuest
Content
... ... @@ -1,461 +1,32 @@
1 -{{velocity}}
2 -#pagePicker_import
1 +{{box cssClass="floatinginfobox" title="**Contents**"}}
2 +{{toc/}}
3 +{{/box}}
3 3  
4 -## 1) Collect video attachments on this page
5 -#set($videoExts = ['mp4','webm','ogg','avi','mov','wmv','flv','m4v'])
6 -#set($videos = [])
7 -#foreach($att in $doc.getAttachmentList())
8 - #set($n = $att.getFilename())
9 - #set($ln = $n.toLowerCase())
10 - #foreach($e in $videoExts)
11 - #if($ln.endsWith("." + $e))
12 - #set($discard = $videos.add($att))
13 - #break
14 - #end
15 - #end
16 -#end
5 += Paragraph 1 =
17 17  
18 -## 2) Cache HTML (auto-bust on version)
19 -{{cache id="vid-list-$doc.fullName-$doc.version" timeToLive="21600"}}
20 -{{html wiki="false" clean="false"}}
21 -<div id="xwiki-video-manager" style="margin:20px 0;">
22 - <h2>📹 Videos on: ${escapetool.xml($doc.fullName)}</h2>
7 +The conditioning of Western society has been imposed on it for decades but which have reached a level of absurdity that's unmatched in all of recorded history only recently.
23 23  
24 - #if($videos.size() == 0)
25 - <div style="text-align:center;padding:40px;background:#f8f9fa;border-radius:8px;">
26 - <h3>No Videos Found</h3>
27 - <p>Attach video files to this page to see them here.</p>
28 - </div>
29 - #else
9 +== Sub-paragraph ==
30 30  
31 - <!-- Bulk toolbar -->
32 - <div id="bulk-bar" class="bulk-bar">
33 - <label style="margin-right:8px;">
34 - <input type="checkbox" id="pick-all"> Select visible
35 - </label>
36 - <span class="sep"></span>
37 - <input type="text" class="bulk-dest suggest-pages" placeholder="Find a page…"
38 - data-search-scope="wiki:${escapetool.xml($xcontext.database)}">
39 - <button type="button" class="btn btn-sm btn-warning" id="bulk-move">Move selected</button>
40 - <button type="button" class="btn btn-sm btn-danger" id="bulk-delete">Delete selected</button>
41 - <span id="bulk-status" class="bulk-status"></span>
42 - </div>
11 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
43 43  
44 - <script>
45 - window.VID_CHUNK_SIZE = 48;
46 - window.VID_LAZY_MARGIN = '600px';
47 - window.XWIKI_WIKI = ${jsontool.serialize($xcontext.database)};
48 - window.SOURCE_SPACE = ${jsontool.serialize($doc.space)};
49 - window.SOURCE_PAGE = ${jsontool.serialize($doc.name)};
50 - </script>
13 +== Sub-paragraph ==
51 51  
52 - <div id="video-chunks">
53 - #set($i = 0)
54 - #set($chunkIndex = 0)
55 - #foreach($att in $videos)
56 - #set($i = $i + 1)
57 - #set($filename = $att.getFilename())
58 - #set($lname = $filename.toLowerCase())
59 - #set($url = $doc.getAttachmentURL($filename))
15 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
60 60  
61 - ## MIME guess
62 - #set($videoType = "video/mp4")
63 - #if($lname.endsWith(".webm"))
64 - #set($videoType = "video/webm")
65 - #elseif($lname.endsWith(".ogg"))
66 - #set($videoType = "video/ogg")
67 - #elseif($lname.endsWith(".avi"))
68 - #set($videoType = "video/x-msvideo")
69 - #elseif($lname.endsWith(".mov"))
70 - #set($videoType = "video/quicktime")
71 - #elseif($lname.endsWith(".wmv"))
72 - #set($videoType = "video/x-ms-wmv")
73 - #elseif($lname.endsWith(".flv"))
74 - #set($videoType = "video/x-flv")
75 - #elseif($lname.endsWith(".m4v"))
76 - #set($videoType = "video/mp4")
77 - #end
17 +=== Sub-sub paragraph ===
78 78  
79 - #if($i == 1 || ($i - 1) % 48 == 0)
80 - #set($chunkIndex = $chunkIndex + 1)
81 - <div class="vid-chunk" data-chunk="$chunkIndex" style="display: #if($chunkIndex == 1) block #else none #end;">
82 - <div class="video-display-grid">
83 - #end
19 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
84 84  
85 - <div class="video-container">
86 - <div class="video-header">
87 - <label class="pick"><input type="checkbox" class="vid-pick" data-filename="${escapetool.xml($filename)}"></label>
88 - <h4 class="video-title">${escapetool.xml($filename)}</h4>
89 - </div>
90 90  
91 - <div class="video-frame"
92 - data-src="${url}"
93 - data-type="${videoType}"
94 - data-name="${escapetool.xml($filename)}">
95 - <canvas class="vid-canvas" width="320" height="180"></canvas>
96 - <button class="btn btn-sm btn-primary" type="button">Load &amp; Play</button>
97 - </div>
22 += Paragraph 2 =
98 98  
99 - <div class="video-controls">
100 - <a href="${url}" download="${escapetool.xml($filename)}" class="btn btn-sm btn-success">📥 Download</a>
101 - <button class="btn btn-sm btn-danger del-one" data-filename="${escapetool.xml($filename)}">Delete</button>
102 - <span class="vid-duration">Duration: —</span>
103 - </div>
24 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
104 104  
105 - <!-- Move-to-page -->
106 - <div class="move-box">
107 - <label>Move to page:</label>
108 - <div class="move-row">
109 - <input type="text"
110 - class="move-input suggest-pages"
111 - placeholder="Find a page…"
112 - data-search-scope="wiki:${escapetool.xml($xcontext.database)}"
113 - data-filename="${escapetool.xml($filename)}">
114 - <button type="button"
115 - class="btn btn-sm btn-warning move-go"
116 - data-filename="${escapetool.xml($filename)}">Move</button>
117 - </div>
118 - <small class="hint">Pick a page (e.g., <code>Main.SomePage</code>). Click <b>Move</b> to relocate this file.</small>
119 - </div>
120 - </div> <!-- .video-container -->
26 +== Sub-paragraph ==
121 121  
122 - #if(($i % 48 == 0) || $foreach.last)
123 - </div> <!-- .video-display-grid -->
124 - #if(!$foreach.last)
125 - <div class="loadmore-wrap">
126 - <button class="btn btn-secondary load-more" data-next="$mathtool.add($chunkIndex,1)">Load more</button>
127 - </div>
128 - #end
129 - </div> <!-- .vid-chunk -->
130 - #end
131 - #end
132 - </div>
133 - #end
134 -</div>
28 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
135 135  
136 -<script>
137 -(function(){
138 - /* ===== constants & helpers ===== */
139 - var WIKI = window.XWIKI_WIKI;
140 - var CURRENT_SPACE = document.documentElement.getAttribute('data-xwiki-space') || (window.SOURCE_SPACE || 'Main');
141 - var ROOT_SPACE = CURRENT_SPACE.split('.')[0];
30 +== Sub-paragraph ==
142 142  
143 - function spacesPath(dotPath){
144 - if(!dotPath) return '';
145 - return dotPath.split('.').map(function(s){ return 'spaces/' + encodeURIComponent(s); }).join('/');
146 - }
147 - function parseFullName(full){
148 - full = String(full||'').replace(/^[^:]+:/,'');
149 - var parts = full.split('.');
150 - var page = parts.pop();
151 - return {spacePath: parts.join('.'), page: page};
152 - }
153 - function getFormToken(){
154 - return document.documentElement.getAttribute('data-xwiki-form-token') || '';
155 - }
156 -
157 - /* ===== existence check (prevents DocumentDoesNotExist) ===== */
158 - async function docExists(fullRef){
159 - var p = parseFullName(fullRef);
160 - var url = '/rest/wikis/' + encodeURIComponent(WIKI) + '/' +
161 - spacesPath(p.spacePath) + '/pages/' + encodeURIComponent(p.page) + '?media=json';
162 - var r = await fetch(url, {credentials:'same-origin'});
163 - return r.status === 200;
164 - }
165 -
166 - /* ===== robust resolver for Page Picker / typed titles ===== */
167 - async function resolveReference(inp){
168 - var ref = inp.getAttribute('data-reference') || (inp.dataset && inp.dataset.reference) || '';
169 - var raw = (inp.value || '').trim();
170 -
171 - if (ref){
172 - if (/\.WebHome$/i.test(ref)) { if (await docExists(ref)) return ref; }
173 - else {
174 - if (await docExists(ref)) return ref;
175 - var rh = ref + '.WebHome'; if (await docExists(rh)) return rh;
176 - }
177 - }
178 - var base = raw.indexOf('.') === -1 ? (ROOT_SPACE + '.' + raw) : raw;
179 - if (await docExists(base)) return base;
180 - var home2 = /\.WebHome$/i.test(base) ? base : (base + '.WebHome');
181 - if (await docExists(home2)) return home2;
182 -
183 - throw new Error('Target page not found: "' + raw + '". Choose a suggestion or type a full reference like "Main Categories.SomePage".');
184 - }
185 -
186 - /* ===== posters & video mount ===== */
187 - async function makePoster(frame){
188 - if(frame.getAttribute('data-poster-ready')==='1') return;
189 - var src = frame.getAttribute('data-src');
190 - try{
191 - var v = document.createElement('video');
192 - v.preload = 'metadata'; v.muted = true; v.playsInline = true; v.src = src;
193 - function once(t,e){return new Promise(function(res){t.addEventListener(e,res,{once:true});});}
194 - await once(v,'loadedmetadata');
195 - if (typeof v.requestVideoFrameCallback === 'function'){
196 - await new Promise(function(res){ v.requestVideoFrameCallback(function(){ res(); }); });
197 - } else {
198 - try { v.currentTime = 0.25; } catch(e){}
199 - await once(v,'seeked').catch(function(){});
200 - await once(v,'loadeddata').catch(function(){});
201 - }
202 - var canvas = frame.querySelector('.vid-canvas');
203 - if(canvas){
204 - var w = 320, h = Math.round(320 * (v.videoHeight||9) / (v.videoWidth||16));
205 - canvas.width = 320; canvas.height = h>0?h:180;
206 - var ctx = canvas.getContext('2d', {willReadFrequently:true});
207 - ctx.drawImage(v, 0, 0, canvas.width, canvas.height);
208 - try { frame.setAttribute('data-poster', canvas.toDataURL('image/webp', 0.85)); } catch(e){}
209 - }
210 - frame.setAttribute('data-poster-ready','1');
211 - }catch(e){}
212 - }
213 -
214 - function mountVideo(frame){
215 - if(frame.getAttribute('data-mounted')==='1') return;
216 - var src = frame.getAttribute('data-src');
217 - var type = frame.getAttribute('data-type') || 'video/mp4';
218 - var poster = frame.getAttribute('data-poster');
219 -
220 - var v = document.createElement('video');
221 - v.setAttribute('controls',''); v.setAttribute('preload','none');
222 - if(poster) v.setAttribute('poster', poster);
223 - v.style.width='100%'; v.style.maxWidth='100%'; v.style.borderRadius='4px';
224 -
225 - var s = document.createElement('source'); s.src = src; s.type = type; v.appendChild(s);
226 - v.addEventListener('loadedmetadata', function(){
227 - var d = Math.round(v.duration||0), mm = Math.floor(d/60), ss = String(d%60).padStart(2,'0');
228 - var dur = frame.parentElement.querySelector('.vid-duration'); if(dur) dur.textContent = 'Duration: '+mm+':'+ss;
229 - });
230 -
231 - frame.replaceChildren(v);
232 - frame.setAttribute('data-mounted','1');
233 - }
234 -
235 - /* ===== observers & UI wiring ===== */
236 - if('IntersectionObserver' in window){
237 - var io = new IntersectionObserver(function(entries){
238 - entries.forEach(function(e){
239 - if(e.isIntersecting){ makePoster(e.target); io.unobserve(e.target); }
240 - });
241 - }, { rootMargin: (window.VID_LAZY_MARGIN||'600px') });
242 - document.querySelectorAll('.video-frame').forEach(function(el){ io.observe(el); });
243 - }
244 -
245 - document.addEventListener('click', function(ev){
246 - var frame = ev.target.closest('.video-frame');
247 - if(frame){
248 - mountVideo(frame);
249 - var v = frame.querySelector('video'); if(v) v.play().catch(function(){});
250 - }
251 - });
252 -
253 - document.addEventListener('click', function(ev){
254 - var b = ev.target.closest('.load-more'); if(!b) return;
255 - var next = b.getAttribute('data-next');
256 - var nxt = document.querySelector('.vid-chunk[data-chunk="'+ next +'"]');
257 - if(nxt){ nxt.style.display='block'; b.parentElement.style.display='none'; }
258 - });
259 -
260 - /* ===== MOVE & DELETE core ===== */
261 - async function moveAttachment(opts){
262 - var srcSpace = opts.srcSpace, srcPage = opts.srcPage, filename = opts.filename, dstFull = opts.dstFull;
263 - var pf = parseFullName(dstFull);
264 - var srcSpacesPath = spacesPath(srcSpace);
265 - var dstSpacesPath = spacesPath(pf.spacePath);
266 -
267 - var sel = '.video-container input.move-input[data-filename="' + CSS.escape(filename) + '"]';
268 - var inp = document.querySelector(sel);
269 - var card = inp ? inp.closest('.video-container') : null;
270 - var frame = card ? card.querySelector('.video-frame') : null;
271 - var srcURL = frame ? frame.getAttribute('data-src') : null;
272 - if(!srcURL) throw new Error('Missing source URL');
273 -
274 - var downloading = await fetch(srcURL, {credentials:'same-origin'});
275 - if(!downloading.ok) throw new Error('Download failed: ' + downloading.status);
276 - var blob = await downloading.blob();
277 -
278 - var token = getFormToken();
279 -
280 - var putURL = '/rest/wikis/' + encodeURIComponent(WIKI) + '/' + dstSpacesPath +
281 - '/pages/' + encodeURIComponent(pf.page) +
282 - '/attachments/' + encodeURIComponent(filename) + '?media=json';
283 - var uploading = await fetch(putURL, {
284 - method: 'PUT',
285 - body: blob,
286 - headers: {'Content-Type':'application/octet-stream','XWiki-Form-Token': token},
287 - credentials:'same-origin'
288 - });
289 - if(!(uploading.status===201 || uploading.status===202)){
290 - var txt = await uploading.text().catch(function(){ return String(uploading.status); });
291 - throw new Error('Upload failed: ' + txt);
292 - }
293 -
294 - var delURL = '/rest/wikis/' + encodeURIComponent(WIKI) + '/' + srcSpacesPath +
295 - '/pages/' + encodeURIComponent(srcPage) +
296 - '/attachments/' + encodeURIComponent(filename);
297 - var deleting = await fetch(delURL, {method:'DELETE', headers:{'XWiki-Form-Token': token}, credentials:'same-origin'});
298 - if(!(deleting.status===204)){ console.warn('Delete original failed', deleting.status); }
299 - return true;
300 - }
301 -
302 - async function deleteAttachment(filename){
303 - var token = getFormToken();
304 - var srcSpacesPath = spacesPath(window.SOURCE_SPACE);
305 - var url = '/rest/wikis/' + encodeURIComponent(WIKI) + '/' + srcSpacesPath +
306 - '/pages/' + encodeURIComponent(window.SOURCE_PAGE) +
307 - '/attachments/' + encodeURIComponent(filename);
308 - var r = await fetch(url, {
309 - method: 'DELETE',
310 - headers: {'XWiki-Form-Token': token},
311 - credentials: 'same-origin'
312 - });
313 - if (r.status !== 204) {
314 - var t = await r.text().catch(()=>String(r.status));
315 - throw new Error('Delete failed: ' + t);
316 - }
317 - return true;
318 - }
319 -
320 - function removeCardByFilename(filename){
321 - var card = document.querySelector('.video-container input.vid-pick[data-filename="'+CSS.escape(filename)+'"]');
322 - card = card ? card.closest('.video-container') : null;
323 - if (card) card.remove();
324 - }
325 - function selectedFilenames(){
326 - return Array.from(document.querySelectorAll('.vid-pick:checked'))
327 - .map(ch => ch.getAttribute('data-filename'));
328 - }
329 -
330 - /* ===== Move (per-card) ===== */
331 - document.addEventListener('click', function(e){
332 - var btn = e.target.closest('.move-go'); if(!btn) return;
333 - var box = btn.closest('.move-box');
334 - var inp = box.querySelector('.move-input');
335 - (async function(){
336 - var notice = box.querySelector('.move-notice');
337 - if(!notice){ notice = document.createElement('div'); notice.className = 'move-notice'; box.appendChild(notice); }
338 - try{
339 - var ref = await resolveReference(inp);
340 - var filename = btn.getAttribute('data-filename');
341 - notice.style.color = '#666';
342 - notice.textContent = 'Moving “' + filename + '” to ' + ref + ' …';
343 -
344 - await moveAttachment({ srcSpace: window.SOURCE_SPACE, srcPage: window.SOURCE_PAGE, filename: filename, dstFull: ref });
345 -
346 - notice.textContent = 'Moved ✔ — reloading…';
347 - setTimeout(function(){ location.reload(); }, 600);
348 - }catch(err){
349 - notice.style.color = '#b00020';
350 - notice.textContent = 'Move failed: ' + (err && err.message ? err.message : err);
351 - }
352 - })();
353 - });
354 -
355 - /* ===== Delete (per-card) ===== */
356 - document.addEventListener('click', function(e){
357 - var btn = e.target.closest('.del-one'); if(!btn) return;
358 - var filename = btn.getAttribute('data-filename');
359 - if(!confirm('Delete this file permanently?\n\n' + filename)) return;
360 - var notice = document.createElement('div');
361 - notice.className = 'move-notice'; notice.textContent = 'Deleting…';
362 - btn.parentElement.appendChild(notice);
363 - deleteAttachment(filename)
364 - .then(()=>{ notice.textContent = 'Deleted ✔'; removeCardByFilename(filename); })
365 - .catch(err=>{ notice.style.color='#b00020'; notice.textContent = (err && err.message)||String(err); });
366 - });
367 -
368 - /* ===== Bulk: select visible ===== */
369 - document.addEventListener('change', function(e){
370 - if (e.target && e.target.id === 'pick-all'){
371 - var on = e.target.checked;
372 - document.querySelectorAll('.vid-pick').forEach(ch => { ch.checked = on; });
373 - }
374 - });
375 -
376 - /* ===== Bulk: Move ===== */
377 - document.getElementById('bulk-move')?.addEventListener('click', async function(){
378 - var files = selectedFilenames();
379 - if (!files.length) return alert('No videos selected.');
380 - var destInput = document.querySelector('.bulk-dest');
381 - var status = document.getElementById('bulk-status');
382 - try{
383 - var ref = await resolveReference(destInput);
384 - if(!confirm('Move '+files.length+' file(s) to:\n\n'+ref+' ?')) return;
385 - status.style.color=''; status.textContent = 'Moving 0/' + files.length + '…';
386 - let done = 0;
387 - for (const f of files){
388 - await moveAttachment({ srcSpace: window.SOURCE_SPACE, srcPage: window.SOURCE_PAGE, filename: f, dstFull: ref });
389 - done++; status.textContent = 'Moving ' + done + '/' + files.length + '…';
390 - removeCardByFilename(f);
391 - }
392 - status.textContent = 'Move complete ✔';
393 - }catch(err){
394 - status.style.color = '#b00020';
395 - status.textContent = 'Move failed: ' + ((err && err.message) || String(err));
396 - }
397 - });
398 -
399 - /* ===== Bulk: Delete ===== */
400 - document.getElementById('bulk-delete')?.addEventListener('click', async function(){
401 - var files = selectedFilenames();
402 - if (!files.length) return alert('No videos selected.');
403 - if(!confirm('DELETE '+files.length+' file(s)? This cannot be undone.')) return;
404 - var status = document.getElementById('bulk-status');
405 - try{
406 - status.style.color=''; status.textContent = 'Deleting 0/' + files.length + '…';
407 - let done = 0;
408 - for (const f of files){
409 - await deleteAttachment(f);
410 - done++; status.textContent = 'Deleting ' + done + '/' + files.length + '…';
411 - removeCardByFilename(f);
412 - }
413 - status.textContent = 'Delete complete ✔';
414 - }catch(err){
415 - status.style.color = '#b00020';
416 - status.textContent = 'Delete failed: ' + ((err && err.message) || String(err));
417 - }
418 - });
419 -
420 -})();
421 -</script>
422 -
423 -<style>
424 - .video-display-grid{
425 - display:grid;
426 - grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
427 - gap:20px; align-items:start;
428 - }
429 - .video-container{border:1px solid #ddd; border-radius:8px; padding:12px; background:#fff;}
430 - .video-header{display:flex;gap:8px;align-items:center;margin-bottom:8px;}
431 - .video-title{margin:0;flex:1;min-width:0;word-break:break-word;}
432 - .pick{margin-right:2px}
433 - .video-frame{
434 - position:relative;width:100%;aspect-ratio:16/9;background:#111;border-radius:4px;
435 - overflow:hidden;display:flex;align-items:center;justify-content:center;cursor:pointer;
436 - }
437 - .vid-canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
438 - .video-controls{margin-top:8px;display:flex;flex-wrap:wrap;gap:6px;align-items:center;}
439 - .move-box{margin-top:10px;}
440 - .move-row{display:flex;gap:6px;align-items:center;flex-wrap:wrap;}
441 - .move-input{flex:1;min-width:220px;padding:4px;border:1px solid #ccc;border-radius:4px;}
442 - .hint{color:#888;}
443 - .loadmore-wrap{text-align:center;margin:12px 0 28px;}
444 - .btn{padding:4px 8px;border:1px solid #ddd;background:#f8f9fa;border-radius:4px;cursor:pointer;text-decoration:none;display:inline-block;}
445 - .btn:hover{background:#e9ecef;}
446 - .btn-primary{background:#007bff;color:#fff;border-color:#007bff;}
447 - .btn-secondary{background:#6c757d;color:#fff;border-color:#6c757d;}
448 - .btn-success{background:#28a745;color:#fff;border-color:#28a745;}
449 - .btn-danger{background:#dc3545;color:#fff;border-color:#dc3545;}
450 - .btn-danger:hover{background:#c82333}
451 - .btn-sm{font-size:12px;padding:2px 6px;}
452 - .move-notice{font-size:12px;color:#666;margin-top:6px;max-height:6.5em;overflow:auto;white-space:normal;overflow-wrap:anywhere;}
453 - .bulk-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:8px 0 16px;}
454 - .bulk-bar .sep{width:1px;height:18px;background:#ddd;margin:0 4px;}
455 - .bulk-status{font-size:12px;color:#666;margin-left:6px;white-space:normal;overflow-wrap:anywhere;}
456 - @media (max-width:768px){.video-display-grid{grid-template-columns:1fr}}
457 -</style>
458 -{{/html}}
459 -{{/cache}}
460 -{{/velocity}}
461 -
32 +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
1776General__20240817__1824613900312080533_1_18246138792021319680.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -693.9 KB
Content
2025-02-26_05-18-58_0.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.XWikiGuest
Size
... ... @@ -1,1 +1,0 @@
1 -40.7 MB
Content
2025-03-06_16-57-27_0.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -5.9 MB
Content
EndWokeness_20240605__1798457471801098627_1_17984567241410723840.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -1.8 MB
Content
MEGYNK~1.MP4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -147.7 MB
Content
Propaganda.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -1524.6 MB
Content
U8WPGxcawzXzPw0D.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -4.0 MB
Content
Wake-up call for the alt-right; a beige horizon is inevitable ¦ 22 Minutes (1080p_30fps_H264-128kbit_AAC).mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -43.8 MB
Content
bewJ0Ljb0efee3AD.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -5.0 MB
Content
hb_1721711784686lv_0_20240722190054.mp4
Author
... ... @@ -1,1 +1,0 @@
1 -XWiki.AdminAngriff
Size
... ... @@ -1,1 +1,0 @@
1 -112.6 MB
Content