HomeAccounting

Форк
0
2826 строк · 91.1 Кб
1
(function(w) {
2
  if (w.fastXDM) return;
3

4
  var handlers  = {};
5
  var onEnvLoad = [];
6
  var env       = {};
7

8
  // Key generation
9
  function genKey() {
10
    var key = '';
11
    for (var i = 0; i < 5; i++) {
12
      key += Math.ceil(Math.random() * 15).toString(16);
13
    }
14
    return key;
15
  }
16

17
  function waitFor(obj, prop, func, self,  count) {
18
    if (obj[prop]) {
19
      func.apply(self);
20
    } else {
21
      count = count || 0;
22
      if (count < 1000) {
23
        setTimeout(function() {
24
          waitFor(obj, prop, func, self, count + 1);
25
        }, 0);
26
      }
27
    }
28
  }
29

30
  function attachScript(url) {
31
    setTimeout(function() {
32
      var newScript  = document.createElement('script');
33
      newScript.type = 'text/javascript';
34
      newScript.src  = url || w.fastXDM.helperUrl;
35
      waitFor(document, 'body', function() {
36
        document.getElementsByTagName('HEAD')[0].appendChild(newScript);
37
      });
38
    }, 0);
39
  }
40

41
  function walkVar(value, clean) {
42
    var newValue;
43

44
    switch (typeof value) {
45
      case 'string':
46
        if (clean) {
47
          newValue = value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
48
        } else {
49
          newValue = value.replace(/&#039;/g, '\'').replace(/&quot;/g, '"').replace(/&gt;/g, '>').replace(/&lt;/g, '<').replace(/&amp;/g, '&');
50
        }
51
        break;
52
      case 'object':
53
        if (Object.prototype.toString.apply(value) === '[object Array]') {
54
          newValue = [];
55
          for (var i = 0, len = value.length; i < len; i++) {
56
            newValue[i] = walkVar(value[i], clean);
57
          }
58
        } else {
59
          newValue = {};
60
          for (var k in value) {
61
            if (Object.hasOwnProperty.call(value, k)) {
62
              newValue[k] = walkVar(value[k], clean);
63
            }
64
          }
65
        }
66
        break;
67
      default:
68
        newValue = value;
69
        break;
70
    }
71

72
    return newValue;
73
  }
74

75
  // Env functions
76
  function getEnv(callback, self) {
77
    if (env.loaded) {
78
      callback.apply(self, [env]);
79
    } else {
80
      onEnvLoad.push([self, callback]);
81
    }
82
  }
83

84
  function envLoaded() {
85
    env.loaded = true;
86

87
    for (var i = 0, len = onEnvLoad.length; i < len; i++) {
88
      onEnvLoad[i][1].apply(onEnvLoad[i][0], [env]);
89
    }
90
  }
91

92
  function applyMethod(strData, self) {
93
    getEnv(function(env) {
94
      var data = env.json.parse(strData);
95
      if (data[0]) {
96
        if (!data[1]) data[1] = [];
97

98
        for (var i = 0, len = data[1].length; i < len; i++) {
99
          if (data[1][i] && data[1][i]._func) {
100
            var funcNum = data[1][i]._func;
101
            data[1][i] = function() {
102
              var args = Array.prototype.slice.call(arguments);
103
              args.unshift('_func' + funcNum);
104
              self.callMethod.apply(self, args);
105
            }
106
          } else if (self.options.safe) {
107
            data[1][i] = walkVar(data[1][i], true);
108
          }
109
        }
110

111
        setTimeout(function() {
112
          if (!self.methods[data[0]]) {
113
            throw Error('fastXDM: Method ' + data[0] + ' is undefined');
114
          }
115
          self.methods[data[0]].apply(self, data[1]);
116
        }, 0);
117
      }
118
    });
119
  }
120

121
  function extend(obj1, obj2) {
122
    for (var i in obj2) {
123
      if (obj1[i] && typeof(obj1[i]) === 'object') {
124
        extend(obj1[i], obj2[i])
125
      } else {
126
        obj1[i] = obj2[i];
127
      }
128
    }
129
  }
130

131
  // XDM object
132
  w.fastXDM = {
133
    _id: 0,
134
    helperUrl: 'https://vk.com/js/api/xdmHelper.js',
135

136
    Server: function(methods, filter, options) {
137
      this.methods   = methods || {};
138
      this.filter    = filter;
139
      this.options   = options || {};
140
      this.id        = w.fastXDM._id++;
141
      this.key       = genKey();
142
      this.frameName = 'fXD' + this.key;
143
      this.server    = true;
144

145
      this.methods['%init%'] = this.methods.__fxdm_i = function() {
146
        w.fastXDM.run(this.id);
147
        if (this.methods.onInit) {
148
          this.methods.onInit();
149
        }
150
      };
151

152
      handlers[this.key] = [applyMethod, this];
153
    },
154

155
    Client: function(methods, options) {
156
      this.methods = methods || {};
157
      this.options = options || {};
158
      this.id      = w.fastXDM._id++;
159
      this.client  = true;
160

161
      w.fastXDM.run(this.id);
162

163
      if (window.name.indexOf('fXD') === 0) {
164
        this.key = window.name.substr(3);
165
      } else {
166
        throw Error('Wrong window.name property.');
167
      }
168

169
      this.caller = window.parent;
170

171
      handlers[this.key] = [applyMethod, this];
172

173
      w.fastXDM.on('helper', function() {
174
        w.fastXDM.onClientStart(this);
175
      }, this);
176

177
      getEnv(function(env) {
178
        env.send(this, env.json.stringify(['%init%']));
179

180
        var methods = this.methods;
181
        setTimeout(function() {
182
          if (methods.onInit) {
183
            methods.onInit();
184
          }
185
        }, 0);
186
      }, this);
187
    },
188

189
    onMessage: function(e) {
190
      var data = e.data;
191
      if (!data) {
192
        return false;
193
      }
194
      if (typeof data !== 'string' && !(data instanceof String)) {
195
        return false;
196
      }
197

198
      var key = data.substr(0, 5);
199
      if (handlers[key]) {
200
        var self = handlers[key][1];
201
        if (self && (!self.filter || self.filter(e.origin))) {
202
          handlers[key][0](data.substr(6), self);
203
        }
204
      }
205
    },
206

207
    setJSON: function(json) {
208
      env.json = json;
209
    },
210

211
    getJSON: function(callback) {
212
      if (!callback) {
213
        return env.json;
214
      }
215

216
      getEnv(function(env) {
217
        callback(env.json);
218
      });
219
    },
220

221
    setEnv: function(exEnv) {
222
      for (var i in exEnv) {
223
        env[i] = exEnv[i];
224
      }
225

226
      envLoaded();
227
    },
228

229
    _q: {},
230

231
    on: function(key, act, self) {
232
      if (!this._q[key]) this._q[key] = [];
233

234
      if (this._q[key] == -1) {
235
        act.apply(self);
236
      } else {
237
        this._q[key].push([act, self]);
238
      }
239
    },
240

241
    run: function(key) {
242
      var len = (this._q[key] || []).length;
243
      for (var i = 0; i < len; i++) {
244
        this._q[key][i][0].apply(this._q[key][i][1]);
245
      }
246

247
      this._q[key] = -1;
248
    },
249

250
    waitFor: waitFor
251
  }
252

253
  w.fastXDM.Server.prototype.start = function(obj, count) {
254
    if (obj.contentWindow) {
255
      this.caller = obj.contentWindow;
256
      this.frame  = obj;
257

258
      w.fastXDM.on('helper', function() {
259
        w.fastXDM.onServerStart(this);
260
      }, this);
261
    } else { // Opera old versions
262
      var self = this;
263
      count = count || 0;
264
      if (count < 50) {
265
        setTimeout(function() {
266
          self.start.apply(self, [obj, count + 1]);
267
        }, 100);
268
      }
269
    }
270
  }
271

272
  w.fastXDM.Server.prototype.destroy = function() {
273
    delete handlers[this.key];
274
  }
275

276
  w.fastXDM.Server.prototype.append = function(obj, options, attrs) {
277
    var div       = document.createElement('DIV');
278
    div.innerHTML = '<iframe name="' + this.frameName + '" ' + (attrs || '') + '></iframe>';
279
    var frame     = div.firstChild;
280
    var self      = this;
281

282
    setTimeout(function() {
283
      frame.frameBorder = '0';
284
      if (options) extend(frame, options);
285
      obj.insertBefore(frame, obj.firstChild);
286
      self.start(frame);
287
    }, 0);
288

289
    return frame;
290
  }
291

292
  w.fastXDM.Client.prototype.callMethod = w.fastXDM.Server.prototype.callMethod = function() {
293
    var args   = Array.prototype.slice.call(arguments);
294
    var method = args.shift();
295

296
    for (var i = 0, len = args.length; i < len; i++) {
297
      if (typeof(args[i]) === 'function') {
298
        this.funcsCount = (this.funcsCount || 0) + 1;
299
        var func        = args[i];
300
        var funcName    = '_func' + this.funcsCount;
301

302
        this.methods[funcName] = function() {
303
          func.apply(this, arguments);
304
          delete this.methods[funcName];
305
        }
306

307
        args[i] = {_func: this.funcsCount};
308
      } else if (this.options.safe) {
309
        args[i] = walkVar(args[i], false);
310
      }
311
    }
312

313
    waitFor(this, 'caller', function() {
314
      w.fastXDM.on(this.id, function() {
315
        getEnv(function(env) {
316
          env.send(this, env.json.stringify([method, args]));
317
        }, this);
318
      }, this);
319
    }, this);
320
  }
321

322
  if (w.JSON && typeof(w.JSON) === 'object' && w.JSON.parse && w.JSON.stringify && w.JSON.stringify({a:[1,2,3]}).replace(/ /g, '') === '{"a":[1,2,3]}') {
323
    env.json = {parse: w.JSON.parse, stringify: w.JSON.stringify};
324
  } else {
325
    w.fastXDM._needJSON = true;
326
  }
327

328
  // PostMessage cover
329
  if (w.postMessage) {
330
    env.protocol = 'p';
331
    env.send = function(xdm, strData) {
332
      var win = (xdm.frame ? xdm.frame.contentWindow : xdm.caller);
333
      if (win) {
334
        try {
335
          win.postMessage(xdm.key + ':' + strData, "*");
336
        } catch(e) {
337
          window.postMessage.call(win, xdm.key + ':' + strData, "*");
338
        }
339
      }
340
    }
341

342
    if (w.addEventListener) {
343
      w.addEventListener("message", w.fastXDM.onMessage, false);
344
    } else {
345
      w.attachEvent("onmessage", w.fastXDM.onMessage);
346
    }
347

348
    if (w.fastXDM._needJSON) {
349
      w.fastXDM._onlyJSON = true;
350
      attachScript();
351
    } else {
352
      envLoaded();
353
    }
354
  } else {
355
    attachScript();
356
  }
357
})(window);
358

359
if (!window.VK) window.VK = {};
360

361
/*
362
 * Based on JavaScript implementation of the RSA Data Security, Inc. MD5 Message
363
 * Copyright (C) Paul Johnston 1999 - 2009
364
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
365
 * Distributed under the BSD License
366
 */
367
if(!VK.MD5){VK.MD5=function(n){var j=function(o,r){var q=(o&65535)+(r&65535),p=(o>>16)+(r>>16)+(q>>16);return(p<<16)|(q&65535)},g=function(o,p){return(o<<p)|(o>>>(32-p))},k=function(w,r,p,o,v,u){return j(g(j(j(r,w),j(o,u)),v),p)},a=function(q,p,w,v,o,u,r){return k((p&w)|((~p)&v),q,p,o,u,r)},h=function(q,p,w,v,o,u,r){return k((p&v)|(w&(~v)),q,p,o,u,r)},c=function(q,p,w,v,o,u,r){return k(p^w^v,q,p,o,u,r)},m=function(q,p,w,v,o,u,r){return k(w^(p|(~v)),q,p,o,u,r)},b=function(A,u){var z=1732584193,y=-271733879,w=-1732584194,v=271733878,r,q,p,o;A[u>>5]|=128<<((u)%32);A[(((u+64)>>>9)<<4)+14]=u;for(var t=0,s=A.length;t<s;t+=16){r=z;q=y;p=w;o=v;z=a(z,y,w,v,A[t+0],7,-680876936);v=a(v,z,y,w,A[t+1],12,-389564586);w=a(w,v,z,y,A[t+2],17,606105819);y=a(y,w,v,z,A[t+3],22,-1044525330);z=a(z,y,w,v,A[t+4],7,-176418897);v=a(v,z,y,w,A[t+5],12,1200080426);w=a(w,v,z,y,A[t+6],17,-1473231341);y=a(y,w,v,z,A[t+7],22,-45705983);z=a(z,y,w,v,A[t+8],7,1770035416);v=a(v,z,y,w,A[t+9],12,-1958414417);w=a(w,v,z,y,A[t+10],17,-42063);y=a(y,w,v,z,A[t+11],22,-1990404162);z=a(z,y,w,v,A[t+12],7,1804603682);v=a(v,z,y,w,A[t+13],12,-40341101);w=a(w,v,z,y,A[t+14],17,-1502002290);y=a(y,w,v,z,A[t+15],22,1236535329);z=h(z,y,w,v,A[t+1],5,-165796510);v=h(v,z,y,w,A[t+6],9,-1069501632);w=h(w,v,z,y,A[t+11],14,643717713);y=h(y,w,v,z,A[t+0],20,-373897302);z=h(z,y,w,v,A[t+5],5,-701558691);v=h(v,z,y,w,A[t+10],9,38016083);w=h(w,v,z,y,A[t+15],14,-660478335);y=h(y,w,v,z,A[t+4],20,-405537848);z=h(z,y,w,v,A[t+9],5,568446438);v=h(v,z,y,w,A[t+14],9,-1019803690);w=h(w,v,z,y,A[t+3],14,-187363961);y=h(y,w,v,z,A[t+8],20,1163531501);z=h(z,y,w,v,A[t+13],5,-1444681467);v=h(v,z,y,w,A[t+2],9,-51403784);w=h(w,v,z,y,A[t+7],14,1735328473);y=h(y,w,v,z,A[t+12],20,-1926607734);z=c(z,y,w,v,A[t+5],4,-378558);v=c(v,z,y,w,A[t+8],11,-2022574463);w=c(w,v,z,y,A[t+11],16,1839030562);y=c(y,w,v,z,A[t+14],23,-35309556);z=c(z,y,w,v,A[t+1],4,-1530992060);v=c(v,z,y,w,A[t+4],11,1272893353);w=c(w,v,z,y,A[t+7],16,-155497632);y=c(y,w,v,z,A[t+10],23,-1094730640);z=c(z,y,w,v,A[t+13],4,681279174);v=c(v,z,y,w,A[t+0],11,-358537222);w=c(w,v,z,y,A[t+3],16,-722521979);y=c(y,w,v,z,A[t+6],23,76029189);z=c(z,y,w,v,A[t+9],4,-640364487);v=c(v,z,y,w,A[t+12],11,-421815835);w=c(w,v,z,y,A[t+15],16,530742520);y=c(y,w,v,z,A[t+2],23,-995338651);z=m(z,y,w,v,A[t+0],6,-198630844);v=m(v,z,y,w,A[t+7],10,1126891415);w=m(w,v,z,y,A[t+14],15,-1416354905);y=m(y,w,v,z,A[t+5],21,-57434055);z=m(z,y,w,v,A[t+12],6,1700485571);v=m(v,z,y,w,A[t+3],10,-1894986606);w=m(w,v,z,y,A[t+10],15,-1051523);y=m(y,w,v,z,A[t+1],21,-2054922799);z=m(z,y,w,v,A[t+8],6,1873313359);v=m(v,z,y,w,A[t+15],10,-30611744);w=m(w,v,z,y,A[t+6],15,-1560198380);y=m(y,w,v,z,A[t+13],21,1309151649);z=m(z,y,w,v,A[t+4],6,-145523070);v=m(v,z,y,w,A[t+11],10,-1120210379);w=m(w,v,z,y,A[t+2],15,718787259);y=m(y,w,v,z,A[t+9],21,-343485551);z=j(z,r);y=j(y,q);w=j(w,p);v=j(v,o)}return[z,y,w,v]},f=function(r){var q="",s=-1,p=r.length,o,t;while(++s<p){o=r.charCodeAt(s);t=s+1<p?r.charCodeAt(s+1):0;if(55296<=o&&o<=56319&&56320<=t&&t<=57343){o=65536+((o&1023)<<10)+(t&1023);s++}if(o<=127){q+=String.fromCharCode(o)}else{if(o<=2047){q+=String.fromCharCode(192|((o>>>6)&31),128|(o&63))}else{if(o<=65535){q+=String.fromCharCode(224|((o>>>12)&15),128|((o>>>6)&63),128|(o&63))}else{if(o<=2097151){q+=String.fromCharCode(240|((o>>>18)&7),128|((o>>>12)&63),128|((o>>>6)&63),128|(o&63))}}}}}return q},e=function(p){var o=Array(p.length>>2),r,q;for(r=0,q=o.length;r<q;r++){o[r]=0}for(r=0,q=p.length*8;r<q;r+=8){o[r>>5]|=(p.charCodeAt(r/8)&255)<<(r%32)}return o},l=function(p){var o="";for(var r=0,q=p.length*32;r<q;r+=8){o+=String.fromCharCode((p[r>>5]>>>(r%32))&255)}return o},d=function(o){return l(b(e(o),o.length*8))},i=function(q){var t="0123456789abcdef",p="",o;for(var s=0,r=q.length;s<r;s++){o=q.charCodeAt(s);p+=t.charAt((o>>>4)&15)+t.charAt(o&15)}return p};return i(d(f(n)))}}
368

369
/*
370
 * VKontakte Open API JavaScript library
371
 * http://vk.com/
372
 */
373

374
VK.extend = function(target, source, overwrite) {
375
  for (var key in source) {
376
    if (overwrite || typeof target[key] === 'undefined') {
377
      target[key] = source[key];
378
    }
379
  }
380
  return target;
381
};
382

383
VK._protocol = 'https:';
384

385
if (!VK.xdConnectionCallbacks) {
386

387
  VK.extend(VK, {
388
    version: 1,
389
    _apiId: null,
390
    _session: null,
391
    _userStatus: 'unknown',
392
    _domain: {
393
      main: 'https://oauth.vk.com/',
394
      api: 'https://api.vk.com/'
395
    },
396
    _path: {
397
      login: 'authorize',
398
      proxy: 'fxdm_oauth_proxy.html'
399
    },
400
    _rootId: 'vk_api_transport',
401
    _nameTransportPath: '',
402
    xdReady: false,
403
    access: {
404
      FRIENDS:   0x2,
405
      PHOTOS:    0x4,
406
      AUDIO:     0x8,
407
      VIDEO:     0x10,
408
      MATCHES:   0x20,
409
      QUESTIONS: 0x40,
410
      WIKI:      0x80
411
    }
412
  });
413

414
  VK.init = function(options) {
415
    var body, root;
416

417
    VK._apiId = null;
418
    if (!options.apiId) {
419
      throw Error('VK.init() called without an apiId');
420
    }
421
    VK._apiId = options.apiId;
422

423
    if (options.onlyWidgets) return true;
424

425
    if (options.nameTransportPath && options.nameTransportPath !== '') {
426
      VK._nameTransportPath = options.nameTransportPath;
427
    }
428

429
    root = document.getElementById(VK._rootId);
430
    if (!root) {
431
      root = document.createElement('div');
432
      root.id = VK._rootId;
433
      body = document.getElementsByTagName('body')[0];
434
      body.insertBefore(root, body.childNodes[0]);
435
    }
436
    root.style.position = 'absolute';
437
    root.style.top = '-10000px';
438

439
    var session = VK.Cookie.load();
440
    if (session) {
441
      VK.Auth._loadState = 'loaded';
442
      VK.Auth.setSession(session, session ? 'connected' : 'unknown');
443
    }
444
  };
445

446
  if (!VK.Cookie) {
447
    VK.Cookie = {
448
      _domain: null,
449
      load: function() {
450
        var cookie = document.cookie.match('\\bvk_app_' + VK._apiId + '=([^;]*)\\b')
451
        var session;
452

453
        if (cookie) {
454
          session = this.decode(cookie[1]);
455
          if (session.secret != 'oauth') {
456
            return false;
457
          }
458
          session.expire = parseInt(session.expire, 10);
459
          VK.Cookie._domain = '.' + window.location.hostname;//session.base_domain;
460
        }
461

462
        return session;
463
      },
464
      setRaw: function(val, ts, domain, time) {
465
        var rawCookie;
466
        rawCookie = 'vk_app_' + VK._apiId + '=' + val + '';
467
        var exp = time ? (new Date().getTime() + time * 1000) : ts * 1000;
468
        rawCookie += (val && ts === 0 ? '' : '; expires=' + new Date(exp).toGMTString());
469
        rawCookie += '; path=/';
470
        rawCookie += (domain ? '; domain=.' + domain : '');
471
        document.cookie = rawCookie;
472

473
        this._domain = domain;
474
      },
475
      set: function(session, resp) {
476
        if (session) {
477
          this.setRaw(this.encode(session), session.expire, window.location.hostname, (resp || {}).time);
478
        } else {
479
          this.clear();
480
        }
481
      },
482
      clear: function() {
483
        this.setRaw('', 0, this._domain, 0);
484
      },
485
      encode: function(params) {
486
        var
487
            pairs = [],
488
            key;
489

490
        for (key in params) {
491
          if (key != 'user') pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(params[key]));
492
        }
493
        pairs.sort();
494

495
        return pairs.join('&');
496
      },
497
      decode: function(str) {
498
        var
499
            params = {},
500
            parts = str.split('&'),
501
            i,
502
            pair;
503

504
        for (i=0; i < parts.length; i++) {
505
          pair = parts[i].split('=', 2);
506
          if (pair && pair[0]) {
507
            params[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
508
          }
509
        }
510

511
        return params;
512
      }
513
    };
514
  }
515

516
  function obj2qs(obj) {
517
    if (!obj) return '';
518
    var qs = [];
519
    for (var k in obj) {
520
      if (obj.hasOwnProperty(k)) {
521
        qs.push(encodeURIComponent(k) + '=' + encodeURIComponent(obj[k].toString() || ''));
522
      }
523
    }
524
    return qs.length ? '?' + qs.join('&') : '';
525
  }
526

527
  if (!VK.Api) {
528
    VK.Api = {
529
      _headId: null,
530
      _callbacks: {},
531

532
      ie6_7: function() {
533
        if (!VK.Api.ieTested) {
534
          VK.Api.isIE6_7 = navigator.userAgent.match(/MSIE [6|7]/i);
535
          VK.Api.ieTested = true;
536
        }
537
        return VK.Api.isIE6_7;
538
      },
539

540
      supportCORS: function() {
541
        var xhr = new XMLHttpRequest();
542
        if ("withCredentials" in xhr) {
543
          return true;
544
        }
545

546
        if (typeof XDomainRequest != "undefined") {
547
          return true;
548
        }
549

550
        return false;
551
      },
552

553
      makeRequest: function(url, cb) {
554
        var xhr = VK.Api.createRequest('GET', url);
555
        if (!xhr) {
556
          return false;
557
        }
558

559
        xhr.onload = function() {
560
          var text = xhr.responseText;
561
          if (xhr.status === 200) {
562
            cb(text);
563
          } else {
564
            try {
565
              console.error('Open api access error', xhr.response);
566
            } catch(e) {
567
              //nop
568
            }
569
          }
570
        };
571

572
        xhr.onerror = function() {
573
          try {
574
            console.error('Open api access error');
575
          } catch(e) {
576
            //nop
577
          }
578
        };
579

580
        xhr.send();
581
        return true;
582
      },
583

584
      createRequest: function(method, url) {
585
        var xhr = new XMLHttpRequest();
586

587
        if ("withCredentials" in xhr) {
588
          // XHR for Chrome/Firefox/Opera/Safari.
589
          xhr.open(method, url, true);
590
          xhr.withCredentials = true;
591
        } else if (typeof XDomainRequest != "undefined") {
592
          // XDomainRequest for IE.
593
          xhr = new XDomainRequest();
594
          xhr.open(method, url);
595
          xhr.withCredentials = true;
596
        } else {
597
          // CORS not supported.
598
          xhr = null;
599
        }
600

601
        return xhr;
602
      },
603

604
      attachScript: function(url) {
605
        if (!VK.Api._headId) VK.Api._headId = document.getElementsByTagName("head")[0];
606
        var newScript = document.createElement('script');
607
        newScript.type = 'text/javascript';
608
        newScript.setAttribute('encoding', 'UTF-8');
609
        newScript.src = url;
610
        VK.Api._headId.appendChild(newScript);
611
      },
612

613
      checkMethod: function(method, params, cb, queryTry) {
614
        var m = method.toLowerCase();
615

616
        if (m === 'wall.post') {
617
          var validAttacheRegexp = /(^https?:\/\/)|(^(poll|album|photo|video|doc|audio|page|note)-?\d+_-?\d+)$/,
618
              validAttachments = [],
619
              methodAccess,
620
              queryParams,
621
              query,
622
              timer;
623

624
          if (!params.v) {
625
            params.v = '3.0';
626
          }
627

628
          params.attachments = params.attachments || params.attachment || [];
629
          if (typeof params.attachments === 'string') {
630
            params.attachments = params.attachments.split(',')
631
          }
632

633
          for (var i = 0; i < params.attachments.length; i++) {
634
            var attach = params.attachments[i].trim();
635
            if (validAttacheRegexp.test(attach)) {
636
              validAttachments.push(attach);
637
            }
638
          }
639

640
          params.attachments = validAttachments.length ? validAttachments : '';
641
          methodAccess = '_' + (Math.random()).toString(16).substr(2);
642
          queryParams = {
643
            act: 'wall_post_box',
644
            method: m,
645
            widget: 4,
646
            aid: parseInt(VK._apiId, 10),
647
            text: params.message || '',
648
            method_access: methodAccess
649
          };
650

651
          queryParams = VK.extend(queryParams, params);
652
          queryParams.owner_id = parseInt(params.owner_id || 0, 10);
653
          queryParams.publish_date = params.publish_date || '';
654
          query = VK._protocol + '//vk.com/al_apps.php';
655
          query += obj2qs(queryParams);
656

657
          VK.UI.popup({
658
            url: query,
659
            width: 560,
660
            height: 304
661
          });
662

663
          timer = setInterval(function() {
664
            if (VK.UI.active.closed) {
665
              clearInterval(timer);
666
              params.method_access = methodAccess;
667
              VK.Api.call(method, params, cb, queryTry);
668
            }
669
          }, 500);
670
          return false;
671
        }
672

673
        if (m == 'messages.allowmessagesfromgroup') {
674
          methodAccess = '_' + (Math.random()).toString(16).substr(2);
675
          query = VK._protocol + '//vk.com/widget_allow_messages_from_community.php?act=allow_box&group_id=' + parseInt(params.group_id, 10) + '&app_id=' + parseInt(VK._apiId, 10) + '&method_access=' + methodAccess;
676

677
          VK.UI.popup({
678
            url: query,
679
            width: 560,
680
            height: 304
681
          });
682

683
          timer = setInterval(function () {
684
            if (VK.UI.active.closed) {
685
              clearInterval(timer);
686
              params.method_access = methodAccess;
687
              VK.Api.call(method, params, cb, queryTry);
688
            }
689
          }, 500);
690

691
          return false;
692
        }
693

694
        return true;
695
      },
696

697
      call: function(method, params, cb, queryTry) {
698
        var
699
            query = params || {},
700
            qs,
701
            responseCb;
702

703
        if (typeof query != 'object' || typeof cb != 'function') {
704
          return false;
705
        }
706
        if (!params.method_access && !params.method_force && !VK.Api.checkMethod(method, params, cb, queryTry)) {
707
          return;
708
        }
709

710
        if (!queryTry) queryTry = 0;
711

712
        if (VK.Auth._loadState != 'loaded') {
713
          var authFunc = function(result) {
714
            if (result && result.session) {
715
              VK.Observer.unsubscribe('auth.loginStatus', authFunc);
716
              VK.Api.call(method, params, cb);
717
            }
718
          };
719
          VK.Observer.subscribe('auth.loginStatus', authFunc);
720
          VK.Auth.getLoginStatus();
721
          return;
722
        }
723

724
        if (VK.Api.queryLength(query) < 1500 && !VK.Api.ie6_7()) {
725
          var useXDM = false;
726
          var rnd = parseInt(Math.random() * 10000000, 10);
727
          while (VK.Api._callbacks[rnd]) {
728
            rnd = parseInt(Math.random() * 10000000, 10)
729
          }
730
          query.callback = 'VK.Api._callbacks['+rnd+']';
731
        } else {
732
          var useXDM = true;
733
        }
734

735
        if (VK._session && VK._session.sid) {
736
          query.access_token = VK._session.sid;
737
        }
738

739
        qs = VK.Cookie.encode(query);
740

741
        responseCb = function(response) {
742
          if (response.error && (response.error.error_code == 3 || response.error.error_code == 4 || response.error.error_code == 5)) {
743
            if (queryTry > 3) return false;
744
            var repeatCall = function(resp) {
745
              VK.Observer.unsubscribe('auth.sessionChange', repeatCall);
746
              delete params.access_token;
747
              if (resp.session) VK.Api.call(method, params, cb, queryTry + 1);
748
            }
749
            VK.Observer.subscribe('auth.sessionChange', repeatCall);
750
            VK.Auth.getLoginStatus();
751
          } else {
752
            cb(response);
753
          }
754
          if (!useXDM) delete VK.Api._callbacks[rnd];
755
        };
756

757
        if (useXDM) {
758
          if (VK.xdReady) {
759
            VK.XDM.remote.callMethod('apiCall', method, qs, responseCb);
760
          } else {
761
            VK.Observer.subscribe('xdm.init', function() {
762
              VK.XDM.remote.callMethod('apiCall', method, qs, responseCb);
763
            });
764
            VK.XDM.init();
765
          }
766
        } else {
767
          VK.Api._callbacks[rnd] = responseCb;
768
          VK.Api.attachScript(VK._domain.api + 'method/' + method +'?' + qs);
769
        }
770
      },
771

772
      queryLength: function(query) {
773
        var len = 100, i; // sid + sig
774
        for (i in query) {
775
          len += i.length + encodeURIComponent(query[i]).length + 1;
776
        }
777
        return len;
778
      }
779
    };
780

781
// Alias
782
    VK.api = function(method, params, cb) {VK.Api.call(method, params, cb);}
783
  };
784

785
  if (!VK.Auth) {
786
    VK.Auth = {
787
      popup: null,
788
      lsCb: {},
789

790
      setSession: function(session, status, settings, resp) {
791
        var
792
            login = !VK._session && session,
793
            logout = VK._session && !session,
794
            both = VK._session && session && VK._session.mid != session.mid,
795
            sessionChange = login || logout || (VK._session && session && VK._session.sid != session.sid),
796
            statusChange = status != VK._userStatus,
797
            response = {
798
              'session': session,
799
              'status': status,
800
              'settings': settings
801
            };
802

803
        VK._session = session;
804

805
        VK._userStatus = status;
806

807
        VK.Cookie.set(session, resp);
808

809
        if (sessionChange || statusChange || both) {
810
          setTimeout(function() {
811
            if (statusChange) {
812
              VK.Observer.publish('auth.statusChange', response);
813
            }
814

815
            if (logout || both) {
816
              VK.Observer.publish('auth.logout', response);
817
            }
818

819
            if (login || both) {
820
              VK.Observer.publish('auth.login', response);
821
            }
822

823
            if (sessionChange) {
824
              VK.Observer.publish('auth.sessionChange', response);
825
            }
826
          }, 0);
827
        }
828

829
        return response;
830
      },
831

832
      // Public VK.Auth methods
833
      login: function(cb, settings) {
834
        if (!VK._apiId) {
835
          return false;
836
        }
837

838
        var url = VK._domain.main + VK._path.login + '?client_id='+VK._apiId+'&display=popup&redirect_uri=close.html&response_type=token';
839
        if (settings && parseInt(settings, 10) > 0) {
840
          url += '&scope=' + settings;
841
        }
842

843
        VK.Observer.unsubscribe('auth.onLogin');
844
        VK.Observer.subscribe('auth.onLogin', cb);
845

846
        VK.UI.popup({
847
          width: 665,
848
          height: 370,
849
          url: url
850
        });
851

852
        var authCallback = function() {
853
          VK.Auth.getLoginStatus(function(resp) {
854
            VK.Observer.publish('auth.onLogin', resp);
855
            VK.Observer.unsubscribe('auth.onLogin');
856
          }, true);
857
        }
858

859
        VK.UI.popupOpened = true;
860
        var popupCheck = function() {
861
          if (!VK.UI.popupOpened) {
862
            return false;
863
          }
864

865
          try {
866
            if (!VK.UI.active.top || VK.UI.active.closed) {
867
              VK.UI.popupOpened = false;
868
              authCallback();
869
              return true;
870
            }
871
          } catch(e) {
872
            VK.UI.popupOpened = false;
873
            authCallback();
874
            return true;
875
          }
876
          setTimeout(popupCheck, 100);
877
        };
878

879
        setTimeout(popupCheck, 100);
880
      },
881

882
      // Logout user from app, vk.com & login.vk.com
883
      logout: function(cb) {
884
        VK.Auth.revokeGrants(cb);
885
      },
886

887
      revokeGrants: function(cb) {
888
        var onLogout = function(resp) {
889
          VK.Observer.unsubscribe('auth.statusChange', onLogout);
890
          if (cb) {
891
            cb(resp);
892
          }
893
        }
894

895
        VK.Observer.subscribe('auth.statusChange', onLogout);
896
        if (VK._session && VK._session.sid) {
897
          var url = 'https://login.vk.com/?act=openapi&oauth=1&aid=' + parseInt(VK._apiId, 10) + '&location=' + encodeURIComponent(window.location.hostname) + '&do_logout=1&token=' + VK._session.sid;
898
          if (VK.Api.supportCORS()) {
899
            var logoutCallback = function() {
900
              VK.Auth.setSession(null, 'unknown');
901
            };
902

903
            VK.Api.makeRequest(url + '&new=1', logoutCallback);
904
          } else {
905
            VK.Api.attachScript(url);
906
          }
907
        }
908

909
        VK.Cookie.clear();
910
      },
911

912
      // Get current login status from session (sync) (not use on load time)
913
      getSession: function() {
914
        return VK._session;
915
      },
916

917
      // Get current login status from vk.com (async)
918
      getLoginStatus: function(cb, force) {
919
        if (!VK._apiId) {
920
          return;
921
        }
922

923
        if (cb) {
924
          if (!force && VK.Auth._loadState == 'loaded') {
925
            cb({status: VK._userStatus, session: VK._session});
926
            return;
927
          } else {
928
            VK.Observer.subscribe('auth.loginStatus', cb);
929
          }
930
        }
931

932
        if (!force && VK.Auth._loadState == 'loading') {
933
          return;
934
        }
935

936
        VK.Auth._loadState = 'loading';
937

938
        var url = 'https://login.vk.com/?act=openapi&oauth=1&aid=' + parseInt(VK._apiId, 10) + '&location=' + encodeURIComponent(window.location.hostname);
939
        if (VK.Api.supportCORS()) {
940
          var loginCallback = function(response) {
941
            if (!this.JSON) {
942
              this.JSON = {};
943
            }
944

945
            if (typeof JSON.parse !== 'function') {
946
              //IE6 and IE7
947
              response = eval(response);
948
            } else {
949
              response = JSON.parse(response);
950
            }
951

952
            VK.Auth._loadState = 'loaded';
953
            if (response && response.auth) {
954
              var session = {
955
                mid: response.user.id,
956
                sid: response.access_token,
957
                sig: response.sig,
958
                secret: response.secret,
959
                expire: response.expire
960
              };
961

962
              if (force) {
963
                session.user = response.user;
964
              }
965

966
              var status = 'connected';
967
            } else {
968
              var session = null;
969
              var status = response.user ? 'not_authorized' : 'unknown';
970
              VK.Cookie.clear();
971
            }
972

973
            VK.Auth.setSession(session, status, false, response);
974
            VK.Observer.publish('auth.loginStatus', {session: session, status: status});
975
            VK.Observer.unsubscribe('auth.loginStatus');
976
          };
977

978
          VK.Api.makeRequest(url + '&new=1', loginCallback);
979
        } else {
980
          var rnd = parseInt(Math.random() * 10000000, 10);
981
          while (VK.Auth.lsCb[rnd]) {
982
            rnd = parseInt(Math.random() * 10000000, 10);
983
          }
984

985
          VK.Auth.lsCb[rnd] = function(response) {
986
            delete VK.Auth.lsCb[rnd];
987
            VK.Auth._loadState = 'loaded';
988
            if (response && response.auth) {
989
              var session = {
990
                mid: response.user.id,
991
                sid: response.access_token,
992
                sig: response.sig,
993
                secret: response.secret,
994
                expire: response.expire
995
              };
996
              if (force) session.user = response.user;
997
              var status = 'connected';
998
            } else {
999
              var session = null;
1000
              var status = response.user ? 'not_authorized' : 'unknown';
1001
              VK.Cookie.clear();
1002
            }
1003
            VK.Auth.setSession(session, status, false, response);
1004
            VK.Observer.publish('auth.loginStatus', {session: session, status: status});
1005
            VK.Observer.unsubscribe('auth.loginStatus');
1006
          };
1007

1008
            // AttachScript here
1009
          VK.Api.attachScript(url+'&rnd='+rnd);
1010
        }
1011
      }
1012
    };
1013
  }
1014

1015
  if (!VK.App) {
1016
    VK.App = {
1017
      _appOpened: false,
1018

1019
      open: function (url, params) {
1020
        if (VK.App._appOpened || !VK._apiId) {
1021
          return;
1022
        }
1023

1024
        if (!VK._session) {
1025
          VK.Auth.login(function(resp) {
1026
            if (resp && resp.session) {
1027
              VK.App._openApp(url, params);
1028
            }
1029
          });
1030
        } else {
1031
          VK.App._openApp(url, params);
1032
        }
1033
      },
1034

1035
      _openApp: function (url, params) {
1036
        var src, box, request = [];
1037
        params = params || {};
1038

1039
        if (!url || !VK._apiId || VK.App._appOpened) {
1040
          return;
1041
        }
1042
        src = VK._protocol + '//vk.com/apps?act=open_external_app_openapi&aid=' + VK._apiId;
1043
        params['aid'] = VK._apiId;
1044

1045
        for (var arg in params) {
1046
          var val = '';
1047
          if (!params.hasOwnProperty(arg)) {
1048
            continue;
1049
          }
1050
          if (params[arg] !== undefined) {
1051
            val = encodeURIComponent(params[arg]);
1052
          }
1053
          request.push(encodeURIComponent(arg) + '=' + val);
1054
        }
1055

1056
        src += '&url=' + url;
1057
        src += '&q=' + encodeURIComponent(request.join('&'));
1058

1059
        box = VK.Util.Box(src, {}, {
1060
          closeExternalApp: function() {
1061
            VK.Observer.publish('app.closed');
1062
            box.hide();
1063
            VK.App._appOpened = false;
1064
          },
1065
          externalAppDone: function (params) {
1066
            VK.Observer.publish('app.done', params);
1067
            box.hide();
1068
            VK.App._appOpened = false;
1069
          }
1070
        });
1071
        box.show();
1072
        VK.App._appOpened = true;
1073
      },
1074
    }
1075
  }
1076

1077
} else { // if VK.xdConnectionCallbacks
1078
  setTimeout(function() {
1079
    var callback;
1080
    while (callback = VK.xdConnectionCallbacks.pop()) {
1081
      callback();
1082
    }
1083
  }, 0);
1084
  if (VK.Widgets && !VK.Widgets._constructor) {
1085
    VK.Widgets = false;
1086
  }
1087
}
1088

1089
if (!VK.UI) {
1090
  VK.UI = {
1091
    active: null,
1092
    _buttons: [],
1093
    popup: function(options) {
1094
      var
1095
          screenX = typeof window.screenX != 'undefined' ? window.screenX : window.screenLeft,
1096
          screenY = typeof window.screenY != 'undefined' ? window.screenY : window.screenTop,
1097
          outerWidth = typeof window.outerWidth != 'undefined' ? window.outerWidth : document.body.clientWidth,
1098
          outerHeight = typeof window.outerHeight != 'undefined' ? window.outerHeight : (document.body.clientHeight - 22),
1099
          width = options.width,
1100
          height = options.height,
1101
          left = parseInt(screenX + ((outerWidth - width) / 2), 10),
1102
          top = parseInt(screenY + ((outerHeight - height) / 2.5), 10),
1103
          features = (
1104
              'width=' + width +
1105
              ',height=' + height +
1106
              ',left=' + left +
1107
              ',top=' + top
1108
          );
1109
      this.active = window.open(options.url, 'vk_openapi', features);
1110
    },
1111
    button: function(el, handler) {
1112
      var html = '';
1113

1114
      if (typeof el == 'string') {
1115
        el = document.getElementById(el);
1116
      }
1117

1118

1119
      this._buttons.push(el);
1120
      index = this._buttons.length - 1;
1121

1122
      html = (
1123
          '<table cellspacing="0" cellpadding="0" id="openapi_UI_' + index + '" onmouseover="VK.UI._change(1, ' + index + ');" onmouseout="VK.UI._change(0, ' + index + ');" onmousedown="VK.UI._change(2, ' + index + ');" onmouseup="VK.UI._change(1, ' + index + ');" style="cursor: pointer; border: 0px; font-family: tahoma, arial, verdana, sans-serif, Lucida Sans; font-size: 10px;"><tr style="vertical-align: middle">' +
1124
          '<td><div style="border: 1px solid #3b6798;border-radius: 2px 0px 0px 2px;-moz-border-radius: 2px 0px 0px 2px;-webkit-border-radius: 2px 0px 0px 2px;"><div style="border: 1px solid #5c82ab; border-top-color: #7e9cbc; background-color: #6D8DB1; color: #fff; text-shadow: 0px 1px #45688E; height: 15px; padding: 2px 4px 0px 6px;line-height: 13px;">&#1042;&#1086;&#1081;&#1090;&#1080;</div></div></td>' +
1125
          '<td><div style="background: url(' + VK._protocol + '//vk.com/images/btns.png) 0px -42px no-repeat; width: 21px; height: 21px"></div></td>' +
1126
          '<td><div style="border: 1px solid #3b6798;border-radius: 0px 2px 2px 0px;-moz-border-radius: 0px 2px 2px 0px;-webkit-border-radius: 0px 2px 2px 0px;"><div style="border: 1px solid #5c82ab; border-top-color: #7e9cbc; background-color: #6D8DB1; color: #fff; text-shadow: 0px 1px #45688E; height: 15px; padding: 2px 6px 0px 4px;line-height: 13px;">&#1050;&#1086;&#1085;&#1090;&#1072;&#1082;&#1090;&#1077;</div></div></td>' +
1127
          '</tr></table>'
1128
      );
1129
      el.innerHTML = html;
1130
      el.style.width = el.childNodes[0].offsetWidth + 'px';
1131
    },
1132
    _change: function(state, index) {
1133
      var row = document.getElementById('openapi_UI_' + index).rows[0];
1134
      var elems = [row.cells[0].firstChild.firstChild, row.cells[2].firstChild.firstChild];
1135
      for (var i = 0; i < 2; ++i) {
1136
        var elem = elems[i];
1137
        if (state === 0) {
1138
          elem.style.backgroundColor = '#6D8DB1';
1139
          elem.style.borderTopColor = '#7E9CBC';
1140
          elem.style.borderLeftColor = elem.style.borderRightColor = elem.style.borderBottomColor = '#5C82AB';
1141
        } else if (state == 1) {
1142
          elem.style.backgroundColor = '#7693B6';
1143
          elem.style.borderTopColor = '#88A4C4';
1144
          elem.style.borderLeftColor = elem.style.borderRightColor = elem.style.borderBottomColor = '#6088B4';
1145
        } else if (state == 2) {
1146
          elem.style.backgroundColor = '#6688AD';
1147
          elem.style.borderBottomColor = '#7495B8';
1148
          elem.style.borderLeftColor = elem.style.borderRightColor = elem.style.borderTopColor = '#51779F';
1149
        }
1150
      }
1151
      if (state === 0 || state == 2) {
1152
        row.cells[2].firstChild.style.backgroundPosition = '0px -42px';
1153
      } else if (state == 1) {
1154
        row.cells[2].firstChild.style.backgroundPosition = '0px -63px';
1155
      }
1156
    }
1157
  };
1158
}
1159

1160
if (!VK.XDM) {
1161
  VK.XDM = {
1162
    remote: null,
1163
    init: function() {
1164
      if (this.remote) return false;
1165
      var url = VK._domain.api + VK._path.proxy;
1166
      this.remote = new fastXDM.Server({
1167
        onInit: function() {
1168
          VK.xdReady = true;
1169
          VK.Observer.publish('xdm.init');
1170
        }
1171
      });
1172

1173
      this.remote.append(document.getElementById(VK._rootId), {
1174
        src: url
1175
      });
1176
    },
1177
    xdHandler: function(code) {
1178
      try {
1179
        eval('VK.' + code);
1180
      } catch(e) {}
1181
    }
1182
  };
1183
}
1184

1185
if (!VK.Observer) {
1186
  VK.Observer = {
1187
    _subscribers: function() {
1188
      if (!this._subscribersMap) {
1189
        this._subscribersMap = {};
1190
      }
1191
      return this._subscribersMap;
1192
    },
1193
    publish: function(eventName) {
1194
      var
1195
          args = Array.prototype.slice.call(arguments),
1196
          eventName = args.shift(),
1197
          subscribers = this._subscribers()[eventName],
1198
          i, j;
1199

1200
      if (!subscribers) return;
1201

1202
      for (i = 0, j = subscribers.length; i < j; i++) {
1203
        if (subscribers[i] != null) {
1204
          subscribers[i].apply(this, args);
1205
        }
1206
      }
1207
    },
1208
    subscribe: function(eventName, handler) {
1209
      var
1210
          subscribers = this._subscribers();
1211

1212
      if (typeof handler != 'function') return false;
1213

1214
      if (!subscribers[eventName]) {
1215
        subscribers[eventName] = [handler];
1216
      } else {
1217
        subscribers[eventName].push(handler);
1218
      }
1219
    },
1220
    unsubscribe: function(eventName, handler) {
1221
      var
1222
          subscribers = this._subscribers()[eventName],
1223
          i, j;
1224

1225
      if (!subscribers) return false;
1226
      if (typeof handler == 'function') {
1227
        for (i = 0, j = subscribers.length; i < j; i++) {
1228
          if (subscribers[i] == handler) {
1229
            subscribers[i] = null;
1230
          }
1231
        }
1232
      } else {
1233
        delete this._subscribers()[eventName];
1234
      }
1235
    }
1236
  };
1237
}
1238

1239
if (!VK.Widgets) {
1240
  VK.Widgets = {};
1241

1242
  VK.Widgets.count = 0;
1243
  VK.Widgets.RPC = {};
1244

1245
  VK.Widgets.showBoxUrl = function(domain, url) {
1246
    domain = (domain || VK._protocol + '//vk.com').replace(/\/?\s*$/, '');
1247
    url = url.replace(/^\s*\/?/, '');
1248
    return domain + '/' + url;
1249
  };
1250

1251
  VK.Widgets.loading = function(obj, enabled) {
1252
    obj.style.background = enabled ? 'url("' + VK._protocol + '//vk.com/images/upload.gif") center center no-repeat transparent' : 'none';
1253
  };
1254

1255
  VK.Widgets.Comments = function(objId, options, page) {
1256
    var pData = VK.Util.getPageData();
1257
    if (!VK._apiId) throw Error('VK not initialized. Please use VK.init');
1258
    options = options || {};
1259

1260
    var obj = document.getElementById(objId),
1261
      params = {
1262
        limit: options.limit || 10,
1263
        height: options.height || 0,
1264
        mini: options.mini === undefined ? 'auto' : options.mini,
1265
        norealtime: options.norealtime ? 1 : 0
1266
      }, mouseup = function() {
1267
        rpc.callMethod('mouseUp');
1268
        return false;
1269
      }, move = function(event) {
1270
        rpc.callMethod('mouseMove', {screenY: event.screenY});
1271
      }, iframe, rpc;
1272

1273
    if (options.browse) { // browse all comments
1274
      params.browse = 1;
1275
      params.replies = options.replies || 0;
1276
    } else { // page
1277
      var url = options.pageUrl || pData.url;
1278
      if (url.substr(0, 1) == '/') {
1279
        url = (location.protocol + '//' + location.host) + url;
1280
      }
1281
      VK.extend(params, {
1282
        page: page || 0,
1283
        status_publish: options.autoPublish === undefined ? 0 : options.autoPublish,
1284
        attach: options.attach === undefined ? '*' : (options.attach ? options.attach : ''),
1285
        url: url,
1286
        title: options.pageTitle || pData.title,
1287
        description: options.pageDescription || pData.description,
1288
        image: options.pageImage || pData.image
1289
      });
1290
    }
1291
    if (options.onChange) { // DEPRECATED
1292
      VK.Observer.subscribe('widgets.comments.new_comment', options.onChange);
1293
      VK.Observer.subscribe('widgets.comments.delete_comment', options.onChange);
1294
    }
1295

1296
    return VK.Widgets._constructor('widget_comments.php', objId, options, params, {
1297
      showBox: function(url, props) {
1298
        var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1299
          proxy: function() {
1300
            rpc.callMethod.apply(rpc, arguments);
1301
          }
1302
        });
1303
        box.show();
1304
      },
1305
      startDrag: function() {
1306
        cursorBack = window.document.body.style.cursor;
1307
        window.document.body.style.cursor = 'pointer';
1308
        VK.Util.addEvent('mousemove', move);
1309
        VK.Util.addEvent('mouseup', mouseup);
1310
      },
1311
      stopDrag: function() {
1312
        window.document.body.style.cursor = cursorBack;
1313
        VK.Util.removeEvent('mousemove', move);
1314
        VK.Util.removeEvent('mouseup', mouseup);
1315
      }
1316
    }, {
1317
      startHeight: 133,
1318
      minWidth: 300
1319
    }, function(o, i, r) {iframe = i; rpc = r;});
1320
  };
