PageSourceSearch

https://goldesel.de/custom/pages/stocks/news-hub-brain.js?v=gJNL9XSr8jlRQXdepa7GvtegUR6a5ntXMrheuCsl9CU

js goldesel.de collected 2026-10-01 16:04:28 UTC 18,745 bytes, 420 lines download raw bytes

1/**
2 * News-Hub „Deine News“: Watchlist laden (Azure Functions) + Brain-Feed (services.goldesel.de), analog startpageV2.js.
3 */
4(function () {
5    'use strict';
6
7    var functionUrl = 'https://goldeselazfunctions.azurewebsites.net/api/';
8    var groupNames = ['dpa-AFX ProFeed', 'Discord', 'Société Générale', 'stock3', 'dpa-AFX Compact'];
9
10    function getToken() {
11        var el = document.getElementById('token');
12        return el && el.value ? el.value : '';
13    }
14
15    function getUserId() {
16        var el = document.getElementById('news-hub-user-id');
17        if (!el || !el.value) return 0;
18        var n = parseInt(el.value, 10);
19        return isNaN(n) ? 0 : n;
20    }
21
22    function formatNewsTime(iso) {
23        if (!iso) return '';
24        var d = new Date(iso);
25        if (isNaN(d.getTime())) return '';
26        return d.toLocaleString('de-DE', {
27            hour: '2-digit',
28            minute: '2-digit',
29            day: '2-digit',
30            month: '2-digit',
31            year: 'numeric'
32        });
33    }
34
35    function formatDeDate(iso) {
36        if (!iso) return '';
37        var d = new Date(iso);
38        if (isNaN(d.getTime())) return '';
39        return d.toLocaleString('de-DE', {
40            hour: '2-digit',
41            minute: '2-digit',
42            day: '2-digit',
43            month: 'long',
44            year: 'numeric'
45        });
46    }
47
48    function formatDeShort(iso) {
49        if (!iso) return '';
50        var d = new Date(iso);
51        if (isNaN(d.getTime())) return '';
52        return d.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' });
53    }
54
55    function formatDeListRow(iso) {
56        if (!iso) return '';
57        var d = new Date(iso);
58        if (isNaN(d.getTime())) return '';
59        return d.toLocaleString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' });
60    }
61
62    function escapeHtml(s) {
63        if (!s) return '';
64        var d = document.createElement('div');
65        d.textContent = s;
66        return d.innerHTML;
67    }
68
69    var EU_AI_GENERATED_BADGE =
70        '<img class="eu-ai-label-badge" alt="AI Generated" src="https://goldesel.azureedge.net/upload-public/img/eu-label/LABEL_AI%20GENERATED_black%20transparent.png" />';
71
72    function withEuAiGeneratedBadge(mediaHtml) {
73        if (!mediaHtml || mediaHtml.indexOf('<img ') !== 0) return mediaHtml;
74        return mediaHtml + EU_AI_GENERATED_BADGE;
75    }
76
77    function stripHtml(html) {
78        if (!html) return '';
79        var tmp = document.createElement('div');
80        tmp.innerHTML = html;
81        return (tmp.textContent || tmp.innerText || '').trim();
82    }
83
84    function buildSnippet(item) {
85        var raw = item.body || item.previewText || item.text || '';
86        var plain = stripHtml(raw);
87        if (!plain) return '';
88        if (plain.length > 160) return plain.substring(0, 160) + '…';
89        return plain;
90    }
91
92    function toNewsSlug(headline) {
93        if (!headline) return '';
94        var result = String(headline).trim().replace(/\s+/g, '-');
95        result = result.replace(/ä/g, 'a').replace(/Ä/g, 'A')
96            .replace(/ö/g, 'o').replace(/Ö/g, 'O')
97            .replace(/ü/g, 'u').replace(/Ü/g, 'U')
98            .replace(/ë/g, 'e').replace(/Ë/g, 'E')
99            .replace(/é/g, 'e').replace(/É/g, 'E')
100            .replace(/è/g, 'e').replace(/È/g, 'E')
101            .replace(/ê/g, 'e').replace(/Ê/g, 'E')
102            .replace(/à/g, 'a').replace(/À/g, 'A')
103            .replace(/â/g, 'a').replace(/Â/g, 'A')
104            .replace(/ç/g, 'c').replace(/Ç/g, 'C')
105            .replace(/ñ/g, 'n').replace(/Ñ/g, 'N')
106            .replace(/ß/g, 'ss')
107            .replace(/æ/g, 'ae').replace(/Æ/g, 'AE')
108            .replace(/œ/g, 'oe').replace(/Œ/g, 'OE');
109        result = result.replace(/[^a-zA-Z0-9-]+/g, '');
110        result = result.replace(/-+/g, '-');
111        result = result.toLowerCase();
112        return result.replace(/-+$/, '');
113    }
114
115    var state = {
116        loaded: false,
117        loading: false,
118        watchlists: [],
119        selectedWatchlistId: 0,
120        items: []
121    };
122
123    function brainItemSlug(n) {
124        if (n.slug && String(n.slug).trim()) return String(n.slug).trim();
125        return toNewsSlug(n.headline || '');
126    }
127
128    function brainLeadImage(n) {
129        if (n.newsImage && String(n.newsImage).trim()) return n.newsImage;
130        var fi = n.instruments && n.instruments[0];
131        if (!fi) return '';
132        var big = fi.logoBig || fi.LogoBig;
133        var lo = fi.logo || fi.Logo;
134        if (big && String(big).trim()) return big;
135        return lo && String(lo).trim() ? lo : '';
136    }
137
138    function instrumentPerfSpanHtml(inst) {
139        if (!inst) return '';
140        var perfRaw = inst.performnaceDay;
141        if ((perfRaw === undefined || perfRaw === null) && inst.PerformnaceDay !== undefined) {
142            perfRaw = inst.PerformnaceDay;
143        }
144        if (perfRaw === undefined || perfRaw === null || isNaN(Number(perfRaw))) return '';
145        var rounded = Math.round(Number(perfRaw) * 1000) / 10;
146        if (Math.abs(rounded) <= 0) return '';
147        var pctNum = rounded;
148        var performanceColor = pctNum >= 0 ? '#63FFDA' : '#db3344';
149        var performanceSign = pctNum >= 0 ? '+' : '';
150        return '<span style="color:' + performanceColor + '; margin-left: 8px; font-weight: 700;">' +
151            performanceSign + pctNum.toFixed(1) + '%</span>';
152    }
153
154    function instrumentBadgeHtml(inst) {
155        var name = (inst && (inst.name || inst.instrumentName)) || '';
156        if (!name) return '';
157        return '<span class="ki-news-instrument-badge">' + escapeHtml(name) + instrumentPerfSpanHtml(inst) + '</span>';
158    }
159
160    function newsUrl(n) {
161        return '/aktien/news/' + encodeURIComponent(brainItemSlug(n));
162    }
163
164    /** Escaped URL for use in data-news-hub-brain-href (same rules as former href). */
165    function brainHrefAttr(n) {
166        return escapeHtml(newsUrl(n));
167    }
168
169    function brainNavOpen(href) {
170        if (!href) return;
171        window.open(href, '_blank', 'noopener,noreferrer');
172    }
173
174    function ensureBrainNavDelegation() {
175        var listEl = document.getElementById('news-hub-brain-list');
176        if (!listEl || listEl._newsHubBrainNavBound) return;
177        listEl._newsHubBrainNavBound = true;
178        listEl.addEventListener('click', function (ev) {
179            var t = ev.target.closest('[data-news-hub-brain-href]');
180            if (!t || !listEl.contains(t)) return;
181            if (ev.defaultPrevented) return;
182            var href = t.getAttribute('data-news-hub-brain-href');
183            if (!href) return;
184            brainNavOpen(href);
185        });
186        listEl.addEventListener('auxclick', function (ev) {
187            if (ev.button !== 1) return;
188            var t = ev.target.closest('[data-news-hub-brain-href]');
189            if (!t || !listEl.contains(t)) return;
190            ev.preventDefault();
191            var href = t.getAttribute('data-news-hub-brain-href');
192            brainNavOpen(href);
193        });
194        listEl.addEventListener('keydown', function (ev) {
195            if (ev.key !== 'Enter' && ev.key !== ' ') return;
196            var t = ev.target.closest('[data-news-hub-brain-href]');
197            if (!t || !listEl.contains(t)) return;
198            ev.preventDefault();
199            var href = t.getAttribute('data-news-hub-brain-href');
200            brainNavOpen(href);
201        });
202    }
203
204    function buildBrainTopReadBlock(items) {
205        if (!items || !items.length) return '';
206        var hi = items[0];
207        var hiUrl = brainHrefAttr(hi);
208        var hiImg = brainLeadImage(hi);
209        var imgHi = hiImg
210            ? '<span class="eu-ai-label-wrap d-block"><img class="news-hub-card__img" src="' + escapeHtml(hiImg) + '" alt="' + escapeHtml(hi.headline || '') + '" loading="lazy" />' + EU_AI_GENERATED_BADGE + '</span>'
211            : '<div class="news-hub-card__img" style="background:#24203f;display:flex;align-items:center;justify-content:center;"><i class="fa-solid fa-newspaper fa-2x" style="color:#8a87b0;"></i></div>';
212        var hiInst = (hi.instruments && hi.instruments[0]) || {};
213        var hiBadge = instrumentBadgeHtml(hiInst);
214
215        var sub = '';
216        if (items.length > 1) {
217            sub += '<div class="news-hub-topread__subgrid">';
218            items.slice(1, 3).forEach(function (n) {
219                var u = brainHrefAttr(n);
220                var im = brainLeadImage(n);
221                var imHtml = im
222                    ? '<img class="news-hub-card__img" src="' + escapeHtml(im) + '" alt="' + escapeHtml(n.headline || '') + '" loading="lazy" />'
223                    : '<div class="news-hub-card__img" style="background:#24203f;display:flex;align-items:center;justify-content:center;min-height:120px;"><i class="fa-solid fa-newspaper" style="color:#8a87b0;"></i></div>';
224                var subInst = (n.instruments && n.instruments[0]) || {};
225                var subBadge = instrumentBadgeHtml(subInst);
226                sub += '<article class="news-hub-card news-hub-kinews-card"><div role="link" tabindex="0" class="news-hub-brain-nav text-reset d-block" data-news-hub-brain-href="' + u + '">' +
227                    '<div class="news-hub-card__media eu-ai-label-wrap">' + withEuAiGeneratedBadge(imHtml) + subBadge + '</div>' +
228                    '<div class="news-hub-card__body"><h3 class="news-hub-card__title" style="font-size:14px;">' + escapeHtml(n.headline || '') + '</h3>' +
229                    '<div class="news-hub-card__meta">' + escapeHtml(formatDeShort(n.time)) + '</div></div></div></article>';
230            });
231            sub += '</div>';
232        }
233
234        var list = '';
235        if (items.length > 3) {
236            list += '<div class="news-hub-topread__list">';
237            items.slice(3, 10).forEach(function (n) {
238                var u = brainHrefAttr(n);
239                var im = brainLeadImage(n);
240                var th = im
241                    ? '<img class="news-hub-topread__thumb" src="' + escapeHtml(im) + '" alt="" loading="lazy" />'
242                    : '<div class="news-hub-topread__thumb" style="background:#24203f;display:flex;align-items:center;justify-content:center;"><i class="fa-solid fa-newspaper" style="color:#8a87b0;"></i></div>';
243                list += '<div role="link" tabindex="0" class="news-hub-topread__row news-hub-kinews-card news-hub-brain-nav" data-news-hub-brain-href="' + u + '">' + th +
244                    '<div class="news-hub-topread__row-text"><div class="news-hub-card__title">' + escapeHtml(n.headline || '') + '</div>' +
245                    '<div class="news-hub-card__meta">' + escapeHtml(formatDeListRow(n.time)) + '</div></div></div>';
246            });
247            list += '</div>';
248        }
249
250        return (
251            '<div class="news-hub-brain-topread-wrap">' +
252            '<div class="news-hub-topread news-hub-brain-topread">' +
253            '<div class="news-hub-topread__featured">' +
254            '<article class="news-hub-card news-hub-kinews-card news-hub-topread__highlight">' +
255            '<div role="link" tabindex="0" class="news-hub-brain-nav" data-news-hub-brain-href="' + hiUrl + '">' + imgHi +
256            '<div class="news-hub-card__body">' +
257            '<span class="news-hub-card__badge">Watchlist</span>' +
258            '<h3 class="news-hub-card__title">' + escapeHtml(hi.headline || '') + '</h3>' +
259            '<div class="news-hub-card__meta">' + escapeHtml(formatDeDate(hi.time)) + '</div></div>' + hiBadge + '</div></article>' +
260            sub + '</div>
260' + list + '</div></div>'
261        );
262    }
263
264    function buildBrainMoreGridCards(items) {
265        return items.map(function (n) {
266            var inst = (n.instruments && n.instruments[0]) || {};
267            var logo = inst.logo || inst.Logo || '';
268            var name = inst.name || inst.instrumentName || '';
269            var headline = n.headline || '';
270            var url = brainHrefAttr(n);
271            var time = formatNewsTime(n.time);
272            var snippet = buildSnippet(n);
273            var imageUrl = n.newsImage || logo;
274            var mediaHtml = imageUrl
275                ? '<img class="news-hub-more-card__img" src="' + escapeHtml(imageUrl) + '" alt="' + escapeHtml(headline) + '" loading="lazy" />'
276                : '<div class="news-hub-more-card__img" style="background:#24203f;display:flex;align-items:center;justify-content:center;"><i class="fa-solid fa-newspaper fa-2x" style="color:#8a87b0;"></i></div>';
277            var badgeHtml = name ? instrumentBadgeHtml(inst) : '';
278            return (
279                '<article class="news-hub-more-card news-hub-kinews-card news-hub-brain-card">' +
280                '<div role="link" tabindex="0" class="news-hub-brain-nav text-reset d-block" data-news-hub-brain-href="' + url + '">' +
281                '<div class="news-hub-more-card__media eu-ai-label-wrap">' + withEuAiGeneratedBadge(mediaHtml) + badgeHtml + '</div>' +
282                '<div class="news-hub-more-card__body">' +
283                '<h3 class="news-hub-card__title mb-0">' + escapeHtml(headline) + '</h3>' +
284                '<div class="news-hub-card__meta">' + escapeHtml(time) + '</div>' +
285                (snippet ? '<div class="ki-news-snippet small mb-0 mt-2">' + escapeHtml(snippet) + '</div>' : '') +
286                '</div></div></article>'
287            );
288        }).join('');
289    }
290
291    function renderBrainList() {
292        var listEl = document.getElementById('news-hub-brain-list');
293        var emptyEl = document.getElementById('news-hub-brain-empty');
294        var loadingEl = document.getElementById('news-hub-brain-loading');
295        if (!listEl) return;
296        ensureBrainNavDelegation();
297        if (loadingEl) loadingEl.style.display = state.loading ? 'block' : 'none';
298        if (state.loading) {
299            listEl.innerHTML = '';
300            if (emptyEl) emptyEl.hidden = true;
301            return;
302        }
303        if (!state.items.length) {
304            listEl.innerHTML = '';
305            if (emptyEl) emptyEl.hidden = false;
306            return;
307        }
308        if (emptyEl) emptyEl.hidden = true;
309
310        var top = state.items.slice(0, 10);
311        var more = state.items.slice(10);
312        var parts = [];
313        parts.push(buildBrainTopReadBlock(top));
314        if (more.length) {
315            parts.push('<h2 class="news-hub-section-title news-hub-brain-more-grid__title">Weitere Schlagzeilen</h2>');
316            parts.push('<div class="news-hub-more-grid news-hub-brain-grid">' + buildBrainMoreGridCards(more) + '</div>');
317        }
318        listEl.innerHTML = parts.join('');
319    }
320
321    function loadBrainNews() {
322        var token = getToken();
323        var userId = getUserId();
324        if (!token || !userId || typeof axios === 'undefined') {
325            state.items = [];
326            state.loading = false;
327            renderBrainList();
328            return;
329        }
330        var wlId = state.selectedWatchlistId;
331        if (!wlId && state.watchlists.length) wlId = state.watchlists[0].Id;
332        var searchAll = false;
333        var filterObj = '{Watchlist: ' + wlId + ', SearchAll: ' + searchAll + '}';
334        var params = 'filter=' + encodeURIComponent(filterObj) + '&aiProcessed=true';
335        var url = 'https://services.goldesel.de/api/Search/AddToGroupsWithFilter?' + params;
336
337        state.loading = true;
338        renderBrainList();
339
340        axios.post(url, groupNames, {
341            headers: {
342                'Authorization': 'Bearer ' + token,
343                'Content-Type': 'application/json'
344            }
345        }).then(function (response) {
346            var data = Array.isArray(response.data) ? response.data : [];
347            data.sort(function (a, b) {
348                return new Date(b.time).getTime() - new Date(a.time).getTime();
349            });
350            state.items = data;
351        }).catch(function () {
352            state.items = [];
353        }).finally(function () {
354            state.loading = false;
355            renderBrainList();
356        });
357    }
358
359    function loadWatchlists() {
360        var token = getToken();
361        var userId = getUserId();
362        var sel = document.getElementById('news-hub-watchlist-select');
363        if (!token || !userId || typeof axios === 'undefined') {
364            if (sel) sel.innerHTML = '';
365            state.watchlists = [];
366            state.items = [];
367            renderBrainList();
368            return;
369        }
370
371        state.loading = true;
372        renderBrainList();
373
374        var qryObj = { Token: token, QueryType: 2, DepotKind: 1, FromUserId: userId, WithPositions: true };
375        axios.post(functionUrl + 'Depot/Get', qryObj, {
376            headers: { 'Cache-Control': 'no-cache', 'Pragma': 'no-cache' }
377        }).then(function (response) {
378            var depots = response.data && response.data.Depots;
379            if (!depots || !Array.isArray(depots)) {
380                state.watchlists = [];
381                state.selectedWatchlistId = 0;
382            } else {
383                state.watchlists = depots;
384                state.selectedWatchlistId = depots.length ? depots[0].Id : 0;
385            }
386            if (sel) {
387                sel.innerHTML = '';
388                state.watchlists.forEach(function (d) {
389                    var opt = document.createElement('option');
390                    opt.value = String(d.Id);
391                    opt.textContent = d.Name || ('Watchlist ' + d.Id);
392                    sel.appendChild(opt);
393                });
394                sel.value = String(state.selectedWatchlistId);
395            }
396            loadBrainNews();
397        }).catch(function () {
398            state.watchlists = [];
399            state.loading = false;
400            renderBrainList();
401        });
402    }
403
404    function ensureLoaded() {
405        if (state.loaded) return;
406        state.loaded = true;
407        ensureBrainNavDelegation();
408        var sel = document.getElementById('news-hub-watchlist-select');
409        if (sel && !sel._newsHubBound) {
410            sel._newsHubBound = true;
411            sel.addEventListener('change', function () {
412                state.selectedWatchlistId = parseInt(sel.value, 10) || 0;
413                loadBrainNews();
414            });
415        }
416        loadWatchlists();
417    }
418
419    window.NewsHubBrain = { ensureLoaded: ensureLoaded };
420})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.