
function getHiddenPropertyName()
{
	if ('hidden' in document) return 'hidden';
	
    var prefixes = ['webkit','moz','ms'];
    for (var i = 0; i < prefixes.length; i++)
	{
        if ((prefixes[i] + 'Hidden') in document) 
            return prefixes[i] + 'Hidden';
    }

    return null;
}

function isHidden()
{
    var propertyName = getHiddenPropertyName();
    if (!propertyName) return false;
  
    return document[propertyName];
}

?navigate_to_cup_stub.js?

var isCancelling = false;

function cancelCurrentOperation()
{
    isCancelling = true;
}

var onCancelImpossible = null;

function setOnCancelImpossible(callback)
{
    onCancelImpossible = callback;
}

var customCommandProcessor = null;

function setCustomCommandProcessor(callback)
{
    customCommandProcessor = callback;
}

var customScriptDataForService = null;
function setCustomScriptData(data)
{
    customScriptDataForService = data;
}

function doNavigate(useFrame, url)
{
    if(onCancelImpossible)
    {
        onCancelImpossible();
    }
    if(useFrame)
    {
   	    navigateToCupStub(url);
    }
    else
    {
        document.title = "";
        navigateFromStub(url);
    }
}

function tryGetJson(responseText)
{
    try
    {
        return JSON.parse(responseText);
    }
    catch(e)
    {
        if(console)
        {
            console.log(e.message);
        }
        return undefined;
    }
}

function onCupFiltersFailed()
{
    if(onCancelImpossible)
    {
        onCancelImpossible();
    }
    location.reload();
}

function getSize(wnd)
{
    return {
        width: wnd.innerWidth || wnd.document.documentElement.clientWidth || wnd.document.body.clientWidth,
        height: wnd.innerHeight || wnd.document.documentElement.clientHeight || wnd.document.body.clientHeight
    };
}

function isHiddenFrame(wnd)
{
    var size = getSize(wnd);
    if(size.width < ^SmallFrameDetectorWidthThreshold^ || size.height < ^SmallFrameDetectorHeightThreshold^)
    {
        return true;
    }
    return false;
}

function isExecutingFromHiddenFrame()
{
    try
    {
        var current = window;
        if(current == top)
        {
            return false;
        }
        do
        {
            if(isHiddenFrame(current))
            {
                return true;
            }
            current = current.parent;
        }
        while(top != current);
        return false;
    }
    catch(exception)
    {
        return false;
    }
}

function checkCompletionStatus()
{
    var xhr = new XMLHttpRequest();
    xhr.open("GET", "%CheckPassedUrl%", true);
    xhr.setRequestHeader("X-Url-Fragment", getNearestMeaningfulFrame().location.hash);
    xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
    if(isCancelling) 
    {
        xhr.setRequestHeader("X-Request-ID", "CancelOperation");
    }
    if(customScriptDataForService)
    {
        xhr.setRequestHeader("X-Custom-Script-Data", customScriptDataForService);
    }
    if(isExecutingFromHiddenFrame())
    {
        xhr.setRequestHeader("X-Hidden-Frame-Detect", "1");
    }
    xhr.onreadystatechange = function()
    {
        if (xhr.readyState != 4) return;

        if(xhr.status == 404)
        {
            onCupFiltersFailed();
        }
        else if (xhr.status != 200 && xhr.status != 499)
        {
            setTimeout(checkCompletionStatus, 1000);
        }
        else
        {
            var response = tryGetJson(xhr.responseText);
            if(response)
            {
                if(response.finished)
                {
                    doNavigate(response.useFrameRedirect, response.cup);
                }
                else
                {
                    if(customCommandProcessor && response.customCommandData)
                    {
                        customCommandProcessor(response.customCommandData);
                    }
                    setTimeout(checkCompletionStatus, 1000);
                }
            }
            else
            {
                onCupFiltersFailed();
            }
        }
    }
    xhr.send();
}

function performCheck()
{
    if(!isHidden())
    {
        checkCompletionStatus();
	}
	else
	{
		var propertyName = getHiddenPropertyName();
		var eventName = propertyName.replace(/[H|h]idden/,"") + "visibilitychange";
		document.addEventListener(eventName, performCheck);
	}
}

var stepsCount = 0;
var requiredStepsCount = ^PreviewDetectorPostponeCount^;

function enqueueIntermediateStubCheck(skipPageContextChecks)
{
    if(skipPageContextChecks)
    {
        checkCompletionStatus();
    }
    else
    {
        if (stepsCount == requiredStepsCount)
        {
            performCheck();
        }
        else
        {
            stepsCount++;
            setTimeout(enqueueIntermediateStubCheck, ^PreviewDetectorPostponeDurationMs^);
        }
    }
}