1321

1322
  VK.Widgets.CommentsBrowse = function(objId, options) {
1323
    options = options || {};
1324
    options.browse = 1;
1325
    return VK.Widgets.Comments(objId, options);
1326
  };
1327

1328
  VK.Widgets.Recommended = function(objId, options) {
1329
    var pData = VK.Util.getPageData();
1330
    if (!VK._apiId) throw Error('VK not initialized. Please use VK.init');
1331
    options = options || {};
1332
    var params = {
1333
      limit: options.limit || 5,
1334
      max: options.max || 0,
1335
      sort: options.sort || 'friend_likes',
1336
      verb: options.verb || 0,
1337
      period: options.period || 'week',
1338
      target: options.target || 'parent'
1339
    };
1340
    return VK.Widgets._constructor('widget_recommended.php', objId, options, params, {}, {
1341
      startHeight: (116 + params.limit * 47 - 15),
1342
      minWidth: 150
1343
    });
1344
  };
1345

1346
  VK.Widgets.Post = function(objId, ownerId, postId, hash, options) {
1347
    options = options || {};
1348
    var obj = document.getElementById(objId),
1349
      params = {
1350
        owner_id: ownerId,
1351
        post_id: postId,
1352
        hash: hash || ''
1353
      }, iframe, rpc, cursorBack;
1354
    return VK.Widgets._constructor('widget_post.php', objId, options, params, {
1355
      showBox: function(url, props) {
1356
        var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1357
          proxy: function() {
1358
            rpc.callMethod.apply(rpc, arguments);
1359
          }
1360
        });
1361
        box.show();
1362
      },
1363
      startDrag: function() {
1364
        cursorBack = window.document.body.style.cursor;
1365
        window.document.body.style.cursor = 'pointer';
1366
      },
1367
      stopDrag: function() {
1368
        window.document.body.style.cursor = cursorBack;
1369
      }
1370
    }, {
1371
      startHeight: 90,
1372
      minWidth: 250
1373
    }, function(o, i, r) {iframe = i; rpc = r;});
