PageSourceSearch

https://interspiro.de/Files/Templates/Designs/Dwsimple/js/jquery.socialfeed.js

js interspiro.de collected 2026-09-26 08:24:17 UTC 46,674 bytes, 923 lines download raw bytes

1if (typeof Object.create !== 'function') {
2    Object.create = function (obj) {
3        function F() { }
4        F.prototype = obj;
5        return new F();
6    };
7}
8
9(function ($, window, document, undefined) {
10    $.fn.socialfeed = function (_options) {
11
12        var defaults = {
13            plugin_folder: '', // a folder in which the plugin is located (with a slash in the end)
14            template: 'template.html', // a path to the template file
15            show_media: false, // show images of attachments if available
16            media_min_width: 300,
17            length: 500, // maximum length of post message shown
18            date_format: 'll',
19            date_locale: 'en'
20        };
21        //---------------------------------------------------------------------------------
22        var options = $.extend(defaults, _options),
23            container = $(this),
24            template,
25            social_networks = ['facebook', 'instagram', 'vk', 'google', 'blogspot', 'pinterest', 'rss'],
26            posts_to_load_count = 0,
27            loaded_post_count = 0;
28        // container.empty().css('display', 'block');
29        //---------------------------------------------------------------------------------
30
31        //---------------------------------------------------------------------------------
32        // This function performs consequent data loading from all of the sources by calling corresponding functions
33        function calculatePostsToLoadCount() {
34            social_networks.forEach(function (network) {
35                if (options[network]) {
36                    if (options[network].accounts) {
37                        posts_to_load_count += options[network].limit * options[network].accounts.length;
38                    } else if (options[network].urls) {
39                        posts_to_load_count += options[network].limit * options[network].urls.length;
40                    } else {
41                        posts_to_load_count += options[network].limit;
42                    }
43                }
44            });
45        }
46
47        calculatePostsToLoadCount();
48
49
50
51
52        function fireCallback() {
53            var fire = true;
54            social_networks.forEach(function (network) {
55                if (Feed[network]) {
56                    Feed[network].accountsToLoad.forEach(function (account) {
57                        if (!account.loaded) {
58                            fire = false;
59                        }
60                    });
61                }
62            });
63            if (fire && options.callback) {
64                options.callback();
65            }
66        }
67
68        var Utility = {
69            request: function (url, callback) {
70                $.ajax({
71                    url: url,
72                    dataType: 'jsonp',
73                    success: callback,
74                    error: function () {
75                        posts_to_load_count--;
76                    }
77                });
78            },
79            get_request: function (url, callback) {
80                $.get(url, callback, 'json');
81            },
82            wrapLinks: function (string, social_network) {
83                var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
84                if (social_network === 'google-plus') {
85                    string = string.replace(/(@|#)([a-z0-9_]+['])/ig, Utility.wrapGoogleplusTagTemplate);
86                } else {
87                    string = string.replace(exp, Utility.wrapLinkTemplate);
88                }
89                return string;
90            },
91            wrapLinkTemplate: function (string) {
92                return '<a target="_blank" href="' + string + '">' + string + '<\/a>';
93            },
94            wrapGoogleplusTagTemplate: function (string) {
95                return '<a target="_blank" href="https://plus.google.com/s/' + string + '" >' + string + '<\/a>';
96            },
97            shorten: function (string) {
98                string = $.trim(string);
99                if (string.length > options.length) {
100                    return jQuery.trim(string).substring(0, options.length).split(" ").slice(0, -1).join(" ") + "...";
101                } else {
102                    return string;
103                }
104            },
105            stripHTML: function (string) {
106                if (typeof string === "undefined" || string === null) {
107                    return '';
108                }
109                return string.replace(/(<([^>]+)>)|nbsp;|\s{2,}|/ig, "");
110            }
111        };
112
113        function SocialFeedPost(social_network, data) {
114            if (!data) {
115                return;
116            }
117            this.content = data;
118            this.content.social_network = social_network;
119            this.content.attachment = (this.content.attachment === undefined) ? '' : this.content.attachment;
120            this.content.time_ago = data.dt_create.locale(options.date_locale).fromNow();
121            this.content.date = data.dt_create.locale(options.date_locale).format(options.date_format);
122            this.content.dt_create = this.content.dt_create.valueOf();
123            this.content.text = Utility.wrapLinks(Utility.shorten(data.message + ' ' + data.description), data.social_network);
124            this.content.moderation_passed = (options.moderation) ? options.moderation(this.content) : true;
125
126            Feed[social_network].posts.push(this);
127        }
128        SocialFeedPost.prototype = {
129            render: function () {
130                var rendered_html = Feed.template(this.content);
131                var data = this.content;
132
133                if ($(container).children('[social-feed-id=' + data.id + ']').length !== 0) {
134                    return false;
135                }
136                if ($(container).children().length === 0) {
137                    $(container).append(rendered_html);
138                } else {
139                    var i = 0,
140                        insert_index = -1;
141                    $.each($(container).children(), function () {
142                        if ($(this).attr('dt-create') < data.dt_create) {
143                            insert_index = i;
144                            return false;
145                        }
146                        i++;
147                    });
148                    $(container).append(rendered_html);
149                    if (insert_index >= 0) {
150                        insert_index++;
151                        var before = $(container).children('div:nth-child(' + insert_index + ')'),
152                            current = $(container).children('div:last-child');
153                        $(current).insertBefore(before);
154                    }
155
156                }
157                if (options.media_min_width) {
158
159                    var query = '[social-feed-id=' + data.id + '] img.attachment';
160                    var image = $(query);
161
162                    // preload the image
163                    var height, width = '';
164                    var img = new Image();
165                    var imgSrc = image.attr("src");
166
167                    $(img).load(function () {
168
169                        if (img.width < options.media_min_width) {
170                            image.hide();
171                        }
172                        // garbage collect img
173                        delete img;
174
175                    }).error(function () {
176                        // image couldnt be loaded
177                        image.hide();
178
179                    }).attr({
180                        src: imgSrc
181                    });
182
183                }
184
185                //loaded_post_count++;
186                //console.log("loads", loaded_post_count, posts_to_load_count);
187                //if (loaded_post_count == posts_to_load_count) {
188                //    fireCallback();
189                //}
190
191                //this.rendered = true;
192
193                //var finished = true;
194                //social_networks.forEach(function (network) {
195                //    if (Feed[network] && Feed[network].posts) {
196                //        for (var i = 0; i < Feed[network].posts.length; i++) {
197                //            var post = Feed[network].posts[i];
198                //            if (!post.rendered) {
199                //                finished = false;
200                //            }
201                //        }
202                //    }
203                //});
204                //if (finished) {
205                //    fireCallback();
206                //}
207
208            }
209
210        };
211
212        var Feed = {
213            template: false,
214            init: function () {
215                Feed.getTemplate(function () {
216                    social_networks.forEach(function (network) {
217                        if (options[network]) {
218                            if (options[network].accounts) {
219                                Feed[network].accountsToLoad = options[network].accounts.map(function (account) {
220                                    return {
221                                        name: account,
222                                        loaded: false
223                                    };
224                                });
225
226                                //loaded[network] = 0;
227                                options[network].accounts.forEach(function (account) {
228                                    //loaded[network]++;
229                                    Feed[network].getData(account);
230                                });
231                            } else if (options[network].urls) {
232                                options[network].urls.forEach(function (url) {
233                                    Feed[network].getData(url);
234                                });
235                            } else {
236                                Feed[network].getData();
237                            }
238                        }
239                    });
240                });
241            },
242            getTemplate: function (callback) {
243                if (Feed.template)
244                    return callback();
245                else {
246                    if (options.template_html) {
247                        Feed.template = doT.template(options.template_html);
248                        return callback();
249                    } else {
250                        $.get(options.template, function (template_html) {
251                            Feed.template = doT.template(template_html);
252                            return callback();
253                        });
254                    }
255                }
256            },
257            twitter: {
258                posts: [],
259                accountsToLoad: [],
260                loaded: false,
261                api: 'http://api.tweecool.com/',
262
263                getData: function (account) {
264
265                    var cb = new Codebird();
266                    cb.setConsumerKey(options.twitter.consumer_key, options.twitter.consumer_secret);
267
268                    // Allow setting your own proxy with Codebird
269                    if (options.twitter.proxy !== undefined) {
270                        cb.setProxy(options.twitter.proxy);
271                    }
272
273                    switch (account[0]) {
274                        case '@':
275                            var userid = account.substr(1);
276                            cb.__call(
277                                "statuses_userTimeline",
278                                "id=" + userid + "&count=" + options.twitter.limit,
279                                function (reply) {
280                                    Feed.twitter.utility.getPosts(reply, account)
281                                },
282                                true // this parameter required
283                            );
284                            break;
285                        case '#':
286                            var hashtag = account.substr(1);
287                            cb.__call(
288                                "search_tweets",
289                                "q=" + hashtag + "&count=" + options.twitter.limit,
290                                function (reply) {
291                                    Feed.twitter.utility.getPosts(reply.statuses, account);
292                                },
293                                true // this parameter required
294                            );
295                            break;
296                        default:
297                    }
298                },
299                utility: {
300                    getPosts: function (json, account) {
301                        if (json) {
302                            $.each(json, function () {
303                                var element = this;
304                                var post = new SocialFeedPost('twitter', Feed.twitter.utility.unifyPostData(element));
305                                if (post.content) {
306                                    post.render();
307                                }
308                            });
309                            Feed.twitter.accountsToLoad.forEach(function (acc) {
310                                if (acc.name === account) {
311                                    acc.loaded = true;
312                                }
313                            });
314                            fireCallback();
315                        }
316                    },
317                    unifyPostData: function (element) {
318                        var post = {};
319                        if (element.id) {
320                            post.id = element.id_str;
321                            //prevent a moment.js console warning due to Twitter's poor date format.
322                            post.dt_create = moment(element.created_at, 'dd MMM DD HH:mm:ss ZZ YYYY');
323                            post.author_link = 'http://twitter.com/' + element.user.screen_name;
324                            post.author_picture = element.user.profile_image_url_https;
325                            post.post_url = post.author_link + '/status/' + element.id_str;
326                            post.author_name = element.user.name;
327                            post.message = element.text;
328                            post.description = '';
329                            post.link = 'http://twitter.com/' + element.user.screen_name + '/status/' + element.id_str;
330
331                            if (options.show_media === true) {
332                                if (element.entities.media && element.entities.media.length > 0) {
333                                    var image_url = element.entities.media[0].media_url_https;
334                                    if (image_url) {
335                                        post.attachment = '<img class="attachment" src="' + image_url + '" />';
336                                    }
337                                }
338                            }
339                        }
340                        if (post.author_name == "Interspiro") {
341                            return post;
342                        }
343                        else {
344                            return false;
345                        }
346                    }
347                }
348            },
349            facebook: {
350                posts: [],
351                graph: 'https://graph.facebook.com/',
352                accountsToLoad: [],
353                loaded: false,
354                getData: function (account) {
355                    var proceed = function (request_url) {
356                        Utility.request(request_url, function (reply) { Feed.facebook.utility.getPosts(reply, account); });
357                    };
358                    var fields = '?fields=id,from,message,created_time,story';
359                    fields += (options.show_media === true) ? ',full_picture' : '';
360                    var request_url, limit = '&limit=' + options.facebook.limit,
361                        query_extention = '&access_token=' + options.facebook.access_token + '&callback=?';
362                    switch (account[0]) {
363                        case '@':
364                            var username = account.substr(1);
365                            Feed.facebook.utility.getUserId(username, function (userdata) {
366                                if (userdata.id !== '') {
367                                    request_url = Feed.facebook.graph + 'v8.0/' + userdata.id + '/posts' + fields + limit + query_extention;
368                                    proceed(request_url);
369                                }
370                            });
371                            break;
372                        case '!':
373                            var page = account.substr(1);
374                            request_url = Feed.facebook.graph + 'v8.0/' + page + '/feed' + fields + limit + query_extention;
375                            console.log(request_url)
376                            proceed(request_url);
377                            break;
378                        default:
379                            proceed(request_url);
380                    }
381                },
382                utility: {
383                    getUserId: function (username, callback) {
384                        var query_extention = '&access_token=' + options.facebook.access_token + '&callback=?';
385                        var url = 'https://graph.facebook.com/' + username + '?' + query_extention;
386                        var result = '';
387                        $.get(url, callback, 'json');
388                    },
389                    prepareAttachment: function (element) {
390                        var image_url = element.full_picture;
391                        if (image_url.indexOf('_b.') !== -1) {
392                            //do nothing it is already big
393                        } else if (image_url.indexOf('safe_image.php') !== -1) {
394                            image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'url');
395
396                        } else if (image_url.indexOf('app_full_proxy.php') !== -1) {
397                            image_url = Feed.facebook.utility.getExternalImageURL(image_url, 'src');
398
399                        } else if (element.object_id) {
400                            image_url = Feed.facebook.graph + element.object_id + '/picture/?type=normal';
401                        }
402
403                        return '<img class="attachment" src="' + image_url + '" />';
404                    },
405                    getExternalImageURL: function (image_url, parameter) {
406                        image_url = decodeURIComponent(image_url).split(parameter + '=')[1];
407                        if (image_url.indexOf('fbcdn-sphotos') === -1) {
408                            return image_url.split('&')[0];
409                        } else {
410                            return image_url;
411                        }
412
413                    },
414                    getPosts: function (json, account) {
415                        if (json['data']) {
416                            if (json['data'].length < options.facebook.limit) {
417                                posts_to_load_count -= (options.facebook.limit - json['data'].length);
418                            }
419                            json['data'].forEach(function (element) {
420                                var post = new SocialFeedPost('facebook', Feed.facebook.utility.unifyPostData(element));
421                                post.render();
422                            });
423                        }
424                        Feed.facebook.accountsToLoad.forEach(function (acc) {
425                            if (acc.name === account) {
426                                acc.loaded = true;
427                            }
428                        });
429                        fireCallback();
430                    },
431                    unifyPostData: function (element) {
432                        var post = {},
433                            text = (element.message) ? element.message : element.story;
434
435                        post.id = element.id;
436                        post.dt_create = moment(element.created_time);
437                        if (element.from) {
438                            if (element.from.id) {
439                                post.author_link = 'http://facebook.com/' + element.from.id;
440                                post.author_picture = Feed.facebook.graph + element.from.id + '/picture';
441                            }
442
443                            post.author_name = element.from.name;
444                        }
445                        post.name = element.name || "";
446                        post.message = (text) ? text : '';
447                        post.description = (element.description) ? element.description : '';
448                        post.link = (element.link) ? element.link : (element.from) ? 'http://facebook.com/' + element.from.id : '';
449
450                        if (options.show_media === true) {
451                            if (element.full_picture) {
452                                var attachment = Feed.facebook.utility.prepareAttachment(element);
453                                if (attachment) {
454                                    post.attachment = attachment;
455                                }
456                            }
457                        }
458                        return post;
459                    }
460                }
461            },
462            google: {
463                posts: [],
464                accountsToLoad: [],
465                loaded: false,
466                api: 'https://www.googleapis.com/plus/v1/',
467                getData: function (account) {
468                    var request_url;
469                    switch (account[0]) {
470                        case '#':
471                            var hashtag = account.substr(1);
472                            request_url = Feed.google.api + 'activities?query=' + hashtag + '&key=' + options.google.access_token + '&maxResults=' + options.google.limit;
473                            Utility.get_request(request_url, function (reply) { Feed.google.utility.getPosts(reply, account) });
474                            break;
475                        case '@':
476                            var username = account.substr(1);
477                            request_url = Feed.google.api + 'people/' + username + '/activities/public?key=' + options.google.access_token + '&maxResults=' + options.google.limit;
478                            Utility.get_request(request_url, function (reply) { Feed.google.utility.getPosts(reply, account) });
479                            break;
480                        default:
481                    }
482                },
483                utility: {
484                    getPosts: function (json, account) {
485                        if (json.items) {
486                            $.each(json.items, function (i) {
487                                var post = new SocialFeedPost('google', Feed.google.utility.unifyPostData(json.items[i]));
488                                post.render();
489                            });
490                        }
491                        Feed.google.accountsToLoad.forEach(function (acc) {
492                            if (acc.name === account) {
493                                acc.loaded = true;
494                            }
495                        });
496                        fireCallback();
497                    },
498                    unifyPostData: function (element) {
499                        var post = {};
500
501                        post.id = element.id;
502                        post.attachment = '';
503                        post.description = '';
504                        post.dt_create = moment(element.published);
505                        post.author_link = element.actor.url;
506                        post.author_picture = element.actor.image.url;
507                        post.author_name = element.actor.displayName;
508
509                        if (options.show_media === true) {
510                            if (element.object.attachments) {
511                                $.each(element.object.attachments, function () {
512                                    var image = '';
513                                    if (this.fullImage) {
514                                        image = this.fullImage.url;
515                                    } else {
516                                        if (this.objectType === 'album') {
517                                            if (this.thumbnails && this.thumbnails.length > 0) {
518                                                if (this.thumbnails[0].image) {
519                                                    image = this.thumbnails[0].image.url;
520                                                }
521                                            }
522                                        }
523                                    }
524                                    post.attachment = '<img class="attachment" src="' + image 
524+ '"/>';
525                                });
526                            }
527                        }
528                        post.message = element.title;
529                        post.link = element.url;
530
531                        return post;
532                    }
533                }
534            },
535            instagram: {
536                posts: [],
537                api: 'https://graph.instagram.com/',
538                accountsToLoad: [],
539                loaded: false,
540                accessType: function () {
541                    // If we have both the client_id and access_token set in options,
542                    // use access_token for authentication. If client_id is not set
543                    // then use access_token. If neither are set, log an error to console.
544                    if (typeof options.instagram.access_token === 'undefined' && typeof options.instagram.client_id === 'undefined') {
545                        console.log('You need to define a client_id or access_token to authenticate with Instagram\'s API.');
546                        return undefined;
547                    }
548                    if (options.instagram.access_token) { options.instagram.client_id = undefined; }
549                    options.instagram.access_type = (typeof options.instagram.client_id === 'undefined' ? 'access_token' : 'client_id');
550                    return options.instagram.access_type;
551                },
552                getData: function (account) {
553                    var url;
554                    var InstagramAccount = $('.instagram-social').attr('data-instagram-id');
555                    var InstagramID = $('.instagram-social').attr('data-instagram-id');
556                    // API endpoint URL depends on which authentication type we're using.
557                    if (this.accessType() !== 'undefined') {
558                        var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type];
559                    }
560
561                    switch (account[0]) {
562                        case '@':
563                            var username = account.substr(1);
564                            url = Feed.instagram.api + '/' + InstagramID + '/media?fields=id,media_url,media_type,caption,username,timestamp,permalink&' + authTokenParams + '&' + 'limit=' + options.instagram.limit + '&callback=?';
565                            console.log("@:" + url)
566                            Utility.request(url, Feed.instagram.utility.getImages);
567
568                            break;
569                        case '#':
570                            var hashtag = account.substr(1);
571                            url = Feed.instagram.api + 'tags/' + hashtag + '/media/recent/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?';
572                            Utility.request(url, function (reply) { Feed.instagram.utility.getImages(reply, account) });
573                            console.log("#:" + url)
574                            break;
575                        case '&':
576                            var id = account.substr(1);
577                            url = Feed.instagram.api + 'users/' + id + '/?' + authTokenParams + '&' + 'count=' + options.instagram.limit + '&callback=?';
578                            console.log("&:" + url)
579                            Utility.request(url, function (reply) { Feed.instagram.utility.getUsers(reply, account) });
580                        default:
581                    }
582                },
583                utility: {
584                    getImages: function (json, account) {
585                        if (json.data) {
586                            json.data.forEach(function (element) {
587                                if (element.media_type == "IMAGE") {
588                                    var post = new SocialFeedPost('instagram', Feed.instagram.utility.unifyPostData(element));
589
590                                    post.render();
591                                }
592
593                            });
594                        }
595                        Feed.instagram.accountsToLoad.forEach(function (acc) {
596                            if (acc.name === account) {
597                                acc.loaded = true;
598                            }
599                        });
600                        fireCallback();
601                    },
602                    getUsers: function (json, account) {
603                        // API endpoint URL depends on which authentication type we're using.
604                        if (options.instagram.access_type !== 'undefined') {
605                            var authTokenParams = options.instagram.access_type + '=' + options.instagram[options.instagram.access_type];
606                        }
607
608                        if (!jQuery.isArray(json.data)) json.data = [json.data]
609                        json.data.forEach(function (user) {
610                            var InstagramAccount = $('.instagram-social').attr('data-instagram-id');
611                            var InstagramID = $('.instagram-social').attr('data-instagram-id');
612
613                            var url = Feed.instagram.api + '/' + InstagramID + '/media?fields=id,media_url,media_type,caption,username,timestamp,permalink&' + authTokenParams + '&' + 'limit=' + options.instagram.limit + '&callback=?';
614                            Utility.request(url, Feed.instagram.utility.getImages);
615                        });
616                        Feed.instagram.accountsToLoad.forEach(function (acc) {
617                            if (acc.name === account) {
618                                acc.loaded = true;
619                            }
620                        });
621                        fireCallback();
622                    },
623                    unifyPostData: function (element) {
624                        if (element.media_type == 'IMAGE') {
625                            var post = {};
626
627                            post.id = element.id;
628                            post.dt_create = moment(element.timestamp * 1000);
629                            post.author_link = 'http://instagram.com/' + element.username;
630                            //post.author_picture = element.user.profile_picture;
631                            post.author_name = element.username;
632                            post.message = (element.caption && element.caption) ? element.caption : '';
633                            post.description = '';
634                            post.link = element.permalink;
635                            if (options.show_media) {
636                                post.attachment = '<img class="attachment" src="' + element.media_url + '' + '" />';
637                            }
638                            return post;
639                        }
640
641                    }
642                }
643            },
644            vk: {
645                posts: [],
646                accountsToLoad: [],
647                loaded: false,
648                base: 'http://vk.com/',
649                api: 'https://api.vk.com/method/',
650                user_json_template: 'https://api.vk.com/method/' + 'users.get?fields=first_name,%20last_name,%20screen_name,%20photo&uid=',
651                group_json_template: 'https://api.vk.com/method/' + 'groups.getById?fields=first_name,%20last_name,%20screen_name,%20photo&gid=',
652                getData: function (account) {
653                    var request_url;
654
655                    switch (account[0]) {
656                        case '@':
657                            var username = account.substr(1);
658                            request_url = Feed.vk.api + 'wall.get?owner_id=' + username + '&filter=' + options.vk.source + '&count=' + options.vk.limit + '&callback=?';
659                            Utility.get_request(request_url, function (reply) { Feed.vk.utility.getPosts(reply, account); });
660                            break;
661                        case '#':
662                            var hashtag = account.substr(1);
663                            request_url = Feed.vk.api + 'newsfeed.search?q=' + hashtag + '&count=' + options.vk.limit + '&callback=?';
664                            Utility.get_request(request_url, function (reply) { Feed.vk.utility.getPosts(reply, account); });
665                            break;
666                        default:
667                    }
668                },
669                utility: {
670                    getPosts: function (json, account) {
671                        if (json.response) {
672                            $.each(json.response, function () {
673                                if (this != parseInt(this) && this.post_type === 'post') {
674                                    var owner_id = (this.owner_id) ? this.owner_id : this.from_id,
675                                        vk_wall_owner_url = (owner_id > 0) ? (Feed.vk.user_json_template + owner_id + '&callback=?') : (Feed.vk.group_json_template + (-1) * owner_id + '&callback=?'),
676                                        element = this;
677                                    Utility.get_request(vk_wall_owner_url, function (wall_owner) {
678                                        Feed.vk.utility.unifyPostData(wall_owner, element, json);
679                                    });
680                                }
681                            });
682                        }
683                        Feed.vk.accountsToLoad.forEach(function (acc) {
684                            if (acc.name === account) {
685                                acc.loaded = true;
686                            }
687                        });
688                        fireCallback();
689                    },
690                    unifyPostData: function (wall_owner, element, json) {
691                        var post = {};
692
693                        post.id = element.id;
694                        post.dt_create = moment.unix(element.date);
695                        post.description = ' ';
696                        post.message = Utility.stripHTML(element.text);
697                        if (options.show_media) {
698                            if (element.attachment) {
699                                if (element.attachment.type === 'link')
700                                    post.attachment = '<img class="attachment" src="' + element.attachment.link.image_src + '" />';
701                                if (element.attachment.type === 'video')
702                                    post.attachment = '<img class="attachment" src="' + element.attachment.video.image_big + '" />';
703                                if (element.attachment.type === 'photo')
704                                    post.attachment = '<img class="attachment" src="' + element.attachment.photo.src_big + '" />';
705                            }
706                        }
707
708                        if (element.from_id > 0) {
709                            var vk_user_json = Feed.vk.user_json_template + element.from_id + '&callback=?';
710                            Utility.get_request(vk_user_json, function (user_json) {
711                                var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getUser(user_json, post, element, json));
712                                vk_post.render();
713                            });
714
715                        } else {
716                            var vk_group_json = Feed.vk.group_json_template + (-1) * element.from_id + '&callback=?';
717                            Utility.get_request(vk_group_json, function (user_json) {
718                                var vk_post = new SocialFeedPost('vk', Feed.vk.utility.getGroup(user_json, post, element, json));
719                                vk_post.render();
720                            });
721                        }
722                    },
723                    getUser: function (user_json, post, element, json) {
724                        post.author_name = user_json.response[0].first_name + ' ' + user_json.response[0].last_name;
725                        post.author_picture = user_json.response[0].photo;
726                        post.author_link = Feed.vk.base + user_json.response[0].screen_name;
727                        post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall' + element.from_id + '_' + element.id;
728
729                        return post;
730                    },
731                    getGroup: function (user_json, post, element, json) {
732                        post.author_name = user_json.response[0].name;
733                        post.author_picture = user_json.response[0].photo;
734                        post.author_link = Feed.vk.base + user_json.response[0].screen_name;
735                        post.link = Feed.vk.base + user_json.response[0].screen_name + '?w=wall-' + user_json.response[0].gid + '_' + element.id;
736
737                        return post;
738                    }
739                }
740            },
741            blogspot: {
742                accountsToLoad: [],
743                loaded: false,
744                getData: function (account) {
745                    var url;
746
747                    switch (account[0]) {
748                        case '@':
749                            var username = account.substr(1);
750                            url = 'http://' + username + '.blogspot.com/feeds/posts/default?alt=json-in-script&callback=?';
751                            request(url, function (reply) { Feed.blogspot.utility.getPosts(reply, account) });
752                            break;
753                        default:
754                    }
755                },
756                utility: {
757                    getPosts: function (json, account) {
758                        $.each(json.feed.entry, function () {
759                            var post = {},
760                                element = this;
761                            post.id = element.id['$t'].replace(/[^a-z0-9]/gi, '');
762                            post.dt_create = moment((element.published['$t']));
763                            post.author_link = element.author[0]['uri']['$t'];
764                            post.author_picture = 'http:' + element.author[0]['gd$image']['src'];
765                            post.author_name = element.author[0]['name']['$t'];
766                            post.message = element.title['$t'] + '</br></br>' + stripHTML(element.content['$t']);
767                            post.description = '';
768                            post.link = element.link.pop().href;
769
770                            if (options.show_media) {
771                                if (element['media$thumbnail']) {
772                                    post.attachment = '<img class="attachment" src="' + element['media$thumbnail']['url'] + '" />';
773                                }
774                            }
775
776                            post.render();
777
778                        });
779                        Feed.blogspot.accountsToLoad.forEach(function (acc) {
780                            if (acc.name === account) {
781                                acc.loaded = true;
782                            }
783                        });
784                        fireCallback();
785                    }
786                }
787            },
788            pinterest: {
789                posts: [],
790                accountsToLoad: [],
791                loaded: false,
792                apiv1: 'https://api.pinterest.com/v1/',
793
794                getData: function (account) {
795                    var request_url,
796                        limit = 'limit=' + options.pinterest.limit,
797                        fields = 'fields=id,created_at,link,note,creator(url,first_name,last_name,image),image',
798                        query_extention = fields + '&access_token=' 
798+ options.pinterest.access_token + '&' + limit + '&callback=?';
799                    switch (account[0]) {
800                        case '@':
801                            var username = account.substr(1);
802                            if (username === 'me') {
803                                request_url = Feed.pinterest.apiv1 + 'me/pins/?' + query_extention;
804                            } else {
805                                request_url = Feed.pinterest.apiv1 + 'boards/' + username + '/pins?' + query_extention;
806                            }
807                            break;
808                        default:
809                    }
810                    Utility.request(request_url, function (reply) { Feed.pinterest.utility.getPosts(reply, account) });
811                },
812                utility: {
813
814                    getPosts: function (json, account) {
815                        json.data.forEach(function (element) {
816                            var post = new SocialFeedPost('pinterest', Feed.pinterest.utility.unifyPostData(element));
817                            post.render();
818                        });
819                        Feed.pinterest.accountsToLoad.forEach(function (acc) {
820                            if (acc.name === account) {
821                                acc.loaded = true;
822                            }
823                        });
824                        fireCallback();
825                    },
826
827                    unifyPostData: function (element) {
828                        var post = {};
829
830                        post.id = element.id;
831                        post.dt_create = moment(element.created_at);
832                        post.author_link = element.creator.url;
833                        post.author_picture = element.creator.image['60x60'].url;
834                        post.author_name = element.creator.first_name + element.creator.last_name;
835                        post.message = element.note;
836                        post.description = '';
837                        post.social_network = 'pinterest';
838                        post.link = element.link ? element.link : 'https://www.pinterest.com/pin/' + element.id;
839                        if (options.show_media) {
840                            post.attachment = '<img class="attachment" src="' + element.image['original'].url + '" />';
841                        }
842                        return post;
843                    }
844                }
845            },
846            rss: {
847                posts: [],
848                accountsToLoad: [],
849                loaded: false,
850                api: 'https://query.yahooapis.com/v1/public/yql?q=',
851                datatype: 'json',
852
853                getData: function (url) {
854                    var limit = options.rss.limit,
855                        yql = encodeURIComponent('select entry FROM feednormalizer where url=\'' + url + '\' AND output=\'atom_1.0\' | truncate(count=' + limit + ')'),
856                        request_url = Feed.rss.api + yql + '&format=json&callback=?';
857
858                    Utility.request(request_url, function (reply) { Feed.rss.utility.getPosts(reply, account) }, Feed.rss.datatype);
859                },
860                utility: {
861
862                    getPosts: function (json, account) {
863                        if (json.query.count > 0) {
864                            $.each(json.query.results.feed, function (index, element) {
865                                var post = new SocialFeedPost('rss', Feed.rss.utility.unifyPostData(index, element));
866                                post.render();
867                            });
868                        }
869                        Feed.rss.accountsToLoad.forEach(function (acc) {
870                            if (acc.name === account) {
871                                acc.loaded = true;
872                            }
873                        });
874                        fireCallback();
875                    },
876
877                    unifyPostData: function (index, element) {
878
879                        var item = element;
880
881                        if (element.entry !== undefined) {
882                            item = element.entry;
883                        }
884                        var post = {};
885
886                        post.id = '"' + item.id + '"';
887                        post.dt_create = moment(item.published, 'YYYY-MM-DDTHH:mm:ssZ', 'en');
888
889                        post.author_link = '';
890                        post.author_picture = '';
891                        post.author_name = '';
892                        if (item.creator !== undefined) {
893                            post.author_name = item.creator;
894                        }
895                        post.message = item.title;
896                        post.description = '';
897                        if (item.summary !== undefined) {
898                            post.description = Utility.stripHTML(item.summary.content);
899                        }
900                        post.social_network = 'rss';
901                        post.link = item.link.href;
902                        if (options.show_media && item.thumbnail !== undefined) {
903                            post.attachment = '<img class="attachment" src="' + item.thumbnail.url + '" />';
904                        }
905                        return post;
906                    }
907                }
908            }
909        };
910
911        //make the plugin chainable
912        return this.each(function () {
913            // Initialization
914            Feed.init();
915            if (options.update_period) {
916                setInterval(function () {
917                    return Feed.init();
918                }, options.update_period);
919            }
920        })
921    };
922
923})(jQuery);

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.