PageSourceSearch

https://www.obren359.com/

html obren359.com collected 2026-10-06 20:41:12 UTC 22,264 bytes, 407 lines download raw bytes

1<!DOCTYPE html>
2<html>
3<head lang="en">
4    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5    <title>359° View on Tech Trends</title>
6
7    <meta content='summary_large_image' name='twitter:card'></meta>
8    <meta content="Željko Obrenović's 359° View on Tech Trends" property="og:title"></meta>
9    <meta content='https://www.obren359.com/' property='og:url'></meta>
10    <meta content='Looking at technology trends from (almost) all angles.' property='og:description'></meta>
11    <meta content='https://www.obren359.com/images/logo2.png' property='og:image'></meta>
12    <meta content='www.obren359.com' property='og:site_name'></meta>
13    <meta content='2018-11-25' property='og:article:modified_time'></meta>
14    <meta content='@zeljko_obren' name='twitter:creator'></meta>
15
16    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
17    <meta http-equiv="cache-control" content="max-age=0">
18    <meta http-equiv="cache-control" content="no-cache">
19    <meta http-equiv="expires" content="0">
20    <meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT">
21    <meta http-equiv="pragma" content="no-cache">
22    <link rel="stylesheet" type="text/css" href="client_code/css/font.css">
23    <link rel="stylesheet" type="text/css" href="client_code/css/style.css?v=1531067321959">
24    
24<script src="client_code/lib/vue.min.js"></script>
24
25    
25<script src="client_code/lib/jquery.min.js"></script>
25
26    
26<script src="client_code/lib/ace/ace.js"></script>
26
27    
27<script src="client_code/lib/showdown.min.js"></script>
27
28    
28<script src="client_code/js/global.js?v=1531067321959"></script>
28
29    
29<script src="client_code/js/about.js?v=1531067321959"></script>
29
30    
30<script src="client_code/js/chapters.js?v=1531067321959"></script>
30
31    
31<script src="client_code/js/articles.js?v=1531067321959"></script>
31
32    
32<script src="client_code/js/basket.js?v=1531067321959"></script>
32
33    
33<script src="client_code/js/main.js?v=1531067321959"></script>
33
34    
34<script src="client_code/js/components/timeline-component.js?v=1531067321959"></script>
34
35    
35<script src="client_code/js/components/home-component.js?v=1531067321959"></script>
35
36    
36<script src="client_code/js/components/cover-component.js?v=1531067321959"></script>
36
37    
37<script src="client_code/js/components/covers-component.js?v=1531067321959"></script>
37
38    
38<script src="client_code/js/components/article-abstract-component.js?v=1531067321959"></script>
38
39    
39<script src="client_code/js/components/filter-input-component.js?v=1531067321959"></script>
39
40    
40<script src="client_code/js/components/about-component.js?v=1531067321959"></script>
40
41    
41<script src="client_code/js/components/contact-component.js?v=1531067321959"></script>
41
42    
42<script src="client_code/js/components/links-list-component.js?v=1531067321959"></script>
42
43    
43<script src="client_code/js/components/timeline-component.js?v=1531067321959"></script>
43
44    
44<script src="client_code/js/components/ace-component.js?v=1531067321959"></script>
44
45    
45<script src="client_code/js/components/sources-component.js?v=1531067321959"></script>
45
46    
46<script src="client_code/js/components/pricing-component.js?v=1531067321959"></script>
46
47    
47<script src="client_code/js/components/basket-component.js?v=1531067321959"></script>
47
48    
48<script src="client_code/js/components/modal-editor-component.js?v=1531067321959"></script>
48
49    
49<script src="client_code/js/components/modal-input-component.js?v=1531067321959"></script>
49
50    
50<script src="client_code/js/components/dropdown-component.js?v=1531067321959"></script>
50
51    
51<script src="client_code/js/components/articles-stats-component.js?v=1531067321959"></script>
51
52    <!-- Global site tag (gtag.js) - Google Analytics -->
vendor: 68 bytes, lines 52-53
52
53    <script async src="https://www.googletagmanager.com/gtag/js?id=
53UA-129891352-1
vendor: 16 bytes, lines 53-54
53"></script>
54    
54<script>
55        
vendor: 176 bytes, lines 55-62
55window.dataLayer = window.dataLayer || [];
56
57        function gtag() {
58            dataLayer.push(arguments);
59        }
60
61        gtag('js', new Date());
62        gtag('config', '
62UA-129891352-1
vendor: 8 bytes, lines 62-63
62');
63    
63</script>
63
64</head>
65<body>
66<div id="app" :class="mobile ? 'mainMobile' : 'mainDesktop'" style="visibility: hidden">
67
68    <table style="margin-bottom: -4px; margin-left: -10px">
69        <tr>
70            <td>
71                <a href="https://obren.io"><img height='146' src="logo.png"/></a>
72            </td>
73            <td style="text-align: left">
74                <br/><span :style="'color: grey; margin: 0; font-size: ' + (mobile ? '10px;' : '18px;')">Željko Obrenović's</span>
75                <h1 :style="'margin: 0; font-size: ' + (mobile ? '38px;' : '50px;')">Curated Reads</h1>
76                <p :style="'margin-top:0; font-size: ' + (mobile ? '100%' : '120%')">Collections of articles from authoritative, high-quality, peer-reviewed publications</p>
77
78            </td>
79        </tr>
80    </table>
81
82
83    <ul class="tab" v-if="!mobile">
84        <li><a href="javascript:void(0)" class="tablinks active" onclick="openTab(event, 'Sources')">Sources</a></li>
85        <li><a href="javascript:void(0)" class="tablinks" onclick="openTab(event, 'Home')">Collections</a></li>
86        <li>
87            <a href="javascript:void(0)" class="tablinks" onclick="openTab(event, 'Covers')">
88                <img src="images/search_icon.png" style="height: 20px; vertical-align: top;">Search Issues</a>
89        </li>
90        <li>
91            <a id="articlesTab" href="javascript:void(0)" class="tablinks" onclick="openTab(event, 'Articles')">
92                <img src="images/search_icon.png" style="height: 20px; vertical-align: top;">Search Articles</a>
93        </li>
94        <li v-if="mode === 'edit'"><a style="padding-left: 10px; padding-right: 10px;" id="basketTab"
95                                      href="javascript:void(0)" class="tablinks"
96                                      onclick="openTab(event, 'Basket')">My View</a></li>
97    </ul>
98
99    <ul class="tab" v-if="mobile">
100        <li><a style="padding-left: 10px; padding-right: 10px;" href="javascript:void(0)" class="tablinks active"
101               onclick="openTab(event, 'Sources')">Sources</a></li>
102        <li><a style="padding-left: 10px; padding-right: 10px;" href="javascript:void(0)" class="tablinks"
103               onclick="openTab(event, 'Home')">Collections</a></li>
104        <li><a style="padding-left: 10px; padding-right: 10px;" href="javascript:void(0)" class="tablinks"
105               onclick="openTab(event, 'Covers')"><img src="images/search_icon.png"
106                                                       style="height: 20px; vertical-align: top;">Issues</a></li>
107        <li>
108            <a style="padding-left: 10px; padding-right: 10px;" href="javascript:void(0)"
109               class="tablinks" onclick="openTab(event, 'Articles')">
110                <img src="images/search_icon.png" style="height: 20px; vertical-align: top;">
111                Articles
112            </a>
113        </li>
114    </ul>
115
116    <div id="Home" class="tabcontent">
117        <p>Explore <b>{{ collectionsCount }}</b> collections of high-quality articles, podcasts and videos.</p>
118        <filter-input v-model="collectionsFilter"></filter-input>
119
120        <span v-if='collectionsFilter.length > 0'>
121            &nbsp;=&nbsp;<b>{{ filteredCollections.length }}</b> collection{{ filteredCollections.length == 1 ? "" : "s"
122            }}.
123        </span>
124        <div v-if="collectionsFilter.length > 0" style="text-align: center">
125            <br/>
126            <br/>
127            <div v-for="c in filteredCollections" :class="mobile ? 'collectionCardMobile' : 'collectionCard'">
128                <a :href="collectionLink(c.group.folder, c)" target="_blank"><p
129                        style="margin: 0px; color: deepskyblue; font-size: 90%">{{ c.type }}</p>
130                    <h3 style="margin: 0px;">{{ c.title }}</h3>
131                    <p style="margin-top: 0px; color: lightgrey; font-size: 90%">{{ c.subtitle }}</p>
132                    <img :style="'max-width: 170px;height:120px;filter: grayscale(100%);'"
133                         :src="'collections/' + c.group.folder + '/images/' + c.id + '_thumb.jpg'"/></a>
134            </div>
135        </div>
136        <div v-if="collectionsFilter.length === 0"
137             v-for="group in about.collectionGroups"
138             style="text-align: left">
139            <br/>
140            <h2 style="margin-bottom: 10px; margin-top: 40px;">{{ group.name }}</h2>
141            <p v-if="group.intro" style="color: grey; margin-top: 0;" v-html="mdToHtml(group.intro)"></p>
142            <div style="text-align: center">
143                <div v-for="c in group.collections" :class="mobile ? 'collectionCardMobile' : 'collectionCard'">
144                    <a :href="collectionLink(group.folder, c)" target="_blank"><p
145                            style="margin: 0px; color: deepskyblue; font-size: 90%">{{ c.type }}</p>
146                        <h3 style="margin: 0px;">{{ c.title }}</h3>
147                        <p style="margin-top: 0px; color: lightgrey; font-size: 90%">{{ c.subtitle }}</p>
148                        <img :style="'max-width: 170px; height:120px;filter: grayscale(100%);'"
149                             :src="'collections/' + group.folder + '/images/' + c.id + '_thumb.jpg'"/></a>
150                </div>
151            </div>
152            <br/>
153        </div>
154    </div>
155
156
157    <div id="Sources" class="tabcontent">
158        <div :class="mobile ? 'groupMobile' : 'group'">
159            <a name="sources"></a>
160            <sources :sources="sources" :mobile="mobile"></sources>
161        </div>
162        <div :class="mobile ? 'groupMobile' : 'group'">
163            <h2>What is this Site?</h2>
164            <ul>
165                <li>This site contains <a href='https://obren.io' target="_blank">Željko Obrenović</a>'s
166                    curated collections of articles, podcasts, and quotes on technology trends.
167                </li>
168                <li>This site is a free hobby project and does not generate any income.</li>
169                <li>Grounded in a carefully selected and limited number of practitioner-friendly,
170                    <a href="#sources">authoritative sources</a>.
171                </li>
172                <li>Focused of high-quality sources that peer-review articles, and edit articles to improve readability.
173                </li>
174            </ul>
175            <h2>Key Principles</h2>
176            <ul>
177                <li>
177Creating Pragmatic, Holistic, Well Balanced View on Technology Trends.</li>
178                <li>Antidote to Misplaced Simplicity, Ignorance, Clichés, and Hype.</li>
179            </ul>
180            <h2>Target Audience</h2>
181            <ul>
182                <li>All knowledge-driven technology professionals and leaders.</li>
183                <li>Tech Leads, IT Architects, CTOs, CIOs, anyone interested in technology trends.</li>
184            </ul>
185            <h2>Privacy</h2>
186            <ul>
187                <li>This static site does not collect personal information. It configures Google Analytics to anonymize IP addresses and to not share data with Google.</li>
188            </ul>
189        </div>
190        <div :class="mobile ? 'groupMobile' : 'group'">
191            <h3>Editor: <a href="https://obren.io/" target="_blank">Željko Obrenović</a></h3>
192            <img src='images/twitter.png' width='32' style='margin: 8px' align='center'/>Twitter: <a target='_blank'
193                                                                                                     href='https://twitter.com/zeljko_obren'><b>@zeljko_obren</b></a>
194            <br/><img src='images/linkedin.png' width='32' style='margin: 8px' align='center'/>LinkedIn: <a
195                target='_blank' href='https://www.linkedin.com/in/zeljkoobrenovic/'>zeljkoobrenovic</a>
196        </div>
197    </div>
198
199    <div id="Covers" class="tabcontent">
200        <p>A searchable index (by theme and year) of all <b>{{ chapters.length }}</b> {{ about.source }} issues.</p>
201
202        <filter-input v-model="issuesFilter"></filter-input>
203
204        <span v-if='issuesFilter.length > 0'>
205            &nbsp;=&nbsp;<b>{{ filteredChapters.length }}</b> cover page{{ filteredChapters.length == 1 ? "" : "s" }}.
206        </span>
207
208        <br v-if="mobile"/>
209        <input id="groupPerYear" name="groupPerYear" v-model="groupPerYear" type="checkbox"/>
210        <label for="groupPerYear">group</label>
211
212        <input id="textOnly" name="textOnly" v-model="textOnly" type="checkbox"/>
213        <label for="textOnly">text</label>
214
215        <span style="margin-left:25px">size:</span>
216
217        <select class='cover-size-select' name="imageWidth" v-model="imageWidth">
218            <option v-for="item in coverSizes" :value="item.value">{{item.label}}</option>
219        </select>
220
221        <br/>
222
223        <covers :issues="filteredChapters" :group-per-year="groupPerYear" :image-width="imageWidth" :mobile='mobile'
224                :height-width-ratio="about.coverPageHeightWidthRatio" :show-latest="issuesFilter.length === 0"
225                :show-articles='showArticles' :text-only="textOnly"></covers>
226
227        <button v-if="filteredChapters.length < allFilteredChaptersLength" class="dropbtn" @click="showMoreCovers()">
228            Show More...
229        </button>
230    </div>
231
232    <div id="Articles" class="tabcontent">
233        <p>
234            A searchable index (title, author, year) of all <b>{{ totalArticlesCount.toLocaleString() }}</b> {{
235                about.source }} articles.
236        </p>
237
238        <span v-if="about.commonThemes && about.commonThemes.length > 0">
239            <b>Trending:</b>
240            <div v-for="theme in about.commonThemes"
241                 style="display: inline-block; margin: 4px; padding: 4px; background-color: yellow">
242                <a href @click.prevent="setArticlesFilter(theme)">{{ theme.displayText }}</a>
243            </div>
244            <br/><br/>
245        </span>
246
247        <timeline :all-years="allArticlesYears" :selected-years="selectedArticlesYears"
248                  v-if="articlesFilter.length > 0"></timeline>
249
250        <div>
251            <br v-if="articlesFilter.length > 0"/><img src='images/search_icon.png' height='40'
252                                                       style='vertical-align:middle'/>
253            <input id="filter" style='padding: 0; width: calc(60% - 100px); height: 30px'
254                   :placeholder="'Search ' + totalArticlesCount.toLocaleString() + ' articles'"
255                   @keydown.enter="doArticlesFiltering()"/>
256            <select style="height: 30px" v-model="filterScope">
257                <option>title</option>
258                <option>
258authors</option>
259                <option>abstract</option>
260                <option>year</option>
261            </select>
262            <button @click="doArticlesFiltering()"
263                    class="dropbtn">SEARCH
264            </button>
265            <span v-if='articlesFilter.length > 0'>
266                &nbsp;=&nbsp; <b>{{ filteredArticlesCount }}</b>
267                article{{ articlesFilter.length == 1 ? "" : "s" }}
268                <span v-if="displayedArticlesCount !== filteredArticlesCount">(showing {{ filteredArticles.length
269                    }})</span>
270                <articles-stats :article-items='filteredArticleItems'></articles-stats>
271            </span>
272            <div v-if="progressGoal > 0 && progressCount < progressGoal" style="margin-bottom: 20px;">
273                Searching, please wait...
274                <div :style="'color: grey; width: 12px; height: 8px; display: inline-block; background-color: ' + (i < progressCount ? 'skyblue' : 'lightgrey;')"
275                     v-for="i in Array.from(Array(progressGoal).keys())"></div>
276                <span v-if="progressCount > 0">{{ Math.round(100 * progressCount / progressGoal) }}%</span>
277            </div>
278            <br/>
279            <label style="margin-left: 42px;"><input type="checkbox" v-model="wholeWordSearch"/> whole word</label>
280            <label><input type="checkbox" v-model="showAbstracts"/> show abstracts</label>
281            <span v-if="mode === 'edit'">
282                <br/><button @click.stop="addAllToBasket(filteredArticles)" class="dropbtn">Add All By Theme</button>
283                <button @click.stop="addAllToBasketOldestFirst(filteredArticles)" class="dropbtn">Add All By Year (Oldest First)</button>
284            </span>
285        </div>
286
287
288        <hr/>
289        <table :class="mobile ? '' : 'group'" style="width:100%;" v-if="articlesFilter">
290            <template v-for="(article, index) in filteredArticles">
291                <tr v-if="index === 0 || filteredArticles[index].year !== filteredArticles[index - 1].year">
292                    <td colspan="2" align="right">
293                        <h1 style="margin-top: 36px; margin-bottom: 0px;">{{ article.year }}</h1>
294                        <a :href="'https://wikipedia.org/wiki/' + article.year" target="_blank" style="color: grey">wikipedia</a>
295                        <a v-if="article.year >= 1933 && article.year <= 2015"
296                           :href="'http://www.computerhistory.org/timeline/' + article.year" target="_blank">CS
297                            museum</a>
298                    </td>
299                </tr>
300                <tr v-if="index === 0 || filteredArticles[index].source.displayName !== filteredArticles[index - 1].source.displayName">
301                    <td colspan="2"><h3 style="margin-top: 36px; margin-bottom: 0px;">
302                        {{ article.source.defaultTag }} / <a target="_blank" :href="'../' + article.source.id">{{
303                            article.source.displayName }}</a>
304                    </h3></td>
305                </tr>
306                <tr>
307                    <td v-if="!mobile" style="width: 40px; padding-top: 20px; text-align: right;" valign="top">{{ index
308                    + 1 }}.
309                    </td>
310                    <td style="padding-top: 20px">
311                        <article-abstract :article="article"
312                                          :show-authors="true"
313                                          :source="about.source" :mobile="mobile"
314                                          :show-all-abstracts="showAbstracts"
315                                          :get-link-text="getLinkText"
316                                          :mobile="mobile"
317                                          :get-digital-library-link="getDigitalLibraryLink">
318                        </article-abstract>
319                    </td>
320                    <td v-if="mode === 'edit'">
321                        <dropdown button-text='Add...' :options='getBasketSectionOptions(article)'></dropdown>
322                        <button @click='copyJSON($event, article)' class="dropbtn">Copy JSON...</button>
323                    </td>
324            </template>
325            </tr>
326            <tr>
327                <td></td>
328            </tr>
329        </table>
330    </div>
331
332    <div id="Basket" class="tabcontent" v-if="mode === 'edit'">
333        <basket :source="about.source"
334                :basket="basket"
335                :mobile="mobile"
336                :show-all-abstracts="showAbstracts"
337                :get-link-text="getLinkText"
338                :get-digital-library-link="getDigitalLibraryLink">
339        </basket>
340    </div>
341    <modal-editor></modal-editor>
342    <modal-input></modal-input>
343    <div id="modal" class="modal" v-if="showModalDialog">
344        <div :class="mobile ? 'modal-content-mobile' : 'modal-content'">
345            <span class="close" @click.prevent="closeModalDialog()">&times;</span>
346            <span>
347                <h2><a :href="'https://obren359.com/library/' + modalChapter.source.id"
348                       target="_blank">{{ modalChapter.source.displayName }}</a><br/>
349                    <span style="color: #5DADE2;">{{ modalChapterDescription }}</span></h2>
350            <div style="margin-left: 16px; margin-top: 2px; margin-bottom: 0">
351                <input v-model="modalTextFilter" placeholder="search" style="height: 32px; width: 400px">
352                = <span style="color:grey"><b>{{ filteredModalArticles().length }}</b>
353                {{ modalFilteredArticles.length === 1 ? 'article' : 'articles' }}</span>
354                <br><br>
355                <label v-if="!mobile"><input type="checkbox" v-model="modalShowAbstracts"/> show
356                    abstracts&nbsp;&nbsp;</label>
357            </div>
358                <a v-if="showDigLibLink(modalChapter)"
359                   :href="getIssueDigitalLibraryLink(modalChapter, modalYear, modalIssue)" target="_blank">View in digital library</a>
360            <br/>
361            <br/>
362            </span>
363            </span>
364            <div :class="mobile ? 'modal-articles-list-mobile' : 'modal-articles-list'">
365                <table style="padding: 0">
366                    <tr v-if="modalFilteredArticlesCount === -1">
367                        <td>Loading articles...</td>
368                    </tr>
369                    <tr v-for="article in filteredModalArticles()">
370                        <td>
371                            <article-abstract :article="article"
372                                              :show-authors="true"
373                                              :source="about.source" :mobile="mobile"
374                                              :show-all-abstracts="articles.length === 1 || modalShowAbstracts"
375                                              :get-link-text="getLinkText"
376                                              :get-digital-library-link="getDigitalLibraryLink">
377                            </article-abstract>
378                            <br/>
379                        </td>
380                    </tr>
381                </table>
382                <br><br><br>
383                <br><br><br>
384                <br>
385            </div>
386        </div>
387    </div>
388</div>
389
390<script>
391    logEvent('page_visit', location.href);
392    openTab(null, 'Sources');
393    document.getElementsByClassName("tablinks")[0].className += " active";
394    document.getElementsByClassName("tablinks")[5].className += " active";
395    var modeParam = findGetParameter("mode");
396    if (modeParam) {
397        mode = modeParam;
398    }
399</script>
399
400
401<div id="loading" style="position: fixed; left: 10%; top: 20px">
402    <a href="https://obren.io"><img height='46' src="images/logo.png"/></a>
403    <h1>Loading Tech Trends Radar...</h1>
404</div>
405
406</body>
407</html>

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.