1374
  };
1375

1376
  VK.Widgets.Like = (function(Like) {
1377
    if (Like) return Like;
1378

1379
    var instances = [];
1380

1381
    Like = function(objId, options, page) {
1382
      var pData = VK.Util.getPageData();
1383
      if (!VK._apiId) throw Error('VK not initialized. Please use VK.init');
1384
      options = VK.extend(options || {}, {allowTransparency: true});
1385
      var verticalBtnHeightWidth = {
1386
            18: 43,
1387
            20: 47,
1388
            22: 51,
1389
            24: 55,
1390
            30: 67,
1391
          },
1392
          type = (options.type == 'full' || options.type == 'button' || options.type == 'vertical' || options.type == 'mini') ? options.type : 'full',
1393
          autoWidth = options.width === 'auto' && (type == 'button' || type == 'mini'),
1394
          btnHeight = parseInt(options.height, 10) || 22,
1395
          size = btnHeight && verticalBtnHeightWidth[btnHeight] ? btnHeight : 22,
1396
          width = autoWidth ? 153 : (type == 'full' ? Math.max(200, options.width || 350) : (type == 'button' ? 180 : (type == 'mini' ? 115 : verticalBtnHeightWidth[size]))),
1397
          height = type == 'vertical' ? (2 * btnHeight + 7) : btnHeight,
1398
          params = {
1399
            page: page || 0,
1400
            url: options.pageUrl || pData.url,
1401
            type: type,
1402
            verb: options.verb == 1 ? 1 : 0,
1403
            color: options.color || '',
1404
            title: options.pageTitle || pData.title,
1405
            description: options.pageDescription || pData.description,
1406
            image: options.pageImage || pData.image,
1407
            text: (options.text || '').substr(0, 140),
1408
            h: btnHeight
1409
          },
1410
          ttHere = options.ttHere || false,
1411
          isOver = false,
1412
          hideTimeout = null,
1413
          obj, buttonIfr, buttonRpc, tooltipIfr, tooltipRpc, checkTO;
1414
      if (type == 'vertical' || type == 'button' || type == 'mini') delete options.width;
1415
      if (autoWidth) params.auto_width = 1;
1416
      function showTooltip(force) {
1417
        if ((!isOver && !force) || !tooltipRpc) return;
1418
        if (!tooltipIfr || !tooltipRpc || tooltipIfr.style.display != 'none' && tooltipIfr.getAttribute('vkhidden') != 'yes') return;
1419
        hideTimeout && clearTimeout(hideTimeout);
1420
        checkTO && clearTimeout(checkTO);
1421
        var scrollTop = options.getScrollTop ? options.getScrollTop() : (document.body.scrollTop || document.documentElement.scrollTop || 0);
1422
        var objPos = VK.Util.getXY(obj, options.fixed);
1423
        var startY = ttHere ? 0 : objPos[1];
1424
        if (scrollTop > objPos[1] - 120 && options.tooltipPos != 'top' || type == 'vertical' || options.tooltipPos == 'bottom') {
1425
          tooltipIfr.style.top = (startY + height + 2) + 'px';
1426
          tooltipRpc.callMethod('show', false, type+'_'+size);
1427
        } else {
1428
          tooltipIfr.style.top = (startY - 128) + 'px';
1429
          tooltipRpc.callMethod('show', true, type+'_'+size);
1430
        }
1431
        VK.Util.ss(tooltipIfr, {left: (ttHere ? 0 : objPos[0]) - (type == 'full' || type == 'button' ? 32 : 2) + 'px', display: 'block', opacity: 1, filter: 'none'});
1432
        tooltipIfr.setAttribute('vkhidden', 'no');
1433
        isOver = true;
1434
      }
1435

1436
      function hideTooltip(force) {
1437
        if ((isOver && !force) || !tooltipRpc) return;
1438
        tooltipRpc.callMethod('hide');
1439
        buttonRpc.callMethod('hide');
1440
        hideTimeout = setTimeout(function() {
1441
          tooltipIfr.style.display = 'none'
1442
        }, 400);
1443
      }
1444

1445
      var widgetId = VK.Widgets._constructor('widget_like.php', objId, options, params, {
1446
        initTooltip: function(counter) {
1447
          tooltipRpc = new fastXDM.Server({
1448
            onInit: counter ? function() {
1449
                showTooltip();
1450
              } : function() {},
1451
            proxy: function() {
1452
              buttonRpc.callMethod.apply(buttonRpc, arguments);
1453
            },
1454
            showBox: function(url, props) {
1455
              var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [props.width, props.height], {
1456
                proxy: function() {
1457
                  tooltipRpc.callMethod.apply(tooltipRpc, arguments);
1458
                }
1459
              });
1460
              box.show();
1461
            },
1462
          }, false, {safe: true});
1463
          tooltipIfr = tooltipRpc.append(ttHere ? obj : document.body, {
1464
            src: buttonIfr.src + '&act=a_like_tooltip',
1465
            scrolling: 'no',
1466
            allowTransparency: true,
1467
            id: buttonIfr.id + '_tt',
1468
            style: {position: 'absolute', padding: 0, display: 'none', opacity: 0.01, filter: 'alpha(opacity=1)', border: '0', width: '274px', height: '130px', zIndex: 5000, overflow: 'hidden'}
1469
          });
1470
          tooltipIfr.setAttribute('vkhidden', 'yes');
1471

1472
          tooltipIfr.onmouseover = function() {
1473
            clearTimeout(checkTO);
1474
            isOver = true;
1475
          };
1476
          tooltipIfr.onmouseout = function() {
1477
            clearTimeout(checkTO);
1478
            isOver = false;
1479
            checkTO = setTimeout(function() {hideTooltip(); }, 200);
1480
          };
1481
        },
1482
        showTooltip: showTooltip,
1483
        hideTooltip: hideTooltip,
1484
        destroy: function() {
1485
          buttonRpc.destroy();
1486
          try {buttonIfr.src = 'about: blank;';} catch (e) {}
1487
          buttonIfr.parentNode.removeChild(buttonIfr);
1488
          if (tooltipIfr) {
1489
            try {tooltipIfr.src = 'about: blank;';} catch (e) {}
1490
            tooltipIfr.parentNode.removeChild(tooltipIfr);
1491
          }
1492
          tooltipRpc && tooltipRpc.destroy();
1493
        },
1494
        showBox: function(url, props) {
1495
          var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1496
            proxy: function() {
1497
              buttonRpc.callMethod.apply(buttonRpc, arguments);
1498
            }
1499
          });
1500
          box.show();
1501
        },
1502
        proxy: function() {if (tooltipRpc) tooltipRpc.callMethod.apply(tooltipRpc, arguments);}
1503
      }, {
1504
        startHeight: height,
1505
        minWidth: width
1506
      }, function(o, i, r) {
1507
        buttonRpc = r;
1508
        VK.Util.ss(obj = o, {height: height + 'px', width: width + 'px', position: 'relative', clear: 'both'});
1509
        VK.Util.ss(buttonIfr = i, {height: height + 'px', width: width + 'px', overflow: 'hidden', zIndex: 150});
1510
        obj.onmouseover = function() {
1511
          clearTimeout(checkTO);
1512
          isOver = true;
1513
        };
1514
        obj.onmouseout = function() {
1515
          clearTimeout(checkTO);
1516
          isOver = false;
1517
          checkTO = setTimeout(function() {hideTooltip(); }, 200);
1518
        };
1519
      });
