1// ============================================================================ 2// ÐÐÐСТÐÐТР3// ============================================================================ 4 5const API_ENVIRONMENT = window.widgetConfig?.apiEnvironment || 'api.sandbox'; 6const SMP_API_KEY = window.widgetConfig?.smpApiKey || 'sportal.bg:X8hMnFQNsfiJ8ER2gZgpIKIBSCbf7BK0'; 7const DEBOUNCE_DELAY = 500; 8const ODDS_OVERLAP_INTERVAL = 3000; 9 10// ÐбÑи sdkOptions за вÑиÑки SDK-Ñа. Widget Studio Check не ÑеÑе Ñези полеÑа, 11// заÑова spread-ÑÑ ÑÑк не пÑеÑи на пÑовеÑкаÑа (за Ñазлика Ð¾Ñ labels/widgetAttributes). 12const BASE_SDK_OPTIONS = { 13 dataConfigApiKey: SMP_API_KEY, 14 dataConfigProject: 'sportal.bg', 15 dataConfigOddClient: 'sportal_web', 16 dataConfigTimezone: 'Europe/Sofia', 17 dataConfigLang: 'bg' 18}; 19 20// ============================================================================ 21// UTILITY ФУÐÐЦÐÐ 22// ============================================================================ 23 24const buildApiUrl = (service) => `https://${service}.${API_ENVIRONMENT}.sportal365.com`; 25 26// ============================================================================ 27// ÐÐÐФÐÐУРÐЦÐЯ ÐРСÐÐРТÐÐÐ 28// ============================================================================ 29 30// data-labels и widgetAttributes Ñа изпиÑани Ñ Ð»Ð¸ÑеÑали за вÑеки ÑпоÑÑ (без spread/helper-и): 31// Widget Studio â Config manager â Check ÑеÑе Ñамо лиÑеÑали и инаÑе показва ÑалÑиви 32// "липÑваÑи" еÑикеÑи/аÑÑибÑÑи. Само ÑÑойноÑÑиÑе, завиÑеÑи Ð¾Ñ ÑÑедаÑа, Ñа изÑази. 33const smpConfig = { 34 football: { 35 sdkOptions: { 36 ...BASE_SDK_OPTIONS, 37 dataConfigApiUrl: buildApiUrl('football'), 38 dataConfigStandingsApiUrl: buildApiUrl('standing'), 39 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 40 dataConfigCompetitionList: 'all' 41 }, 42 widgetAttributes: { 43 'data-header-display': true, 44 'data-refresh-time': 'medium', 45 'data-popular-list': 'sportal_popular', 46 'data-odds-display': true, 47 'data-odds-pre-event-only': false, 48 'data-betting-logo-overlap': true, 49 'data-theme': window.widgetTheme?.() || 'light', 50 'data-odds-betting-id': window.selectedBookies?.football?.id ?? '', 51 'data-name-format': 'last_name', 52 'data-labels': { 53 all: 'ÐÑиÑки', 54 popular: 'ÐопÑлÑÑни', 55 upcoming: 'ÐÑедÑÑоÑÑи', 56 live: 'Ðа Ðиво', 57 odds: 'С коеÑиÑиенÑи', 58 finished: 'ÐÑиклÑÑили', 59 standings: 'ÐлаÑиÑане', 60 score_table_label: 'РезÑлÑаÑи', 61 next_match: 'Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð¼Ð°Ñ:', 62 no_games: 'ÐÑма маÑове', 63 fixtures: 'ÐÑедÑÑоÑÑи ÑÑеÑи', 64 results: 'РезÑлÑаÑи', 65 current_season: 'ТекÑÑ Ñезон', 66 team: 'ÐÑбоÑ', 67 matches_won_short: 'Ð', 68 points_short: 'Т', 69 matches_played_short: 'Ð', 70 match_losses_short: 'Ð', 71 match_draws_short: 'Ð ', 72 team_form_short: 'ФоÑма', 73 team_form: 'ФоÑма на оÑбоÑа', 74 matches_played: 'ÐзигÑани маÑове', 75 goal_difference: 'Ðолова Ñазлика', 76 points: 'ТоÑки', 77 matches_won: 'СпеÑелени маÑове', 78 match_draw: 'РавенÑÑва', 79 match_losses: 'ÐагÑбени маÑове', 80 no_odds: 'ÐÑма налиÑни коеÑиÑиенÑи', 81 '1x2': '1Ð¥2', 82 OVER_UNDER: 'ÐÑой голове', 83 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 84 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 85 DRAW_NO_BET: 'Равен нÑма залог', 86 FIRST_TEAM_TO_SCORE: 'ÐÑÑви гол', 87 GAME_HANDICAP: 'Хендикап', 88 over: 'над', 89 under: 'под', 90 yes: 'Ðа', 91 no: 'Ðе', 92 name: 'Ðме', 93 age: 'ÐÑзÑаÑÑ', 94 minutes: 'ÐинÑÑи', 95 yellow_cards: 'ÐÑлÑи каÑÑони', 96 red_cards: 'ЧеÑвени каÑÑони', 97 forwards: 'ÐападаÑели', 98 player: 'ÐгÑаÑ', 99 played: 'ÐаÑове', 100 assists: 'ÐÑиÑÑенÑии', 101 goals: 'Ðолове', 102 conceded: 'ÐопÑÑнаÑи голове', 103 cleansheets: 'ЧиÑÑа мÑежа', 104 started: 'ТиÑÑлÑÑ', 105 no_data: 'ÐÑма налиÑна инÑоÑмаÑиÑ', 106 first_yellow_cards: 'ÐÑÑви жÑÐ»Ñ ÐºÐ°ÑÑон', 107 total_cards: 'ÐбÑо', 108 group: 'ÐÑÑпа', 109 H2H: 'H2H', 110 W: 'Ð', 111 L: 'Ð', 112 D: 'Ð ', 113 top_scores: 'ÐолмайÑÑоÑи', 114 most_decorated_player: 'Ðай-гÑÑби игÑаÑи', 115 score_table_total_label: 'Ð ', 116 score_table_overtime_label: 'Ð', 117 corners: 'ÐоÑнеÑи', 118 counter_attacks: 'ÐонÑÑааÑаки', 119 crosses: 'ЦенÑÑиÑаниÑ', 120 fouls_committed: 'ÐзвÑÑÑени наÑÑÑениÑ', 121 goal_kicks: 'ÐÑÑове', 122 offside: 'ÐаÑади', 123 possession: 'ÐÑиÑежание на ÑопкаÑа', 124 shots_blocked: 'ÐлокиÑани ÑдаÑи', 125 shots_off: 'ÐеÑоÑни ÑдаÑи', 126 shots_on: 'УдаÑи', 127 substitutions: 'Смени', 128 throw_in: 'ТÑÑове', 129 treatments: 'СпиÑÐ°Ð½Ð¸Ñ Ð·Ð° медиÑинÑка помоÑ', 130 vs: 'СÑеÑÑ',
131 minutes_substitute: 'ÐинÑÑи каÑо ÑмÑна', 132 offsides: 'ÐаÑади', 133 own_goals: 'ÐвÑоголове', 134 penalties_committed: 'ÐзвÑÑÑени дÑзпи', 135 penalties_missed: 'ÐÑопÑÑнаÑи дÑзпи', 136 penalties_received: 'СпеÑелени дÑзпи', 137 penalties_saved: 'СпаÑени дÑзпи', 138 penalty_goals: 'Ðолове Ð¾Ñ Ð´Ñзпи', 139 shots: 'УдаÑи', 140 shots_on_target: 'ТоÑни ÑдаÑи', 141 substitute_in: 'ÐлÑзÑл каÑо ÑмÑна', 142 substitute_out: 'Ðаменен', 143 defeats: 'ÐагÑби', 144 draw: 'РавенÑÑва', 145 goals_conceded: 'ÐопÑÑнаÑи голове', 146 goals_scored: 'ÐкаÑани голове', 147 win: 'Ðобеди', 148 rank: 'ÐозиÑÐ¸Ñ Ð² клаÑиÑанеÑо', 149 in_regular_time: 'Ð ÑедовноÑо вÑеме', 150 after_penalties: 'След дÑзпи', 151 aggregate: 'ÐÐ±Ñ ÑезÑлÑаÑ', 152 first_team: 'СÑаÑÑови ÑÑÑÑави', 153 substitutes: 'РезеÑви', 154 substituted_players: 'Смени', 155 formation: 'Ð¡Ñ ÐµÐ¼Ð°', 156 game_starts: 'ÐаÑало на маÑа', 157 no_events_yet: 'Ðез ÑÑбиÑÐ¸Ñ Ð´Ð¾ моменÑа', 158 match_information_tab: 'ÐнÑоÑмаÑиÑ', 159 match_timeline_tab: 'ÐеÑайли', 160 match_statistics_tab: 'СÑаÑиÑÑика', 161 match_standings_tab: 'ÐлаÑиÑане', 162 match_playoff_tab: 'Ð¡Ñ ÐµÐ¼Ð°', 163 match_odds_tab: 'ÐоеÑиÑиенÑи', 164 match_h2h_tab: 'Ðдин ÑÑеÑÑ Ð´ÑÑг', 165 penalty_goal: 'Ð', 166 own_goal: 'ÐÐ', 167 win_short: 'Ð', 168 draw_short: 'Ð ', 169 loss_short: 'Ð', 170 player_bio: 'ÐизиÑка', 171 position: 'ÐозиÑиÑ', 172 KEEPER: 'ÐÑаÑаÑ', 173 shirt_number: 'ÐомеÑ', 174 height: 'Ð ÑÑÑ', 175 weight: 'Тегло', 176 player_stats: 'СÑаÑиÑÑика', 177 weight_metric: 'кг', 178 height_metric: 'Ñм', 179 est: 'оÑн.', 180 aggregate_status: 'пÑодÑлжава напÑед', 181 aggregate_label: 'ÐÐЩ', 182 after_penalty_label: 'ÐУÐ', 183 team_stats: 'СÑаÑиÑÑика', 184 goals_difference_short: 'ÐÐ ', 185 goals_difference: 'Ðолова Ñазлика', 186 programme: 'ÐÑогÑама', 187 coach: 'ТÑенÑоÑ', 188 title: 'ÐлаÑиÑане', 189 penalties: 'ÐУÐ', 190 no_matches: 'ÐÑма маÑове', 191 round: 'ÐÑÑг', 192 select_team: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° оÑбоÑ', 193 select_lineup_group: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑÑÑÑав', 194 penalty: '(ÐÑзпа)', 195 match_center_tabs: 'Табове на Ð¼Ð°Ñ ÑенÑÑÑа', 196 match_center_loading: 'ÐаÑеждане...', 197 var_goal_review: 'ÐÐР· ÐÑовеÑка за гол', 198 var_card_review: 'ÐÐР· ÐÑовеÑка за каÑÑон', 199 var_penalty_review: 'ÐÐР· ÐÑовеÑка за дÑзпа', 200 var_review: 'ÐÐР· ÐÑовеÑка', 201 var_ended: 'ÐÐР· ÐÑовеÑкаÑа пÑиклÑÑи', 202 goal_disallowed: 'ÐолÑÑ Ðµ оÑменен', 203 goal_given: 'ÐолÑÑ Ðµ пÑизнаÑ', 204 goal_awarded: 'ÐÑиÑÑден гол', 205 card_confirmed: 'ÐаÑÑонÑÑ Ðµ поÑвÑÑден', 206 card_awarded: 'ÐÑиÑÑден каÑÑон', 207 card_disallowed: 'ÐаÑÑонÑÑ Ðµ оÑменен', 208 penalty_disallowed: 'ÐÑзпаÑа е оÑменена', 209 penalty_confirmed: 'ÐÑзпаÑа е поÑвÑÑдена', 210 penalty_not_confirmed: 'ÐÑзпаÑа не е поÑвÑÑдена', 211 penalty_retake: 'ÐÑзпаÑа Ñе изпÑлнÑва повÑоÑно', 212 web: 'ÐÑиÑиален ÑайÑ', 213 facebook: 'Facebook ÑÑÑаниÑа', 214 instagram: 'Instagram пÑоÑил', 215 twitter: 'Twitter пÑоÑил', 216 youtube: 'YouTube канал', 217 win_overtime_short: 'ÐÐ', 218 loss_overtime_short: 'ÐÐ', 219 win_after_penalty_short: 'ÐÑÐ', 220 loss_after_penalty_short: 'ÐÑÐ', 221 goals_substitute: 'Ðолове каÑо ÑезеÑва', 222 caught_ball: 'ХванаÑи Ñопки', 223 saves: 'СпаÑÑваниÑ', 224 follow: 'ÐоÑледвай', 225 followed: 'ÐоÑледван', 226 followers: 'поÑледоваÑели', 227 stakes_amount_description: 'ÐÑи залог Ð¾Ñ {amount}', 228 stakes_bet: 'Ðаложи Ñега', 229 stakes_bet_on_team: 'Ðаложи на победа за ÑÐ²Ð¾Ñ Ð¾ÑбоÑ!', 230 stakes_currency: 'â¬', 231 stakes_payout: 'ÐеÑалба', 232 stakes_stake: 'Ðалог', 233 stakes_limit_exceeded: 'ÐимиÑÑÑ Ðµ надвиÑен', 234 stakes_invalid_stake: 'Ðевалиден залог',
235 list_view: 'СпиÑÑк', 236 card_view: 'ÐаÑÑи', 237 CORRECT_SCORE: 'ТоÑен ÑезÑлÑаÑ', 238 FIRST_HALF_GOALS: 'Ðолове пÑез пÑÑвоÑо полÑвÑеме', 239 FIRST_PLAYER_TO_SCORE: 'ÐÑÑви голмайÑÑоÑ', 240 PLAYER_TO_SCORE_DURING_GAME: 'ÐгÑÐ°Ñ Ð´Ð° оÑбележи гол в маÑа', 241 PLAYER_TO_RECEIVE_CARD: 'ÐгÑÐ°Ñ Ð´Ð° полÑÑи каÑÑон', 242 FIRST_HALF_AND_FINAL_RESULT: 'ÐÑÑво полÑвÑеме / ÐÑаен ÑезÑлÑаÑ' 243 }, 244 'data-elements': { 245 stats: { 246 'player-h2h': [ 247 'minutes', 248 'goals', 249 'assists', 250 'yellow_cards', 251 'red_cards', 252 'cleansheets', 253 'shots', 254 'shots_on_target', 255 'played', 256 'started', 257 'substitute_in', 258 'substitute_out', 259 'minutes_substitute', 260 'goals_substitute', 261 'own_goals', 262 'penalty_goals', 263 'penalties_missed', 264 'penalties_committed', 265 'penalties_received', 266 'penalties_saved', 267 'fouls_committed', 268 'offsides' 269 ], 270 'team-h2h-match': [ 271 'goals', 272 'possession', 273 'shots_on', 274 'shots_off', 275 'shots_blocked', 276 'corners', 277 'yellow_cards', 278 'red_cards', 279 'offside', 280 'fouls_committed', 281 'crosses', 282 'throw_in', 283 'goal_kicks', 284 'counter_attacks', 285 'substitutions', 286 'treatments' 287 ], 288 'team-h2h': ['win', 'defeats', 'draw', 'goals_conceded', 'goals_scored', 'played', 'points', 'rank'], 289 'match-center': [ 290 'goals', 291 'possession', 292 'shots_on', 293 'shots_off', 294 'shots_blocked', 295 'corners', 296 'yellow_cards', 297 'red_cards', 298 'offside', 299 'fouls_committed', 300 'crosses', 301 'throw_in', 302 'goal_kicks', 303 'counter_attacks', 304 'substitutions', 305 'treatments' 306 ], 307 'top-scorers': [ 308 'goals', 309 'assists', 310 'played', 311 'minutes', 312 'penalties', 313 'missed_penalties', 314 'scored_first', 315 'red_cards', 316 'yellow_cards' 317 ], 318 'most-decorated': ['total_cards', 'red_cards', 'yellow_cards'] 319 } 320 }, 321 'data-entity-links': { 322 player: { 323 url: 'https://sportal.bg/football/player-{playerId}' 324 }, 325 team: { 326 url: 'https://sportal.bg/football/team-{teamId}' 327 }, 328 competition: { 329 url: 'https://sportal.bg/football/league-{competitionId}' 330 }, 331 standings: { 332 url: 'https://sportal.bg/football/league-{competitionId}#standings' 333 }, 334 match: { 335 url: 'https://sportal.bg/football/match-{teamId}-{teamId}#{matchId}', 336 sort: { 337 criteria: 'alphabetically', 338 direction: 'asc' 339 } 340 }, 341 configuration: { 342 newWindow: false 343 } 344 }, 345 'data-betslip-enabled': true 346 }, 347 themes: { 348 light: { 349 colors: {
350 footballFieldTone: 'green', 351 footballFieldLineColor: 'white', 352 standingsTopBg: '#2BAE74', 353 standingsTopPlayoffBg: '#7ED9A6', 354 standingsTierTwoBg: '#2E7DE9', 355 standingsTierTwoPlayoffBg: '#7BB4F2', 356 standingsRelegationPlayoffBg: '#F39C12', 357 standingsRelegationBg: '#E74C3C', 358 standingsHoverBg: '#F0F2F5' 359 } 360 }, 361 dark: { 362 colors: { 363 footballFieldTone: 'green', 364 footballFieldLineColor: 'white', 365 standingsTopBg: '#2BAE74', 366 standingsTopPlayoffBg: '#7ED9A6', 367 standingsTierTwoBg: '#2E7DE9', 368 standingsTierTwoPlayoffBg: '#7BB4F2', 369 standingsRelegationPlayoffBg: '#F39C12', 370 standingsRelegationBg: '#E74C3C', 371 standingsHoverBg: '#2A3543' 372 } 373 }, 374 client: { 375 colors: { 376 footballFieldTone: 'green', 377 footballFieldLineColor: 'white', 378 standingsTopBg: '#2BAE74', 379 standingsTopPlayoffBg: '#7ED9A6', 380 standingsTierTwoBg: '#2E7DE9', 381 standingsTierTwoPlayoffBg: '#7BB4F2', 382 standingsRelegationPlayoffBg: '#F39C12', 383 standingsRelegationBg: '#E74C3C', 384 standingsHoverBg: '#F0F2F5' 385 } 386 } 387 } 388 }, 389 basketball: { 390 sdkOptions: { 391 ...BASE_SDK_OPTIONS, 392 dataConfigApiUrl: buildApiUrl('basketball'), 393 dataConfigStandingsApiUrl: buildApiUrl('standing'), 394 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 395 dataConfigCompetitionList: 'all' 396 }, 397 widgetAttributes: { 398 'data-header-display': true, 399 'data-refresh-time': 'medium', 400 'data-popular-list': 'sportal_popular', 401 'data-odds-display': true, 402 'data-odds-pre-event-only': false, 403 'data-betting-logo-overlap': true, 404 'data-theme': window.widgetTheme?.() || 'light', 405 'data-odds-betting-id': window.selectedBookies?.basketball?.id ?? '', 406 'data-labels': { 407 all: 'ÐÑиÑки', 408 popular: 'ÐопÑлÑÑни', 409 upcoming: 'ÐÑедÑÑоÑÑи', 410 live: 'Ðа Ðиво', 411 odds: 'С коеÑиÑиенÑи', 412 finished: 'ÐÑиклÑÑили', 413 standings: 'ÐлаÑиÑане', 414 score_table_label: 'РезÑлÑаÑи', 415 next_match: 'Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð¼Ð°Ñ:', 416 no_games: 'ÐÑма ÑÑеÑи', 417 fixtures: 'ÐÑедÑÑоÑÑи ÑÑеÑи', 418 results: 'РезÑлÑаÑи', 419 round: 'ÐÑÑг', 420 points_short: 'Т', 421 score_short: 'Ð ', 422 percentages_short: 'ÐРЦ', 423 team: 'ÐÑбоÑ', 424 matches_won_short: 'Ð', 425 match_losses_short: 'Ð', 426 points_difference_short: 'Т', 427 matches_won: 'Ðобеди', 428 match_losses: 'ÐагÑби', 429 points_difference: 'ТоÑки', 430 points: 'ТоÑки', 431 percentages: 'ÐÑоÑÐµÐ½Ñ Ð½Ð° победиÑе', 432 win_overtime_short: 'Ð*', 433 loss_overtime_short: '*', 434 team_form_short: 'ФоÑма', 435 score_table_total_label: 'Ð ', 436 score_table_overtime_label: 'Ð', 437 '1x2': '1Ð¥2', 438 OVER_UNDER: 'Ðад/Ðод', 439 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 440 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 441 DRAW_NO_BET: 'Равен нÑма залог', 442 FIRST_TEAM_TO_SCORE: 'ÐÑÑви оÑбоÑ, койÑо Ñе оÑбележи', 443 CORRECT_SCORE: 'ТоÑен ÑезÑлÑаÑ', 444 FIRST_HALF_GOALS: 'Ðолове пÑез пÑÑвоÑо полÑвÑеме', 445 FIRST_PLAYER_TO_SCORE: 'ÐÑÑви голмайÑÑоÑ', 446 PLAYER_TO_SCORE_DURING_GAME: 'ÐгÑÐ°Ñ Ð´Ð° оÑбележи гол в маÑа', 447 PLAYER_TO_RECEIVE_CARD: 'ÐгÑÐ°Ñ Ð´Ð° полÑÑи Ð
447ºÐ°ÑÑон', 448 FIRST_HALF_AND_FINAL_RESULT: 'ÐÑÑво полÑвÑеме / ÐÑаен ÑезÑлÑаÑ', 449 over: 'Ðад', 450 under: 'Ðод', 451 yes: 'Ðа', 452 no: 'Ðе', 453 first_team: 'СÑаÑÑови ÑÑÑÑави', 454 substitutes: 'РезеÑви', 455 substituted_players: 'Смени', 456 coach: 'ТÑенÑоÑ', 457 vs: 'СÑеÑÑ', 458 select_team: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° оÑбоÑ', 459 select_lineup_group: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑÑÑÑав', 460 game_starts: 'ÐаÑало на маÑа', 461 no_events_yet: 'Ðез ÑÑбиÑÐ¸Ñ Ð´Ð¾ моменÑа', 462 penalty: '(Ðаказание)', 463 match_information_tab: 'ÐнÑоÑмаÑиÑ', 464 match_timeline_tab: 'ÐеÑайли', 465 match_standings_tab: 'ÐлаÑиÑане', 466 match_playoff_tab: 'Ð¡Ñ ÐµÐ¼Ð°', 467 match_center_tabs: 'Табове на Ð¼Ð°Ñ ÑенÑÑÑа', 468 match_center_loading: 'ÐаÑеждане...', 469 penalties: 'ÐУÐ', 470 series: 'СеÑии', 471 no_matches: 'ÐÑма маÑове', 472 aggregate_label: 'ÐÐЩ', 473 after_penalty_label: 'ÐУÐ', 474 no_data: 'ÐÑма налиÑна инÑоÑмаÑиÑ', 475 free_throw_made: 'ÐкаÑано наказаÑелно Ñ Ð²ÑÑлÑне', 476 team_form: 'ФоÑма на оÑбоÑа', 477 matches_played: 'ÐаÑове', 478 matches_played_short: 'Ð', 479 programme: 'ÐÑогÑама', 480 current_season: 'ТекÑÑ Ñезон' 481 }, 482 'data-entity-links': { 483 competition: { 484 url: 'https://sportal.bg/basketball/league-{competitionId}' 485 }, 486 slug: { 487 team: 'https://sportal.bg/basketball/team-{slug}', 488 competition: 'https://sportal.bg/basketball/league-{slug}', 489 standings: 'https://sportal.bg/basketball/league-{slug}#standings' 490 }, 491 configuration: { 492 newWindow: false 493 } 494 } 495 }, 496 onLoaded: () => {} 497 }, 498 tennis: { 499 sdkOptions: { 500 ...BASE_SDK_OPTIONS, 501 dataConfigApiUrl: buildApiUrl('tennis'), 502 dataConfigStandingsApiUrl: buildApiUrl('standing'), 503 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 504 dataConfigCompetitionList: 'all' 505 }, 506 widgetAttributes: { 507 'data-header-display': true, 508 'data-refresh-time': 'super_fast', 509 'data-popular-list': 'sportal_popular', 510 'data-odds-display': true, 511 'data-odds-pre-event-only': false, 512 'data-betting-logo-overlap': true, 513 'data-theme': window.widgetTheme?.() || 'light', 514 'data-odds-betting-id': window.selectedBookies?.tennis?.id ?? '', 515 'data-labels': { 516 all: 'ÐÑиÑки', 517 popular: 'ÐопÑлÑÑни', 518 upcoming: 'ÐÑедÑÑоÑÑи', 519 live: 'Ðа Ðиво', 520 odds: 'С коеÑиÑиенÑи', 521 finished: 'ÐÑиклÑÑили', 522 standings: 'ÐлаÑиÑане', 523 score_table_label: 'РезÑлÑаÑи', 524 next_match: 'Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð¼Ð°Ñ:', 525 no_games: 'ÐÑма ÑÑеÑи', 526 fixtures: 'ÐÑедÑÑоÑÑи ÑÑеÑи', 527 results: 'РезÑлÑаÑи', 528 points_short: 'Т', 529 score_short: 'С', 530 nationality_short: 'ÐÑÑжава', 531 name: 'Ðме', 532 points: 'ТоÑки', 533 nationality: 'ÐÑÑжава', 534 show_more: 'Ðиж повеÑе', 535 no_matches: 'ÐÑма маÑове', 536 single: 'ÑингÑл', 537 double: 'двойки', 538 team: 'оÑбоÑи', 539 score_table_total_label: 'С', 540 '1x2': '1Ð¥2', 541 OVER_UNDER: 'Ðад/Ðод', 542 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 543 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 544 DRAW_NO_BET: 'Равен нÑма залог', 545 FIRST_TEAM_TO_SCORE: 'ÐÑÑви оÑбоÑ, койÑо Ñе оÑбележи', 546 CORRECT_SCORE: 'ТоÑен ÑезÑлÑаÑ', 547 FIRST_HALF_GOALS: 'Ðолове пÑез пÑÑвоÑо полÑвÑеме', 548 FIRST_PLAYER_TO_SCORE: 'ÐÑÑви голмайÑÑоÑ', 549 PLAYER_TO_SCORE_DURING_GAME: 'ÐгÑÐ°Ñ Ð´Ð° оÑбележи гол в маÑа', 550 PLAYER_TO_RECEIVE_CARD: 'ÐгÑÐ°Ñ Ð´Ð° полÑÑи Ð
550ºÐ°ÑÑон', 551 FIRST_HALF_AND_FINAL_RESULT: 'ÐÑÑво полÑвÑеме / ÐÑаен ÑезÑлÑаÑ', 552 no: 'Ðе', 553 round: 'ÐÑÑг', 554 no_data: 'ÐÑма данни за ÑанглиÑÑаÑа' 555 } 556 }, 557 onLoaded: () => {} 558 }, 559 iceHockey: { 560 sdkOptions: { 561 ...BASE_SDK_OPTIONS, 562 dataConfigApiUrl: buildApiUrl('multi-sport'), 563 dataConfigStandingsApiUrl: buildApiUrl('standing'), 564 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 565 dataConfigCompetitionList: 'all_comp' 566 }, 567 widgetAttributes: { 568 'data-header-display': true, 569 'data-refresh-time': 'medium', 570 'data-popular-list': 'sportal_popular', 571 'data-odds-display': true, 572 'data-odds-pre-event-only': false, 573 'data-betting-logo-overlap': true, 574 'data-theme': window.widgetTheme?.() || 'light', 575 'data-odds-betting-id': window.selectedBookies?.iceHockey?.id ?? '', 576 'data-labels': { 577 all: 'ÐÑиÑки', 578 popular: 'ÐопÑлÑÑни', 579 upcoming: 'ÐÑедÑÑоÑÑи', 580 live: 'Ðа Ðиво', 581 odds: 'С коеÑиÑиенÑи', 582 finished: 'ÐÑиклÑÑили', 583 standings: 'ÐлаÑиÑане', 584 score_table_label: 'РезÑлÑаÑи', 585 next_match: 'Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð¼Ð°Ñ:', 586 no_games: 'ÐÑма ÑÑеÑи', 587 points_short: 'Т', 588 score: 'РезÑлÑаÑ', 589 round: 'ÐÑÑг -', 590 after_penalties: 'След дÑзпи', 591 FIRST_HALF: 'ÐÑÑво полÑвÑеме', 592 SECOND_HALF: 'ÐÑоÑо полÑвÑеме', 593 '1x2': '1Ð¥2', 594 OVER_UNDER: 'ÐÑой голове', 595 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 596 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 597 DRAW_NO_BET: 'Равен нÑма залог', 598 FIRST_TEAM_TO_SCORE: 'ÐÑÑви гол', 599 GAME_HANDICAP: 'Хендикап', 600 over: 'Ðад', 601 under: 'Ðод', 602 yes: 'Ðа', 603 no: 'Ðе', 604 percentages_short: 'ÐРЦ', 605 team: 'ÐÑбоÑ', 606 matches_won_short: 'Ð', 607 matches_played_short: 'Ð', 608 match_losses_short: 'Ð', 609 points_difference_short: 'Т', 610 matches_played: 'ÐаÑове', 611 matches_won: 'Ðобеди', 612 match_losses: 'ÐагÑби', 613 points_difference: 'ТоÑки', 614 points: 'ТоÑки', 615 percentages: 'ÐÑоÑÐµÐ½Ñ Ð½Ð° победиÑе', 616 team_form_short: 'ФоÑма', 617 team_form: 'ФоÑма на оÑбоÑа', 618 goals_difference_short: 'ÐÐ ', 619 goals_difference: 'Ðолова Ñазлика', 620 matches_won_overtime_short: 'ÐÑÐ', 621 matches_won_overtime: 'Ðобеди Ñлед пÑодÑлжениÑ', 622 no_data: 'ÐÑма налиÑна инÑоÑмаÑиÑ', 623 win_after_penalty_short: 'ÐÑÐ', 624 loss_after_penalty_short: 'ÐÑÐ', 625 win_overtime_short: 'ÐÐ', 626 loss_overtime_short: 'ÐÐ', 627 score_short: 'Ð ', 628 score_table_total_label: 'Ð ', 629 score_table_overtime_label: 'Ð', 630 CORRECT_SCORE: 'ТоÑен ÑезÑлÑаÑ', 631 FIRST_HALF_GOALS: 'Ðолове пÑез пÑÑвоÑо полÑвÑеме', 632 FIRST_PLAYER_TO_SCORE: 'ÐÑÑви голмайÑÑоÑ', 633 PLAYER_TO_SCORE_DURING_GAME: 'ÐгÑÐ°Ñ Ð´Ð° оÑбележи гол в маÑа', 634 PLAYER_TO_RECEIVE_CARD: 'ÐгÑÐ°Ñ Ð´Ð° полÑÑи Ð
634ºÐ°ÑÑон', 635 FIRST_HALF_AND_FINAL_RESULT: 'ÐÑÑво полÑвÑеме / ÐÑаен ÑезÑлÑаÑ', 636 first_team: 'СÑаÑÑови ÑÑÑÑави', 637 substitutes: 'РезеÑви', 638 substituted_players: 'Смени', 639 coach: 'ТÑенÑоÑ', 640 vs: 'СÑеÑÑ', 641 select_team: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° оÑбоÑ', 642 select_lineup_group: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑÑÑÑав', 643 game_starts: 'ÐаÑало на маÑа', 644 no_events_yet: 'Ðез ÑÑбиÑÐ¸Ñ Ð´Ð¾ моменÑа', 645 penalty: '(Ðаказание)', 646 match_information_tab: 'ÐнÑоÑмаÑиÑ', 647 match_timeline_tab: 'ÐеÑайли', 648 match_standings_tab: 'ÐлаÑиÑане', 649 match_playoff_tab: 'Ð¡Ñ ÐµÐ¼Ð°', 650 match_center_tabs: 'Табове на Ð¼Ð°Ñ ÑенÑÑÑа', 651 match_center_loading: 'ÐаÑеждане...', 652 matches_losses_overtime: 'ÐагÑби Ñлед пÑодÑлжениÑ', 653 matches_losses_overtime_short: 'ÐÑÐ', 654 win_after_penalty: 'Ðобеди Ñлед дÑзпи', 655 loss_after_penalty: 'ÐагÑби Ñлед дÑзпи', 656 programme: 'ÐÑогÑама', 657 no_matches: 'ÐÑма маÑове', 658 penalties: 'ÐУÐ', 659 series: 'СеÑии', 660 aggregate_label: 'ÐÐЩ', 661 after_penalty_label: 'ÐУÐ', 662 aggregate: 'ÐÐ±Ñ ÑезÑлÑаÑ', 663 penalty_goal: 'Ð', 664 own_goal: 'ÐÐ', 665 line: 'ÐеÑиÑа', 666 power_play: 'ЧиÑлено пÑевÑÐ·Ñ Ð¾Ð´ÑÑво', 667 suspension_2_min: 'Ðаказание (2 мин.)', 668 fixtures: 'ÐÑедÑÑоÑÑи ÑÑеÑи', 669 results: 'РезÑлÑаÑи', 670 current_season: 'ТекÑÑ Ñезон' 671 } 672 }, 673 onLoaded: () => {} 674 }, 675 volleyball: { 676 sdkOptions: { 677 ...BASE_SDK_OPTIONS, 678 dataConfigApiUrl: buildApiUrl('multi-sport'), 679 dataConfigStandingsApiUrl: buildApiUrl('standing'), 680 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 681 dataConfigCompetitionList: 'all' 682 }, 683 widgetAttributes: { 684 'data-header-display': true, 685 'data-refresh-time': 'medium', 686 'data-popular-list': 'sportal_popular_volleyball', 687 'data-odds-display': true, 688 'data-odds-pre-event-only': false, 689 'data-betting-logo-overlap': true, 690 'data-theme': window.widgetTheme?.() || 'light', 691 'data-odds-betting-id': window.selectedBookies?.volleyball?.id ?? '', 692 'data-labels': { 693 all: 'ÐÑиÑки', 694 popular: 'ÐопÑлÑÑни', 695 upcoming: 'ÐÑедÑÑоÑÑи', 696 live: 'Ðа Ðиво', 697 odds: 'С коеÑиÑиенÑи', 698 finished: 'ÐÑиклÑÑили', 699 standings: 'ÐлаÑиÑане', 700 score_table_label: 'РезÑлÑаÑи', 701 next_match: 'Ð¡Ð»ÐµÐ´Ð²Ð°Ñ Ð¼Ð°Ñ:', 702 no_games: 'ÐÑма ÑÑеÑи', 703 score_short: 'Ð ', 704 team: 'ÐÑбоÑ', 705 coach: 'ТÑенÑоÑ', 706 vs: 'СÑеÑÑ', 707 no_matches: 'ÐÑма маÑове', 708 no_data: 'ÐÑма данни за клаÑиÑанеÑо', 709 first_team: 'СÑаÑÑови ÑÑÑÑави', 710 substitutes: 'РезеÑви', 711 substituted_players: 'Смени', 712 select_team: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° оÑбоÑ', 713 select_lineup_group: 'ÐÐ·Ð±Ð¾Ñ Ð½Ð° ÑÑÑÑав', 714 game_starts: 'ÐаÑало', 715 no_events_yet: 'Ðез ÑÑбиÑÐ¸Ñ Ð´Ð¾ моменÑа', 716 penalty: '(Ðаказание)', 717 match_information_tab: 'ÐнÑоÑмаÑиÑ', 718 match_timeline_tab: 'ÐеÑайли', 719 match_standings_tab: 'ÐлаÑиÑане', 720 match_playoff_tab: 'Ð¡Ñ ÐµÐ¼Ð°', 721 match_center_tabs: 'Табове на Ð¼Ð°Ñ ÑенÑÑÑа', 722 match_center_loading: 'ÐаÑеждане...', 723 matches_played: 'ÐзигÑани маÑове', 724 matches_played_short: 'Ð', 725 matches_won: 'Ðобеди', 726 matches_won_short: 'Ð', 727 match_losses: 'ÐагÑби', 728 match_losses_short: 'Ð', 729 points: 'ТоÑки', 730 points_short: 'Т', 731 team_form: 'ФоÑма на оÑбоÑа', 732 team_form_short: 'Ф', 733 series: 'СеÑии', 734 penalties: 'ÐаказаниÑ', 735 score_table_total_label: 'Ð ', 736 aggregate_label: 'ÐÐЩÐ', 737 aggregate_status: 'пÑодÑлжава', 738 '1x2': '1Ð¥2', 739 OVER_UNDER: 'Ðад/Ðод', 740 over: 'Ðад', 741 under: 'Ðод', 742 yes: 'Ðа', 743 no: 'Ðе', 744 fixtures: 'ÐÑедÑÑоÑÑи ÑÑеÑи', 745 results: 'РезÑлÑаÑи', 746 round: 'ÐÑÑг', 747 current_season: 'ТекÑÑ Ñезон', 748 programme: 'ÐÑогÑама', 749 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 750 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 751 DRAW_NO_BET: 'Равен нÑма залог', 752 FIRST_TEAM_TO_SCORE: 'ÐÑÑви оÑбоÑ, койÑо Ñе оÑбележи', 753 after_penalty_label: 'ÐУÐ', 754 penalty_goal: 'Ð', 755 own_goal: 'ÐÐ' 756 } 757 }, 758 onLoaded: () => {} 759 }, 760 multisport: { 761 sdkOptions: { 762 ...BASE_SDK_OPTIONS, 763 dataConfigApiUrl: buildApiUrl('multi-sport'), 764 dataConfigMultisportApiUrl: buildApiUrl('multi-sport'), 765 dataConfigCompetitionList: 'sportal_multi-sport' 766 }, 767 widgetAttributes: { 768 'data-theme': window.widgetTheme?.() || 'light', 769 'data-labels': { 770 winner: 'ÐобедиÑел', 771 football: 'ФÑÑбол', 772 legal_text: 'Age Restriction', 773 legal_value: '18+', 774 legal_link: '#', 775 today: 'ÐнеÑ', 776 yesterday: 'ÐÑеÑа', 777 tomorrow: 'УÑÑе', 778 live: 'Ðа живо', 779 no_events: 'ÐÑма ÑÑеÑи', 780 no_live_events: 'ÐÑма ÑÑеÑи', 781 scroll_left: 'Ðазад', 782 scroll_right: 'ÐапÑед' 783 }, 784 'data-entity-links': { 785 football: { 786 player: { 787 url: 'https://sportal.bg/football/player-{playerId}' 788 }, 789 team: { 790 url: 'https://sportal.bg/football/team-{teamId}' 791 }, 792 competition: { 793 url: 'https://sportal.bg/football/league-{competitionId}' 794 }, 795 standings: { 796 url: 'https://sportal.bg/football/league-{competitionId}#standings' 797 }, 798 match: { 799 url: 'https://sportal.bg/football/match-{teamId}-{teamId}#{matchId}', 800 sort: { 801 criteria: 'alphabetically', 802 direction: 'asc' 803 } 804 }, 805 configuration: { 806 newWindow: false 807 } 808 } 809 } 810 }, 811 getAuthToken: () => {}, 812 onLoaded: () => {} 813 } 814}; 815 816const BETSLIP_CONFIG = { 817 sdkOptions: { ...BASE_SDK_OPTIONS }, 818 widgetAttributes: { 819 'data-betslip-config': { 820 enabled: true, 821 position: 'floating-inline-right', 822 floatingOnMobile: true, 823 ageRestrictionDisplay: 'none', 824 maxSelections: 10, 825 betType: 'multiples', 826 quickStakes: '5,10,20' 827 }, 828 'data-labels': { 829 betslip_continue_to: ' ',
830 betslip_combined_odds: 'ÐÐ±Ñ ÐºÐ¾ÐµÑиÑиенÑ:', 831 betslip_total_stake: 'ÐбÑо', 832 betslip_potential_win: 'ÐÑзмножно', 833 betslip_stake: 'СÑма', 834 betslip_opposing_outcomes: 'ÐзаимноизклÑÑваÑи Ñе Ð¸Ð·Ñ Ð¾Ð´Ð¸ не Ñа ÑазÑеÑени.', 835 betslip_max_selections: 'ÐоÑÑÐ¸Ð³Ð½Ð°Ñ Ðµ макÑималниÑÑ Ð±Ñой ÑелекÑии.', 836 betslip_settled_info: 'ÐÑкои Ð¾Ñ Ð²Ð°ÑиÑе ÑелекÑии веÑе Ñа пÑиклÑÑили. Те Ñа изклÑÑени Ð¾Ñ Ð¸Ð·ÑиÑлениÑÑа', 837 betslip_all_settled: 'ÐÑиÑки ÑелекÑии Ñа пÑиклÑÑили. ÐобавеÑе нови ÑелекÑии, за да пÑодÑлжиÑе.', 838 betslip_provider_switch_title: 'Само един бÑкмейкÑÑ ÐµÐ´Ð½Ð¾Ð²Ñеменно.', 839 betslip_provider_switch_description: 'СмÑнаÑа на бÑкмейкÑÑа Ñе изÑÑие ÑекÑÑиÑе ви ÑелекÑии.', 840 betslip_provider_switch_confirm: 'Смени бÑкмейкÑÑа', 841 betslip_provider_switch_cancel: 'ÐÑказ', 842 betslip_quick_stake_1: '5', 843 betslip_quick_stake_2: '10', 844 betslip_quick_stake_3: '20', 845 betslip_finished: 'ÐÑиклÑÑен', 846 betslip_terms: 'ÐбÑи ÑÑловиÑ', 847 betslip_responsible_gambling: 'ÐгÑай оÑговоÑно', 848 betslip_age_restriction: '18+', 849 '1x2': '1X2', 850 'FIRST HALF': 'ÐÑÑво полÑвÑеме', 851 'SECOND HALF': 'ÐÑоÑо полÑвÑеме', 852 OVER_UNDER: 'Ðад/Ðод', 853 DOUBLE_CHANCE: 'Ðвоен ÑанÑ', 854 BOTH_TO_SCORE: 'ÐваÑа оÑбоÑа да оÑбележаÑ', 855 DRAW_NO_BET: 'Ðалог без Ñавен', 856 FIRST_TEAM_TO_SCORE: 'ÐÑÑви оÑбоÑ, койÑо Ñе оÑбележи', 857 CORRECT_SCORE: 'ТоÑен ÑезÑлÑаÑ', 858 FIRST_HALF_GOALS: 'Ðолове пÑез пÑÑвоÑо полÑвÑеме', 859 FIRST_PLAYER_TO_SCORE: 'ÐÑÑви голмайÑÑоÑ', 860 PLAYER_TO_SCORE_DURING_GAME: 'ÐгÑÐ°Ñ Ð´Ð° оÑбележи гол в маÑа', 861 PLAYER_TO_RECEIVE_CARD: 'ÐгÑÐ°Ñ Ð´Ð° полÑÑи каÑÑон', 862 FIRST_HALF_AND_FINAL_RESULT: 'ÐÑÑво полÑвÑеме / ÐÑаен ÑезÑлÑаÑ', 863 over: 'Ðад', 864 under: 'Ðод', 865 yes: 'Ðа', 866 no: 'Ðе' 867 } 868 }, 869 onLoaded: () => {} 870}; 871 872// ============================================================================ 873// ÐÐ ÐÐÐÐ ÐÐ ÐÐÐÐÐÐÐÐ ÐÐÐФÐЦÐÐÐТР874// ============================================================================ 875 876const oddsFlushers = []; 877 878const buildOddsViews = (countsList, sport) => { 879 const page = window.currentPage || ''; 880 const views = {}; 881 882 countsList.forEach((counts) => { 883 Object.keys(counts).forEach((bookieId) => { 884 if (bookieId === 'unknown') { 885 return; 886 } 887 888 const view = views[bookieId] || (views[bookieId] = { sport, page, singleCount: 0, allCount: 0 }); 889 view.singleCount += 1; 890 view.allCount += counts[bookieId]; 891 }); 892 }); 893 894 return views; 895}; 896 897const trackOddsViews = (sport) => { 898 const odds = window.smpWidgetsOdds?.[sport]; 899 900 if (typeof odds !== 'object' || odds === null) { 901 return; 902 } 903 904 let pending = []; 905 let timer = null; 906 907 const flush = () => { 908 clearTimeout(timer); 909 timer = null; 910 911 if (pending.length === 0) { 912 return; 913 } 914 915 const views = buildOddsViews(pending, sport); 916 pending = []; 917 918 if (window.saveViewsFromWidgetsV2 && Object.keys(views).length > 0) { 919 window.saveViewsFromWidgetsV2(views); 920 } 921 }; 922 923 const widgetHandler = { 924 set: (widgetOdds, widgetCuid, counts) => { 925 widgetOdds[widgetCuid] = counts; 926 927 if (typeof counts === 'object' && counts !== null) { 928 pending.push(counts); 929 clearTimeout(timer); 930 timer = setTimeout(flush, DEBOUNCE_DELAY); 931 } 932 933 return true; 934 } 935 }; 936 937 // Ðдин Proxy на widget, за да не Ñе ÑÑздава нов пÑи вÑÑко ÑеÑене 938 const widgetProxies = new WeakMap(); 939 940 window.smpWidgetsOdds[sport] = new Proxy(odds, { 941 get: (target, widgetId, receiver) => { 942 const widgetOdds = Reflect.get(target, widgetId, receiver); 943 944 if (typeof widgetOdds !== 'object' || widgetOdds === null) { 945 return widgetOdds; 946 } 947 948 let proxy = widgetProxies.get(widgetOdds); 949 if (!proxy) { 950 proxy = new Proxy(widgetOdds, widgetHandler); 951 widgetProxies.set(widgetOdds, proxy); 952 } 953 954 return proxy; 955 } 956 }); 957 958 oddsFlushers.push(flush); 959}; 960 961document.addEventListener('visibilitychange', () => { 962 if (document.hidden) {
963 oddsFlushers.forEach(flush => flush()); 964 } 965}); 966 967// ============================================================================ 968// ÐÐÐЦÐÐÐÐÐÐЦÐЯ ÐРСÐÐРТÐÐ WIDGETS 969// ============================================================================ 970 971const SPORT_WIDGET_GLOBALS = { 972 football: 'smpFootballWidgets', 973 basketball: 'smpBasketballWidgets', 974 tennis: 'smpTennisWidgets', 975 iceHockey: 'smpIceHockeyWidgets', 976 volleyball: 'smpVolleyballWidgets', 977 multisport: 'smpMultisportWidgets' 978}; 979 980const LOAD_SPORT_WIDGETS = { 981 football: () => window.smpFootballWidgets.LoadSmpWidget(smpConfig.football), 982 basketball: () => window.smpBasketballWidgets.LoadSmpWidget(smpConfig.basketball), 983 tennis: () => window.smpTennisWidgets.LoadSmpWidget(smpConfig.tennis), 984 iceHockey: () => window.smpIceHockeyWidgets.LoadSmpWidget(smpConfig.iceHockey), 985 volleyball: () => window.smpVolleyballWidgets.LoadSmpWidget(smpConfig.volleyball), 986 multisport: () => window.smpMultisportWidgets.LoadSmpWidget(smpConfig.multisport) 987}; 988 989const readySports = new Set(); 990 991const saveWidgetClick = (data) => { 992 window.saveClicksFromWidgets?.(data); 993}; 994 995const sendWidgetPageView = (event) => { 996 if (window.sendPageView && event) { 997 const page = window.currentPage || ''; 998 window.sendPageView('Data reload', `${page}/${event.dataWidgetSport}-${event.dataWidgetId}`); 999 } 1000}; 1001 1002const initializeSportWidget = (sport, sdk) => { 1003 trackOddsViews(sport); 1004 1005 sdk.subscribe('bettingMarketValue', saveWidgetClick); 1006 sdk.subscribe('bettingLogo', saveWidgetClick); 1007 sdk.subscribe('onUserInteraction', sendWidgetPageView); 1008 1009 // ТемаÑа може да е Ñменена, докаÑо SDK-Ñо Ñе е заÑеждало (lazy SDK-ÑаÑа Ð¸Ð´Ð²Ð°Ñ Ð¿Ð¾-кÑÑно) 1010 smpConfig[sport].widgetAttributes['data-theme'] = window.widgetTheme?.() || 'light'; 1011 1012 readySports.add(sport); 1013 LOAD_SPORT_WIDGETS[sport](); 1014}; 1015 1016const onSdkRegistered = (globalName, init) => { 1017 let done = false; 1018 1019 const run = () => { 1020 const sdk = window[globalName]; 1021 1022 if (done || !sdk) { 1023 return; 1024 } 1025 1026 done = true; 1027 1028 try { 1029 init(sdk); 1030 } catch (error) { 1031 console.error(`[SMP] Error initializing ${globalName}:`, error); 1032 } 1033 }; 1034 1035 window.addEventListener(`${globalName}Registered`, run, { once: true }); 1036 run(); 1037}; 1038 1039Object.entries(SPORT_WIDGET_GLOBALS).forEach(([sport, globalName]) => { 1040 onSdkRegistered(globalName, sdk => initializeSportWidget(sport, sdk)); 1041}); 1042 1043onSdkRegistered('smpBetslipWidgets', () => window.smpBetslipWidgets.LoadSmpWidget(BETSLIP_CONFIG)); 1044 1045// ============================================================================ 1046// LAZY ÐÐÐ ÐÐÐÐÐÐ ÐÐ SDK-ТР1047// ============================================================================ 1048 1049const LAZY_SDK_WIDGET_PREFIXES = { 1050 basketball: 'basketball-', 1051 tennis: 'tennis-', 1052 iceHockey: 'ice-hockey-', 1053 volleyball: 'volleyball-', 1054 multisport: 'multisport-' 1055}; 1056 1057const SDK_BASE_URL = 'https://widgets.sportal365.com'; 1058const SDK_VERSION = window.widgetConfig?.widgetVersion; 1059const requestedSdks = new Set(); 1060 1061const loadNeededSdks = () => { 1062 if (!SDK_VERSION) { 1063 console.error('[SMP] window.widgetConfig.widgetVersion is missing - lazy SDKs are not loaded'); 1064 return; 1065 } 1066 1067 const widgetIds = Array.from( 1068 document.querySelectorAll('[data-widget-id]'), 1069 element => element.getAttribute('data-widget-id') || '' 1070 ); 1071 1072 Object.entries(LAZY_SDK_WIDGET_PREFIXES).forEach(([sport, prefix]) => { 1073 if (requestedSdks.has(sport) || !widgetIds.some(id => id.startsWith(prefix))) { 1074 return; 1075 } 1076 1077 requestedSdks.add(sport); 1078 1079 import(`${SDK_BASE_URL}/${prefix.slice(0, -1)}.${SDK_VERSION}.js`).catch((error) => { 1080 requestedSdks.delete(sport); // нов Ð¾Ð¿Ð¸Ñ Ð¿Ñи ÑледваÑаÑа AJAX навигаÑÐ¸Ñ 1081 console.error(`[SMP] Error loading ${sport} SDK:`, error); 1082 }); 1083 }); 1084}; 1085 1086loadNeededSdks(); 1087 1088// ============================================================================ 1089// ODDS OVERLAP ÐÐÐ¥ÐÐÐÐЪР1090// ============================================================================ 1091 1092window.smpCustomBettingOverlapValue = false;
1093 1094setInterval(() => { 1095 // ÐÑеки коеÑиÑÐ¸ÐµÐ½Ñ Ñе пÑе-ÑендеÑиÑа пÑи ÑмÑнаÑа - излиÑно в ÑкÑÐ¸Ñ Ñаб 1096 if (document.hidden) { 1097 return; 1098 } 1099 1100 window.smpCustomBettingOverlapValue = !window.smpCustomBettingOverlapValue; 1101 window.dispatchEvent(new Event('smpCustomBettingOverlapValueChange')); 1102}, ODDS_OVERLAP_INTERVAL); 1103 1104// ============================================================================ 1105// AJAX ÐÐÐТÐÐÐÐÐ Ð ÐÐÐÐЮÐÐÐÐÐ 1106// ============================================================================ 1107 1108const reloadAllWidgets = () => { 1109 readySports.forEach((sport) => { 1110 try { 1111 LOAD_SPORT_WIDGETS[sport](); 1112 } catch (error) { 1113 console.error(`[SMP] Error reloading ${sport} widgets:`, error); 1114 } 1115 }); 1116}; 1117 1118const setupMutationObserver = () => { 1119 const containers = ['pageContentJS', 'matchWidget'] 1120 .map(id => document.getElementById(id)) 1121 .filter(Boolean); 1122 1123 if (containers.length === 0) { 1124 return; 1125 } 1126 1127 // AJAX навигаÑиÑÑа ÑÐ¼ÐµÐ½Ñ innerHTML и поÑле Ñлага class="pseudo-class-loader". 1128 // ÐÑколко Ñмени в един кадÑÑ -> едно пÑезаÑеждане. 1129 let reloadScheduled = false; 1130 const observer = new MutationObserver(() => { 1131 if (reloadScheduled) { 1132 return; 1133 } 1134 1135 reloadScheduled = true; 1136 requestAnimationFrame(() => { 1137 reloadScheduled = false; 1138 loadNeededSdks(); 1139 reloadAllWidgets(); 1140 }); 1141 }); 1142 1143 containers.forEach(container => observer.observe(container, { attributes: true, attributeFilter: ['class'] })); 1144}; 1145 1146setupMutationObserver(); 1147 1148window.sprtlSMPConfig = smpConfig;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.