1520

1521
      instances.push(widgetId);
1522
      return widgetId;
1523
    };
1524

1525
    Like.destroyAll = function() {
1526
      var xdm = null;
1527
      while (instances[0]) {
1528
        xdm = VK.Widgets.RPC[instances.pop()];
1529
        xdm && xdm.methods.destroy();
1530
      }
1531
    }
1532

1533
    return Like;
1534
  })(VK.Widgets.Like);
1535

1536
  VK.Widgets.Poll = function(objId, options, pollId) {
1537
    var pData = VK.Util.getPageData();
1538
    if (!pollId) throw Error('No poll id passed');
1539
    options = options || {};
1540
    var params = {
1541
      poll_id: pollId,
1542
      url: options.pageUrl || pData.url || location.href,
1543
      title: options.pageTitle || pData.title,
1544
      description: options.pageDescription || pData.description
1545
    };
1546
    return VK.Widgets._constructor('al_widget_poll.php', objId, options, params, {}, {
1547
      startHeight: 144,
1548
      minWidth: 300
1549
    });
1550
  };
1551

1552
  VK.Widgets.App = function(objId, app_id, options) {
1553
    if (!app_id) throw Error('No app id passed');
1554
    if (!options) options = {};
1555
    var startHeight = void 0,
1556
        height = void 0,
1557
        minWidth = void 0,
1558
        params = {
1559
          aid: app_id,
1560
          mode: parseInt(options.mode, 10) || 1,
1561
        };
1562
    switch (params.mode) {
1563
      case 1:
1564
        options.width = 144;
1565
        startHeight = 251;
1566
        break;
1567
      case 2:
1568
        options.width = options.width ? Math.max(200, Math.min(10000, parseInt(options.width, 10))) : 200;
1569
        height = startHeight = 193;
1570
        break;
1571
      case 3:
1572
        options.width = options.width ? Math.max(50, Math.min(10000, parseInt(options.width, 10))) : void 0;
1573
        height = startHeight = options.height = ({18: 18, 20: 20, 22: 22, 24: 24, 30: 30})[parseInt(options.height, 10) || 30];
1574
        break;
1575
    }
1576
    minWidth = options.width;
1577
    return VK.Widgets._constructor('widget_app.php', objId, options, params, {}, {
1578
      startHeight: startHeight,
1579
      height: height,
1580
      minWidth: minWidth
1581
    });
1582
  };
1583

1584
  VK.Widgets.Community = VK.Widgets.Group = function(objId, options, gid) {
1585
    gid = parseInt(gid, 10);
1586
    if (!gid) {
1587
      throw Error('No group_id passed');
1588
    }
1589
    options.mode = parseInt(options.mode, 10).toString();
1590
    var params = {
1591
        gid: gid,
1592
        mode: (options.mode) ? options.mode : '0'
1593
      },
1594
      startHeight = options.mode == 3 ? 185 : (options.mode == 1 ? 141 : options.height|0 || 290),
1595
      rpc;
1596
    if (options.wall) params.wall = options.wall;
1597
    params.color1 = options.color1 || '';
1598
    params.color2 = options.color2 || '';
1599
    params.color3 = options.color3 || '';
1600
    params.class_name = options.class_name || '';
1601
    if (options.no_head) params.no_head = 1;
1602
    if (options.no_cover) params.no_cover = 1;
1603
    if (options.wide) {
1604
      params.wide = 1;
1605
      if (!options.width || options.width < 300) {
1606
        options.width = 300;
1607
      }
1608
    }
1609
    if (!options.width|0) options.width = 200;
1610

1611
    var cursorBack;
1612

1613
    function mouseup() {
1614
      rpc.callMethod('mouseUp');
1615
      return false;
1616
    }
1617

1618
    function move(event) {
1619
      rpc.callMethod('mouseMove', {screenY: event.screenY});
1620
      return false;
1621
    }
1622

1623
    return VK.Widgets._constructor('widget_community.php', objId, options, params, {
1624
      showBox: function(url, props) {
1625
        var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1626
          proxy: function() {
1627
            rpc.callMethod.apply(rpc, arguments);
1628
          }
1629
        });
1630
        box.show();
1631
      },
1632
      startDrag: function() {
1633
        cursorBack = window.document.body.style.cursor;
1634
        window.document.body.style.cursor = 'pointer';
1635
        VK.Util.addEvent('mousemove', move);
1636
        VK.Util.addEvent('mouseup', mouseup);
1637
      },
1638
      stopDrag: function() {
1639
        window.document.body.style.cursor = cursorBack;
1640
        VK.Util.removeEvent('mousemove', move);
1641
        VK.Util.removeEvent('mouseup', mouseup);
1642
      },
1643
      auth: function() {
1644
        VK.Auth.login(null, 1);
1645
      }
1646
    }, {
1647
      minWidth: 120,
1648
      startHeight: startHeight
1649
    }, function(o, i, r) {
1650
      rpc = r;
1651
    });
1652
  };
1653

1654
  VK.Widgets.Auth = function(objId, options) {
1655
    var pData = VK.Util.getPageData();
1656
    if (!VK._apiId) throw Error('VK not initialized. Please use VK.init');
1657
    if (!options.width) {
1658
      options.width = 200;
1659
    }
1660
    if (options.type) {
1661
      type = 1;
1662
    } else {
1663
      type = 0;
1664
    }
1665
    return VK.Widgets._constructor('widget_auth.php', objId, options, {}, {makeAuth: function(data) {
1666
      if (data.session) {
1667
        VK.Auth._loadState = 'loaded';
1668
        VK.Auth.setSession(data.session, 'connected');
1669
        VK.Observer.publish('auth.loginStatus', {session: data.session, status: 'connected'});
1670
        VK.Observer.unsubscribe('auth.loginStatus');
1671
      }
1672
      if (options.onAuth) {
1673
        options.onAuth(data);
1674
      } else {
1675
        if (options.authUrl) {
1676
          var href = options.authUrl;
1677
        } else {
1678
          var href = window.location.href;
1679
        }
1680
        if (href.indexOf('?') == -1) {
1681
          href+='?';
1682
        } else {
1683
          href+='&';
1684
        }
1685
        var vars = [];
1686

1687
        for (var i in data) {
1688
          if (i != 'session') vars.push(i+'='+decodeURIComponent(data[i]).replace(/&/g, '%26').replace(/\#/g, '%23').replace(/\?/, '%3F'));
1689
        }
1690
        window.location.href = href + vars.join('&');
1691
      }
1692
    }}, {
1693
      startHeight: 134
1694
    });
1695
  };
1696

1697
  VK.Widgets.Subscribe = function(objId, options, oid) {
1698
    oid = parseInt(oid, 10);
1699
    if (!oid) {
1700
      throw Error('No owner_id passed');
1701
    }
1702
    var params = {
1703
      oid: oid
1704
    }, rpc;
1705
    if (options.mode) {
1706
      params.mode = options.mode;
1707
    }
1708
    if (options.soft) {
1709
      params.soft = options.soft;
1710
    }
1711

1712
    return VK.Widgets._constructor('widget_subscribe.php', objId, options, params, {
1713
      showBox: function(url, props) {
1714
        var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1715
          proxy: function() {
1716
            rpc.callMethod.apply(rpc, arguments);
1717
          }
1718
        });
1719
        box.show();
1720
      },
1721
      auth: function() {
1722
        VK.Auth.login(null, 1);
1723
      }
1724
    }, {
1725
      minWidth: 220,
1726
      startHeight: 22
1727
    }, function(o, i, r) {
1728
      rpc = r;
1729
    });
1730
  };
1731

1732
  VK.Widgets.ContactUs = function(objId, options, oid) {
1733
    oid = parseInt(oid, 10);
1734

1735
    if (!options) options = {};
1736
    if (!oid) throw Error('No group or user id passed');
1737

1738
    var params = {
1739
      oid: oid,
1740
      height: ({18: 18, 20: 20, 22: 22, 24: 24, 30: 30})[parseInt(options.height, 10) || 24],
1741
      text: (options.text || '').substr(0, 140)
1742
    }, rpc;
1743

1744
    return VK.Widgets._constructor('widget_contactus.php', objId, options, params, {}, {
1745
      startHeight: params.height,
1746
      height: params.height
1747
    }, function(o, i, r) {
1748
      rpc = r;
1749
    });
1750
  };
1751

1752
  VK.Widgets.Playlist = function(objId, ownerId, playlistId, hash, options) {
1753
    var params = {
1754
      oid: parseInt(ownerId, 10),
1755
      pid: parseInt(playlistId, 10),
1756
      hash: hash || ''
1757
    }, rpc;
1758

1759
    if (!options) options = {};
1760
    if (!params.oid) throw Error('No owner id passed');
1761
    if (!params.pid) throw Error('No playlist id passed');
1762

1763
    return VK.Widgets._constructor('widget_playlist.php', objId, options, params, {
1764
      showBox: function(url, props) {
1765
        var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
1766
          proxy: function() {
1767
            rpc.callMethod.apply(rpc, arguments);
1768
          }
1769
        });
1770
        box.show();
1771
      }
1772
    }, {
1773
      minWidth: 200
1774
    }, function(o, i, r) {
1775
      rpc = r;
1776
    });
1777
  };
1778

1779
  VK.Widgets.Ads = function(objId, options, paramsExtra) {
1780
    options = options || {};
1781
    paramsExtra = paramsExtra || {};
1782
    var params = {};
1783
    var defaults = {};
1784
    var funcs = {};
1785
    var obj = document.getElementById(objId);
1786
    var iframe;
1787
    var rpc;
1788

1789
    var adsParams = {};
1790
    var adsParamsLocal = {};
1791
    var adsParamsDefault = {};
1792
    for (var key in paramsExtra) {
1793
      var keyFix = (inArray(key, ['hash']) ? key : 'ads_' + key);
1794
      adsParams[keyFix] = paramsExtra[key];
1795
    }
1796

1797
    if (obj && obj.getBoundingClientRect) {
1798
      obj.style.width  = '100%';
1799
      obj.style.height = '100%';
1800
      var rect = obj.getBoundingClientRect();
1801
      obj.style.width  = '';
1802
      obj.style.height = '';
1803
      adsParams.ads_ad_unit_width_auto  = Math.floor(rect.right - rect.left);
1804
      adsParams.ads_ad_unit_height_auto = Math.floor(rect.bottom - rect.top);
1805
    }
1806

1807
    adsParamsDefault.ads_ad_unit_width  = 100;
1808
    adsParamsDefault.ads_ad_unit_height = 100;
1809

1810
    adsParamsLocal.ads_ad_unit_width  = (parseInt(adsParams.ads_ad_unit_width)  || adsParams.ads_ad_unit_width === 'auto'  && adsParams.ads_ad_unit_width_auto  || adsParamsDefault.ads_ad_unit_width);
1811
    adsParamsLocal.ads_ad_unit_height = (parseInt(adsParams.ads_ad_unit_height) || adsParams.ads_ad_unit_height === 'auto' && adsParams.ads_ad_unit_height_auto || adsParamsDefault.ads_ad_unit_height);
1812
    if (adsParams.ads_handler) {
1813
      adsParamsLocal.ads_handler = adsParams.ads_handler;
1814
    }
1815
    if (adsParams.ads_handler_empty_html) {
1816
      adsParamsLocal.ads_handler_empty_html = adsParams.ads_handler_empty_html;
1817
    }
1818

1819
    delete adsParams.ads_handler;
1820
    delete adsParams.ads_handler_empty_html;
1821

1822
    params.act = 'ads_web';
1823
    params.url = location.href;
1824
    VK.extend(params, adsParams);
1825

1826
    options.noDefaultParams   = true;
1827
    options.width             = adsParamsLocal.ads_ad_unit_width;
1828
    options.allowTransparency = true;
1829
    defaults.startHeight = adsParamsLocal.ads_ad_unit_height;
1830
    defaults.minWidth    = adsParamsLocal.ads_ad_unit_width;
1831
    funcs.adsOnInitLoader = adsOnInitLoader;
1832
    funcs.adsOnInit       = adsOnInit;
1833

1834
    return VK.Widgets._constructor('ads_rotate.php', objId, options, params, funcs, defaults, onDone);
1835

1836
    function adsOnInitLoader(adsScriptVersion) {
1837
      VK.Widgets.loading(obj, true);
1838
      adsAttachScript(adsScriptVersion);
1839
    }
1840
    function adsOnInit(errorCode, adsParamsExport) {
1841
      VK.Widgets.loading(obj, false);
1842
      adsProcessParams(adsParamsExport);
1843
      if (options.onAdsReady) options.onAdsReady.apply(options.onAdsReady, Array.prototype.slice.call(arguments));
1844
      adsProcessHandler(errorCode);
1845
    }
1846
    function adsAttachScript(adsScriptVersion) {
1847
      if (!('vk__adsLight' in window)) {
1848
        window.vk__adsLight = false;
1849
        adsScriptVersion = parseInt(adsScriptVersion);
1850
        var attachScriptFunc = (VK.Api && VK.Api.attachScript || VK.addScript);
1851
        var base_domain = (options.base_domain || VK._protocol + '//vk.com');
1852
        attachScriptFunc(base_domain + '/js/al/aes_light.js?' + adsScriptVersion);
1853
      } else if (window.vk__adsLight && vk__adsLight.userHandlers && vk__adsLight.userHandlers.onInit) {
1854
        vk__adsLight.userHandlers.onInit(false); // false - do not publish initial onInit
1855
      }
1856
    }
1857
    function adsProcessParams(adsParamsExport) {
1858
      if (!adsParamsExport) {
1859
        return;
1860
      }
1861
      for (var paramName in adsParamsExport) {
1862
        var paramValue = adsParamsExport[paramName];
1863
        if (paramName === 'ads_ad_unit_width' || paramName === 'ads_ad_unit_height') {
1864
          if (!(paramName in adsParams)) {
1865
            adsParamsLocal[paramName] = (parseInt(paramValue) || paramValue === 'auto' && adsParams[paramName + '_auto'] || adsParamsDefault[paramName]);
1866
          }
1867
        } else {
1868
          if (!(paramName in adsParamsLocal)) {
1869
            adsParamsLocal[paramName] = paramValue;
1870
          }
1871
        }
1872
      }
1873
    }
1874
    function adsProcessHandler(errorCode) {
1875
      var handlerResult = adsEvalHandler(adsParamsLocal.ads_handler, errorCode);
1876
      if (errorCode <= 0 && handlerResult !== true) {
1877
        try { console.log('VK: ad_unit_id = ' + adsParams.ads_ad_unit_id, ', errorCode = ', errorCode); } catch (e) {}
1878
        adsInsertHtmlHandler(adsParamsLocal.ads_handler_empty_html, adsParamsLocal.ads_ad_unit_width, adsParamsLocal.ads_ad_unit_height);
1879
      }
1880
    }
1881
    function adsEvalHandler(handler) {
1882
      var result = false;
1883
      try {
1884
        if (!handler) {
1885
          return false;
1886
        }
1887
        var func = false;
1888
        if (isFunction(handler)) {
1889
          func = handler;
1890
        } else if (isString(handler)) {
1891
          var handlerFuncs = handler.split('.');
1892
          func = window;
1893
          for (var i = 0, len = handlerFuncs.length; i < len; i++) {
1894
            func = func[handlerFuncs[i]];
1895
            if (!func) {
1896
              break;
1897
            }
1898
          }
1899
          if (!func) {
1900
            if (handler.substr(0, 8) === 'function') {
1901
              handler = 'return ' + handler + ';';
1902
            }
1903
            var handlerResult = (new Function(handler))();
1904
            if (isFunction(handlerResult)) {
1905
              func = handlerResult;
1906
            } else {
1907
              result = handlerResult;
1908
            }
1909
          }
1910
        }
1911
        if (func) {
1912
          var args = Array.prototype.slice.call(arguments, 1);
1913
          result = func.apply(func, args);
1914
        }
1915
      } catch (e) {
1916
        try {
1917
          console.error(e);
1918
        } catch (e2) {}
1919
      }
1920

1921
      return result;
1922

1923
      function isFunction(obj) {
1924
        return Object.prototype.toString.call(obj) === '[object Function]';
1925
      }
1926
      function isString(obj) {
1927
        return Object.prototype.toString.call(obj) === '[object String]';
1928
      }
1929
    }
1930
    function adsInsertHtmlHandler(handlerHtml, width, height) {
1931
      if (!handlerHtml) {
1932
        return;
1933
      }
1934
      if (!obj) {
1935
        return;
1936
      }
1937

1938
      width  = (width  ? width  + 'px' : '');
1939
      height = (height ? height + 'px' : '');
1940

1941
      var iframeHandlerHtml = '<html><head></head><body style="padding: 0; margin: 0;"><div>' + handlerHtml + '</div></body></html>';
1942

1943
      var iframeHandler = document.createElement('iframe');
1944
      iframeHandler.onload            = fixIframeHeight;
1945
      iframeHandler.id                = (iframe ? iframe.id : ('vkwidget-' + Math.round(Math.random() * 1000000))) + '_ads_html_handler';
1946
      iframeHandler.src               = 'about:blank';
1947
      iframeHandler.width             = '100%';
1948
      iframeHandler.height            = '100%';
1949
      iframeHandler.scrolling         = 'no';
1950
      iframeHandler.frameBorder       = '0';
1951
      iframeHandler.allowTransparency = true;
1952
      iframeHandler.style.overflow    = 'hidden';
1953
      iframeHandler.style.width       = width;
1954
      iframeHandler.style.height      = height;
1955

1956
      obj.style.width                 = width;
1957
      obj.style.height                = height;
1958

1959
      obj.appendChild(iframeHandler);
1960

1961
      iframeHandler.contentWindow.vk_ads_html_handler = iframeHandlerHtml;
1962
      iframeHandler.src = 'javascript:window["vk_ads_html_handler"]';
1963

1964
      function fixIframeHeight() {
1965
        if (height) {
1966
          return;
1967
        }
1968
        try {
1969
          var rect = iframeHandler.contentWindow.document.body.firstChild.getBoundingClientRect();
1970
          var heightFix = Math.ceil(rect.bottom - rect.top);
1971
          if (heightFix) {
1972
            iframeHandler.style.height = heightFix;
1973
            obj.style.height           = heightFix;
1974
          }
1975
        } catch (e) {}
1976
      }
1977
    }
1978
    function indexOf(arr, value, from) {
1979
      for (var i = from || 0, l = (arr || []).length; i < l; i++) {
1980
        if (arr[i] == value) return i;
1981
      }
1982
      return -1;
1983
    }
1984
    function inArray(value, arr) {
1985
      return indexOf(arr, value) != -1;
1986
    }
1987
    function onDone(o, i, r) {
1988
      obj = o;
1989
      iframe = i;
1990
      rpc = r;
1991
    }
1992
  };
1993

1994
  VK.Widgets.AllowMessagesFromCommunity = function (objId, options, groupId) {
1995
    groupId = parseInt(groupId, 10);
1996

1997
    if (!options) options = {};
1998
    if (!groupId || groupId < 0) throw Error('No group id passed');
1999

2000
    var params = {
2001
      height: ({22: 22, 24: 24, 30: 30})[parseInt(options.height, 10) || 24],
2002
      key: options.key ? options.key.substr(0, 256) : '',
2003
      group_id: groupId
2004
    }, rpc;
2005

2006
    return VK.Widgets._constructor('widget_allow_messages_from_community.php', objId, options, params, {}, {
2007
      startHeight: params.height,
2008
      height: params.height
2009
    }, function(o, i, r) {
2010
      rpc = r;
2011
    });
2012
  };
2013

2014
  VK.Widgets.CommunityMessages = (function(CommunityMessages) {
2015
    if (CommunityMessages) return CommunityMessages;
2016

2017
    var instances = {}, wCur = {};
2018
    var BUTTONS_CONF = {
2019
      no_button: {width: 0, height: 0},
2020
      blue_circle: {
2021
        width: 50,
2022
        height: 50,
2023
        margin: {
2024
          bottom: 20
2025
        }
2026
      }
2027
    }, DEFAULT_BUTTON_TYPE = 'blue_circle',
2028
    BUTTON_POSITIONS = {
2029
      left: {
2030
        bottom: 0,
2031
        left: 20
2032
      },
2033
      right: {
2034
        bottom: 0,
2035
        right: 20
2036
      }
2037
    }, DEFAULT_BUTTON_POSITION = 'right';
2038

2039
    /* options
2040
      - welcomeScreen
2041
      - expandTimeout
2042
      - shown || expended
2043
      - widgetPosition
2044
      - buttonType
2045
      - disableButtonTooltip
2046
      - tooltipButtonText
2047
      - disableNewMessagesSound
2048
      - disableExpandChatSound
2049
      - disableTitleChange
2050
    */
2051
    CommunityMessages = function(objId, gid, options) {
2052
      options = options || {};
2053

2054
      options.width = 300;
2055
      options.height = 399;
2056

2057
      if (!options.base_domain) {
2058
        options.base_domain = options.base_domain || VK._protocol + '//vk.com';
2059
      }
2060

2061
      options.expandTimeout = parseInt(options.expandTimeout) || 0;
2062

2063
      var params = {
2064
        gid: gid
2065
      };
2066

2067
      options.expanded = parseInt(options.expanded) || 0;
2068

2069
      if (!options.from_dev && lsGet('expanded') != null || options.expanded) {
2070
        options.shown = 1;
2071
      }
2072

2073
      if (options.shown) {
2074
        params.shown = 1;
2075
      }
2076

2077
      if (!options.welcomeScreen) {
2078
        params.disable_welcome_screen = 1;
2079
      }
2080

2081
      var buttonType = options.buttonType;
2082
      if (Object.keys(BUTTONS_CONF).indexOf(buttonType) == -1) {
2083
        buttonType = DEFAULT_BUTTON_TYPE;
2084
      }
2085

2086
      if (buttonType == 'no_button') {
2087
        options.disableButtonTooltip = 1;
2088
      }
2089

2090
      if (options.disableButtonTooltip) {
2091
        params.disable_tooltip = 1;
2092
      }
2093
      if (options.tooltipButtonText) {
2094
        params.tooltip_text = options.tooltipButtonText;
2095
      }
2096

2097
      if (options.disableNewMessagesSound) {
2098
        params.disable_new_messages_sound = 1;
2099
      }
2100

2101
      if (instances[objId]) {
2102
        CommunityMessages.destroy(objId);
2103
      }
2104

2105
      params.domain = document.domain;
2106

2107
      options.no_loading = 1;
2108

2109
      var curBox = false, expanded = 0;
2110
      var ttSize = [0, 0], widgetPosition;
2111

2112
      changeWidgetPosition(options.widgetPosition);
2113
      params.button_position = options.widgetPosition;
2114

2115
      var chatRpc, chatIfr;
2116
      var inited = 0, timers = {};
2117
      instances[objId] = VK.Widgets._constructor('widget_community_messages.php', objId, options, params, {
2118
        onStartLoading: function() {
2119
          var obj = document.getElementById(objId);
2120
          obj.style.position = 'fixed';
2121
          obj.style['z-index'] = 10000;
2122
          updateWidgetPosition();
2123
        },
2124
        onReady: function () {
2125
          inited = 1;
2126
          if (options.expandTimeout > 0 && !options.shown) {
2127
            timers.showTimer = setTimeout(function () {
2128
              expandChat({
2129
                playSong: !options.disableExpandChatSound,
2130
                noSaveState: 1
2131
              });
2132
            }, options.expandTimeout);
2133
          }
2134
        },
2135
        showBox: function(url) {
2136
          if (curBox) {
2137
            try {
2138
              curBox.hide();
2139
              try {
2140
                curBox.iframe.src = 'about: blank;';
2141
              } catch (e) {}
2142
              curBox.iframe.parentNode.removeChild(curBox.iframe);
2143
            } catch(e) { }
2144
          }
2145
          curBox = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, url), [], {
2146
            proxy: function() {
2147
              rpc.callMethod.apply(rpc, arguments);
2148
            }
2149
          });
2150
          curBox.show();
2151
        },
2152
        setTooltipSize: function (size) {
2153
          ttSize = size;
2154
          if (!expanded) {
2155
            minimize();
2156
          }
2157
        },
2158
        expand: function(opts) {
2159
          opts = opts || {};
2160
          expanded = 1;
2161
          expand();
2162

2163
          if (!opts.noSaveState) {
2164
            lsSet('expanded', 1);
2165
          }
2166
        },
2167
        minimize: function() {
2168
          setTimeout(function() {
2169
            expanded = 0;
2170
            minimize(objId);
2171
            lsRemove('expanded');
2172
          }, 120);
2173
        },
2174
        canNotWrite: function(type) {
2175
          options.onCanNotWrite && options.onCanNotWrite(type);
2176
        },
2177
        destroy: function() {
2178
          chatRpc.destroy();
2179
          try {chatIfr.src = 'about: blank;';} catch (e) {}
2180
          try {
2181
            chatIfr.parentNode.removeChild(chatIfr);
2182
          } catch(e) { }
2183
        },
2184
        fatalError: function(error_code, public_id) {
2185

2186
          var query = {
2187
            code: error_code,
2188
            widget: 2,
2189
            public_id: public_id,
2190
          };
2191

2192
          if (error_code == 1903) {
2193
            query.referrer_domain = document.domain;
2194
          }
2195

2196
          var query_str = [];
2197
          for(var i in query) {
2198
            query_str.push(i+'='+query[i]);
2199
          }
2200

2201
          CommunityMessages.destroy(objId);
2202
          var box = VK.Util.Box(VK.Widgets.showBoxUrl(options.base_domain, 'blank.php?'+query_str.join('&')));
2203
          box.show();
2204
        },
2205
        setPageTitle: function (title) {
2206
          if (options.disableTitleChange) {
2207
            return;
2208
          }
2209
          stopTitleAnimation();
2210
          wCur.oldTitle = document.title || null;
2211
          wCur.title = title;
2212
          wCur.changeTitleMode = 0;
2213
          startTitleNotify(1);
2214
        },
2215
        resetPageTitle: function () {
2216
          stopTitleAnimation();
2217
        },
2218
        newMessage: function () {
2219
          if (document.hasFocus && !document.hasFocus() && !options.disableNewMessagesSound) {
2220
            callRpcMethod('playNewMsgSong');
2221
          }
2222
        }
2223
      }, {}, function(o, i, r) {
2224
        chatRpc = r;
2225
        chatIfr = i;
2226
        if (!options.shown) {
2227
          minimize();
2228
        } else {
2229
          expand();
2230
        }
2231
      });
2232

2233
      function startTitleNotify(fast) {
2234
        clearTimeout(wCur.titleTimer);
2235
        wCur.titleTimer = setTimeout(function () {
2236
          if (wCur.changeTitleMode == 1) {
2237
            document.title = wCur.oldTitle || '';
2238
          } else {
2239
            document.title = wCur.title;
2240
          }
2241
          wCur.changeTitleMode = wCur.changeTitleMode == 1 ? 0 : 1;
2242
          startTitleNotify();
2243
        }, fast ? 0 : 1500);
2244
      }
2245

2246
      function stopTitleAnimation() {
2247
        if (options.disableTitleChange) {
2248
          return;
2249
        }
2250
        clearTimeout(wCur.titleTimer);
2251
        if (wCur.oldTitle) {
2252
          document.title = wCur.oldTitle;
2253
        } else if (wCur.oldTitle === null) {
2254
          document.title = '';
2255
        }
2256
        wCur.title = '';
2257
      }
2258

2259
      function expand() {
2260
        var obj = document.getElementById(objId), frame = obj.getElementsByTagName('iframe')[0];
2261

2262
        obj.style.width = frame.width = '372px';
2263
        obj.style.height = frame.height = '399px';
2264
        obj.style.margin = '0px 0px 0px 0px';
2265
        //frame.style.boxShadow = '0 0 0 1px rgba(0, 20, 51, .12), 0 20px 40px 0 rgba(0, 0, 0, 0.3)';
2266
        //frame.style.borderRadius = '6px';
2267
      }
2268

2269
      function minimize() {
2270
        var obj = document.getElementById(objId), frame = obj.getElementsByTagName('iframe')[0];
2271

2272
        var btnConf = BUTTONS_CONF[buttonType];
2273

2274
        var w = btnConf.width + ttSize[0];
2275
        var h = Math.max(btnConf.height, ttSize[1]);
2276

2277
        obj.style.width = w + 'px';
2278
        obj.style.height = h + 'px';
2279
        frame.style.boxShadow = 'none';
2280

2281
        var margin = btnConf.margin ? btnConf.margin : {};
2282
        obj.style.margin = '0px ' + (margin.right || 0) + 'px ' + (margin.bottom || 0) + 'px 0px';
2283

2284
        if (frame) {
2285
          frame.width = w;
2286
          frame.height = h;
2287
        }
2288
      }
2289

2290
      function changeWidgetPosition(position) {
2291
        widgetPosition = position;
2292
        if (Object.keys(BUTTON_POSITIONS).indexOf(widgetPosition) == -1) {
2293
          widgetPosition = DEFAULT_BUTTON_POSITION;
2294
        }
2295
        updateWidgetPosition();
2296
        callRpcMethod('changeButtonPosition', widgetPosition);
2297
      }
2298

2299
      function updateWidgetPosition() {
2300
        var obj = document.getElementById(objId);
2301

2302
        if (!obj) {
2303
          return;
2304
        }
2305

2306
        var props = ['left', 'right', 'top', 'bottom'];
2307
        for(var i in props) {
2308
          obj.style[props[i]] = '';
2309
        }
2310

2311
        var conf = BUTTON_POSITIONS[widgetPosition];
2312
        for(var i in conf) {
2313
          obj.style[i] = conf[i] + 'px';
2314
        }
2315

2316
        if (!inited) {
2317
          return;
2318
        }
2319

2320
        if (expanded) {
2321
          expand();
2322
        } else {
2323
          minimize();
2324
        }
2325
      }
2326

2327
      function callRpcMethod() {
2328
        chatRpc && chatRpc.callMethod.apply(chatRpc, arguments);
2329
      }
2330

2331
      /* opts
2332
        - welcomeScreen
2333
      */
2334
      function expandChat(opts) {
2335
        if (!opts || Object.prototype.toString.call(opts) !== '[object Object]') {
2336
          opts = {};
2337
        }
2338

2339
        if (opts.welcomeScreen == undefined) {
2340
          opts.welcomeScreen = options.welcomeScreen;
2341
        }
2342

2343
        clearTimeout(timers.showTimer);
2344
        callRpcMethod('expand', opts);
2345
      }
2346

2347
      function minimizeChat() {
2348
        callRpcMethod('minimize');
2349
      }
2350

2351
      function destroyChat() {
2352
        stopTitleAnimation();
2353
        CommunityMessages.destroy(objId);
2354
      }
2355

2356
      return {
2357
        expand: expandChat,
2358
        minimize: minimizeChat,
2359
        destroy: destroyChat,
2360
        changeButtonPosition: changeWidgetPosition,
2361
        stopTitleAnimation: stopTitleAnimation,
2362
      };
2363
    };
2364

2365
    function lsGet(key) {
2366
      if (!window.localStorage) {
2367
        return null;
2368
      }
2369
      return localStorage.getItem('vk_community_widget_' + key);
2370
    }
2371

2372
    function lsSet(key, value) {
2373
      window.localStorage && localStorage.setItem('vk_community_widget_' + key, value);
2374
    }
2375

2376
    function lsRemove(key) {
2377
      window.localStorage && localStorage.removeItem('vk_community_widget_' + key);
2378
    }
2379

2380
    CommunityMessages.destroy = function(objId) {
2381
      if (!instances[objId]) {
2382
        return;
2383
      }
2384

2385
      var xdm = VK.Widgets.RPC[instances[objId]];
2386
      xdm && xdm.methods.destroy();
2387

2388
      delete instances[objId];
2389
    };
2390

2391
    CommunityMessages.expand = function (objId) {
2392
      console.log(instances[objId]);
2393
    };
2394

2395
    return CommunityMessages;
2396
  })(VK.Widgets.CommunityMessages);
2397

2398
  VK.Widgets._constructor = function(widgetUrl, objId, options, params, funcs, defaults, onDone, widgetId, iter) {
2399
    var obj = document.getElementById(objId);
2400
    widgetId = widgetId || (++VK.Widgets.count);
2401

2402
    if (!obj) {
2403
      iter = iter || 0;
2404
      if (iter > 10) {
2405
        throw Error('VK.Widgets: object #' + objId + ' not found.');
2406
      }
2407
      setTimeout(function() {
2408
        VK.Widgets._constructor(widgetUrl, objId, options, params, funcs, defaults, onDone, widgetId, iter + 1);
2409
      }, 500);
2410
      return widgetId;
2411
    }
2412

2413
    options = options || {};
2414
    defaults = defaults || {};
2415
    funcs = funcs || {};
2416

2417
    if (options.preview) {
2418
      params.preview = 1;
2419
      delete options['preview'];
2420
    }
2421

2422
    var ifr, url, urlQueryString, encodedParam, rpc, iframe, i,
2423
      base_domain = options.base_domain || VK._protocol + '//vk.com',
2424
      width = options.width === 'auto' ? (obj.clientWidth || obj.offsetWidth || defaults.minWidth) | 0 : parseInt(options.width || 0, 10);
2425
    width = width ? (Math.max(defaults.minWidth || 200, Math.min(defaults.maxWidth || 10000, width)) + 'px') : '100%';
2426
    obj.style.width = width;
2427

2428
    if (options.height) {
2429
      params.height = options.height;
2430
      obj.style.height = options.height + 'px';
2431
    } else {
2432
      obj.style.height = (defaults.startHeight || 200) + 'px';
2433
    }
2434

2435
    if (width === '100%') params.startWidth = (obj.clientWidth || obj.offsetWidth) | 0;
2436
    if (!params.url) params.url = options.pageUrl || location.href.replace(/#.*$/, '');
2437

2438
    url = base_domain + '/' + widgetUrl;
2439
    urlQueryString = '';
2440
    if (!options.noDefaultParams) {
2441
      urlQueryString += '&app=' + (VK._apiId || '0') + '&width=' + encodeURIComponent(width)
2442
    }
2443
    urlQueryString += '&_ver=' + VK.version
2444
    if (VK._iframeAppWidget) {
2445
      params.iframe_app = 1;
2446
    }
2447
    var pData = VK.Util.getPageData();
2448
    params.url      = params.url     || pData.url || "";
2449
    params.referrer = params.referrer || document.referrer || "";
2450
    params.title    = params.title   || pData.title  || document.title || "";
2451
    for (i in params) {
2452
      if (i == 'title' && params[i].length > 80) params[i] = params[i].substr(0, 80)+'...';
2453
      if (i == 'description' && params[i].length > 160) params[i] = params[i].substr(0, 160)+'...';
2454
      if (typeof(params[i]) == 'number') {
2455
        encodedParam = params[i];
2456
      } else {
2457
        try {
2458
          encodedParam = encodeURIComponent(params[i]);
2459
        } catch (e) {
2460
          encodedParam = '';
2461
        }
2462
      }
2463
      urlQueryString += '&' + i + '=' + encodedParam;
2464
    }
2465
    urlQueryString += '&' + (+new Date()).toString(16);
2466
    url += '?' + urlQueryString.substr(1);
2467

2468
    funcs.onStartLoading && funcs.onStartLoading();
2469
    if (!options.no_loading) {
2470
      VK.Widgets.loading(obj, true);
2471
    }
2472

2473
    funcs.showLoader = function(enable) {
2474
      VK.Util.Loader(enable);
2475
    };
2476
    funcs.publish = function() {
2477
      var args = Array.prototype.slice.call(arguments);
2478
      args.push(widgetId);
2479
      VK.Observer.publish.apply(VK.Observer, args);
2480
    };
2481
    funcs.onInit = function() {
2482
      VK.Widgets.loading(obj, false);
2483
      if (funcs.onReady) funcs.onReady();
2484
      if (options.onReady) options.onReady();
2485
    };
2486
    funcs.resize = function(e, cb) {
2487
      obj.style.height = e + 'px';
2488
      var el = document.getElementById('vkwidget' + widgetId);
2489
      if (el) {
2490
        el.style.height = e + 'px';
2491
      }
2492
    };
2493
    funcs.resizeWidget = function(newWidth, newHeight) {
2494
      newWidth  = parseInt(newWidth);
2495
      newHeight = parseInt(newHeight);
2496
      var widgetElem = document.getElementById('vkwidget' + widgetId);
2497
      if (isFinite(newWidth)) {
2498
        obj.style.width = newWidth + 'px';
2499
        if (widgetElem) {
2500
          widgetElem.style.width = newWidth + 'px';
2501
        }
2502
      }
2503
      if (isFinite(newHeight)) {
2504
        obj.style.height = newHeight + 'px';
2505
        if (widgetElem) {
2506
          widgetElem.style.height = newHeight + 'px';
2507
        }
2508
      }
2509
      if (options.onResizeWidget) options.onResizeWidget();
2510
    };
2511
    funcs.updateVersion = function(ver) {
2512
      if (ver > 1) {
2513
        VK.Api.attachScript('//vk.com/js/api/openapi_update.js?'+parseInt(ver));
2514
      }
2515
    };
2516
    rpc = VK.Widgets.RPC[widgetId] = new fastXDM.Server(funcs, function(origin) {
2517
      if (!origin) return true;
2518
      origin = origin.toLowerCase();
2519
      return (origin.match(/(\.|\/)vk\.com($|\/|\?)/));
2520
    }, {safe: true});
2521
    iframe = VK.Widgets.RPC[widgetId].append(obj, {
2522
      src: url,
2523
      width: (width.indexOf('%') != -1) ? width : (parseInt(width) || width),
2524
      height: defaults.startHeight || '100%',
2525
      scrolling: 'no',
2526
      id: 'vkwidget' + widgetId,
2527
      allowTransparency: options.allowTransparency || false,
2528
      style: {
2529
        overflow: 'hidden'
2530
      }
2531
    });
2532
    onDone && setTimeout(function() {onDone(obj, iframe || obj.firstChild, rpc);}, 10);
2533
    return widgetId;
2534
  };
2535
}
2536

2537
if (!VK.Util) {
2538
  VK.Util = {
2539
    getPageData: function() {
2540
      if (!VK._pData) {
2541
        var metas = document.getElementsByTagName('meta'), pData = {}, keys = ['description', 'title', 'url', 'image', 'app_id'], metaName;
2542
        for (var i in metas) {
2543
          if (!metas[i].getAttribute) continue;
2544
          if (metas[i].getAttribute && ((metaName = metas[i].getAttribute('name')) || (metaName = metas[i].getAttribute('property')))) {
2545
            for (var j in keys) {
2546
              if (metaName == keys[j] || metaName == 'og:'+keys[j] || metaName == 'vk:'+keys[j]) {
2547
                pData[keys[j]] = metas[i].content;
2548
              }
2549
            }
2550
          }
2551
        }
2552
        if (pData.app_id && !VK._apiId) {
2553
          VK._apiId = pData.app_id;
2554
        }
2555
        pData.title = pData.title || document.title || '';
2556
        pData.description = pData.description || '';
2557
        pData.image = pData.image || '';
2558
        if (!pData.url && VK._iframeAppWidget && VK._apiId) {
2559
          pData.url = '/app' + VK._apiId;
2560
          if (VK._browserHash) {
2561
            pData.url += VK._browserHash
2562
          }
2563
        }
2564
        var loc = location.href.replace(/#.*$/, '');
2565
        if (!pData.url || !pData.url.indexOf(loc)) {
2566
          pData.url = loc;
2567
        }
2568
        VK._pData = pData;
2569
      }
2570
      return VK._pData;
2571
    },
2572
    getStyle: function(elem, name) {
2573
      var ret, defaultView = document.defaultView || window;
2574
      if (defaultView.getComputedStyle) {
2575
        name = name.replace(/([A-Z])/g, '-$1').toLowerCase();
2576
        var computedStyle = defaultView.getComputedStyle(elem, null);
2577
        if (computedStyle) {
2578
          ret = computedStyle.getPropertyValue(name);
2579
        }
2580
      } else if (elem.currentStyle) {
2581
        var camelCase = name.replace(/\-(\w)/g, function(all, letter){
2582
          return letter.toUpperCase();
2583
        });
2584
        ret = elem.currentStyle[name] || elem.currentStyle[camelCase];
2585
      }
2586

2587
      return ret;
2588
    },
2589

2590
    getXY: function(obj, fixed) {
2591
      if (!obj || obj === undefined) return;
2592

2593
      var left = 0, top = 0;
2594
      if (obj.getBoundingClientRect !== undefined) {
2595
        var rect = obj.getBoundingClientRect();
2596
        left = rect.left;
2597
        top = rect.top;
2598
        fixed = true;
2599
      } else if (obj.offsetParent) {
2600
        do {
2601
          left += obj.offsetLeft;
2602
          top += obj.offsetTop;
2603
          if (fixed) {
2604
            left -= obj.scrollLeft;
2605
            top -= obj.scrollTop;
2606
          }
2607
        } while (obj = obj.offsetParent);
2608
      }
2609
      if (fixed) {
2610
        top += window.pageYOffset || window.scrollNode && scrollNode.scrollTop || document.documentElement.scrollTop;
2611
        left += window.pageXOffset || window.scrollNode && scrollNode.scrollLeft || document.documentElement.scrollLeft;
2612
      }
2613

2614
      return [left, top];
2615
    },
2616

2617
    Loader: function self(enable) {
2618
      if (!self.loader) {
2619
        self.loader = document.createElement('DIV');
2620
        self.loader.innerHTML = '<style type="text/css">\
2621
        @-webkit-keyframes VKWidgetsLoaderKeyframes {0%{opacity: 0.2;}30%{opacity: 1;}100%{opacity: 0.2;}}\
2622
        @keyframes VKWidgetsLoaderKeyframes {0%{opacity: 0.2;}30%{opacity: 1;}100%{opacity: 0.2;}}\
2623
        .VKWidgetsLoader div {width: 7px;height: 7px;-webkit-border-radius: 50%;-khtml-border-radius: 50%;-moz-border-radius: 50%;border-radius: 50%;background: #fff;top: 21px;position: absolute;z-index: 2;-o-transition: opacity 350ms linear; transition: opacity 350ms linear;opacity: 0.2;-webkit-animation-duration: 750ms;-o-animation-duration: 750ms;animation-duration: 750ms;-webkit-animation-name: VKWidgetsLoaderKeyframes;-o-animation-name: VKWidgetsLoaderKeyframes;animation-name: VKWidgetsLoaderKeyframes;-webkit-animation-iteration-count: infinite;-o-animation-iteration-count: infinite;animation-iteration-count: infinite;-webkit-transform: translateZ(0);transform: translateZ(0);}</style><div class="VKWidgetsLoader" style="position: fixed;left: 50%;top: 50%;margin: -25px -50px;z-index: 1002;height: 50px;width: 100px;"><div style="left: 36px;-webkit-animation-delay: 0ms;-o-animation-delay: 0ms;animation-delay: 0ms;"></div><div style="left: 47px;-webkit-animation-delay: 180ms;-o-animation-delay: 180ms;animation-delay: 180ms;"></div><div style="left: 58px;-webkit-animation-delay: 360ms;-o-animation-delay: 360ms;animation-delay: 360ms;"></div><span style="display: block;background-color: #000;-webkit-border-radius: 4px;-khtml-border-radius: 4px;-moz-border-radius: 4px;border-radius: 4px;-webkit-box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.35);-moz-box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.35);box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.35);position: absolute;left: 0;top: 0;bottom: 0; right: 0;z-index: 1;opacity: 0.7;"></span></div>';
2624
        document.body.insertBefore(self.loader, document.body.firstChild);
2625
      }
2626
      self.loader.style.display = enable ? 'block' : 'none';
2627
    },
2628

2629
    Box: function(src, sizes, fnc, options) {
2630
      fnc = fnc || {};
2631
      var overflowB = document.body.style.overflow;
2632
      VK.Util.Loader(true);
2633
      var is_vk = /(^|\.)(vk\.com|vkontakte\.ru)$/.test(location.hostname);
2634
      var rpc = new fastXDM.Server(VK.extend(fnc, {
2635
            onInit: function() {
2636
              iframe.style.background = 'transparent';
2637
              iframe.style.visibility = 'visible';
2638
              document.body.style.overflow = 'hidden';
2639
              iframe.setAttribute('allowfullscreen', 1);
2640
              if (is_vk) document.body.className += ' layers_shown';
2641
              VK.Util.Loader();
2642
            },
2643
            hide: function() {
2644
              iframe.style.display = 'none';
2645
            },
2646
            tempHide: function() {
2647
              iframe.style.left = '-10000px';
2648
              iframe.style.top = '-10000px';
2649
              iframe.style.width = '10px';
2650
              iframe.style.height = '10px';
2651
              if (is_vk) document.body.className = document.body.className.replace(/\b\s*?layers_shown\s*\b/, ' ');
2652
              document.body.style.overflow = overflowB;
2653
            },
2654
            destroy: function() {
2655
              try {
2656
                iframe.src = 'about: blank;';
2657
              } catch (e) {}
2658
              iframe.parentNode.removeChild(iframe);
2659
              if (is_vk) document.body.className = document.body.className.replace(/\b\s*?layers_shown\s*\b/, ' ');
2660
              document.body.style.overflow = overflowB;
2661
            },
2662
            resize: function(w, h) {
2663
            }
2664
          }, true), false, {safe: true}),
2665
          iframe = rpc.append(document.body, {
2666
            src: src.replace(/&amp;/g, '&'),
2667
            scrolling: 'no',
2668
            allowTransparency: true,
2669
            style: {position: 'fixed', left: 0, top: 0, zIndex: 1002, background: VK._protocol + '//vk.com/images/upload.gif center center no-repeat transparent', padding: '0', border: '0', width: '100%', height: '100%', overflow: 'hidden', visibility: 'hidden'}
2670
          });
2671
      return {
2672
        show: function(scrollTop, height) {
2673
          iframe.style.display = 'block';
2674
          document.body.style.overflow = 'hidden';
2675
        },
2676
        hide: function() {
2677
          iframe.style.display = 'none';
2678
          document.body.style.overflow = overflowB;
2679
        },
2680
        iframe: iframe,
2681
        rpc: rpc
2682
      }
2683
    },
2684

2685
    addEvent: function(type, func) {
2686
      if (window.document.addEventListener) {
2687
        window.document.addEventListener(type, func, false);
2688
      } else if (window.document.attachEvent) {
2689
        window.document.attachEvent('on'+type, func);
2690
      }
2691
    },
2692

2693
    removeEvent: function(type, func) {
2694
      if (window.document.removeEventListener) {
2695
        window.document.removeEventListener(type, func, false);
2696
      } else if (window.document.detachEvent) {
2697
        window.document.detachEvent('on'+type, func);
2698
      }
2699
    },
2700

2701
    ss: function(el, styles) {VK.extend(el.style, styles, true);}
2702
  };
2703
}
2704

2705
if (!VK.Retargeting) {
2706
  VK.Retargeting = {
2707
    pixelCode: null,
2708
    Init: function (pixelCode) {
2709
      this.pixelCode = pixelCode;
2710
    },
2711
    Event: function (event) {
2712
      if (!this.pixelCode) {
2713
        return;
2714
      }
2715

2716
      (window.Image ? (new Image()) : document.createElement('img')).src = 'https://vk.com/rtrg?p=' + this.pixelCode + (event ? ('&event=' + encodeURIComponent(event)) : '');
2717
    },
2718
    Hit: function () {
2719
      this.Event();
2720
    },
2721
    Add: function (audienceID) {
2722
      if (!this.pixelCode || !audienceID) {
2723
        return;
2724
      }
2725

2726
      (window.Image ? (new Image()) : document.createElement('img')).src = 'https://vk.com/rtrg?p=' + this.pixelCode + '&audience=' + encodeURIComponent(audienceID);
2727
    },
2728
    ProductEvent: function (priceListID, event, params, opts) {
2729
      if (!this.pixelCode || !event || !priceListID) {
2730
        return;
2731
      }
2732

2733
      opts = opts || {};
2734

2735
      var canShowErrors = true;
2736
      if (typeof opts.show_errors !== 'undefined') {
2737
        canShowErrors = opts.show_errors ? true : false;
2738
      }
2739
      var errorsIgnore = '0';
2740
      if (typeof opts.errors_ignore !== 'undefined') {
2741
        errorsIgnore = opts.errors_ignore ? '1' : '0';
2742
      }
2743

2744
      var url = 'https://vk.com/rtrg';
2745
      var productParams = params ? JSON.stringify(params) : '';
2746
      var requestParams = {
2747
        'p': this.pixelCode,
2748
        'products_event': event,
2749
        'price_list_id': priceListID,
2750
        'e': '1',
2751
        'i': errorsIgnore
2752
      };
2753
      if (productParams) {
2754
        requestParams.products_params = productParams;
2755
      }
2756

2757
      var query = Object.keys(requestParams).map(function(key) {
2758
        var segment = encodeURIComponent(key) + '=' + encodeURIComponent(requestParams[key]);
2759
        return segment;
2760
      }).join('&');
2761

2762
      var requestUrl = url + '?' + query;
2763

2764
      VK.Api.makeRequest(requestUrl, this.onDone.bind(this, canShowErrors));
2765
    },
2766
    onDone: function(canShowErrors, response) {
2767
      if (!response || !canShowErrors) {
2768
        return;
2769
      }
2770

2771
      var resp;
2772
      try {
2773
        resp = JSON.parse(response);
2774
      } catch (e) {
2775
        return;
2776
      }
2777

2778
      if (!resp || !resp.errors) {
2779
        return;
2780
      }
2781
      this.showErrors(resp.errors);
2782
    },
2783
    showErrors: function(errors) {
2784
      if (!errors && !errors.length) {
2785
        return;
2786
      }
2787

2788
      var errorBegin = 'VK Pixel Error (' + this.pixelCode + '): ';
2789

2790
      if (typeof errors === 'string') {
2791
        console.error(errorBegin + errors);
2792
        return;
2793
      }
2794

2795
      var errorsLength = errors.length;
2796

2797
      if (!errorsLength) {
2798
        return;
2799
      }
2800

2801
      for (var i = 0; i < errorsLength; i++) {
2802
        console.error(errorBegin + errors[i]);
2803
      }
2804
    }
2805
  };
2806
}
2807

2808
// Init asynchronous library loading
2809
window.vkAsyncInit && setTimeout(vkAsyncInit, 0);
2810

2811
if (window.vkAsyncInitCallbacks && vkAsyncInitCallbacks.length) {
2812
  setTimeout(function() {
2813
    var callback;
2814
    while (callback = vkAsyncInitCallbacks.pop()) {
2815
      try {
2816
        callback();
2817
      } catch(e) {
2818
        try {
2819
          console.error(e);
2820
        } catch (e2) {}
2821
      }
2822
    }
2823
  }, 0);
2824
}
2825

2826
try{stManager.done('api/openapi.js');}catch(e){}
2827

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.