#include <bits/stdc++.h>

using namespace std;

#define MAXN 200010
#define MAXM 1000000
#define INF 0x3f3f3f3f
#define mo 1000000007
typedef long long LL;

int n, ans, segcnt;
int a[MAXN], b[MAXN];
int f[MAXN], l[MAXN], r[MAXN];
LL tree[4][MAXM + 10];
bool vis[MAXN];

void Init()
{
    srand(time(0));
    ans = segcnt = 0;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", a + i);
}

int Find(int u)
{
    return f[u] ? f[u] = Find(f[u]) : u;
}

inline int Sum1(int i, int l, int r)
{
    return (1LL * (i + r) * (r - i + 1) / 2 * (i - l + 1) - 1LL * (i + l - 2) * (i - l + 1) / 2 * (r - i + 1)) % mo;
}

void Solve1()
{
    memset(vis, 0, sizeof(vis));
    int i, j, fv, ret;
    for(i = 1; i <= n; ++i) b[i] = i;
    sort(b + 1, b + 1 + n, [](const int &x, const int &y){return a[x] < a[y]; });
    for(i = 1; i <= n; ++i){
        j = b[i]; vis[j] = true;
        l[j] = r[j] = j; f[j] = 0;
        if(vis[j - 1]){
            fv = Find(j - 1);
            f[fv] = j; l[j] = l[fv];
        }
        if(vis[j + 1]){
            fv = Find(j + 1);
            f[fv] = j; r[j] = r[fv];
        }
        ret = Sum1(j, l[j], r[j]);
        ans = (ans + 1LL * a[j] * ret) % mo;
        segcnt += ret; if(segcnt >= mo) segcnt -= mo;
    }
}

void Update(int k, int i, int v)
{
    for(; i <= MAXM; tree[k][i] += v, i += i & -i);
}

int Prefix(int k, int i)
{
    LL res = 0;
    for(; i; res += tree[k][i], i -= i & -i);
    (res >= mo) && (res %= mo);
    return res;
}

void Solve2()
{
    memset(l, 0, sizeof(l));
    memset(r, 0, sizeof(r));
    int i, res = 0;
    for(i = n; i; --i){
        l[i] = max(l[i + 1], a[i]);
        Update(0, l[i], 1);
        Update(1, MAXM - l[i] + 1, l[i]);
    }
    for(i = 2, r[0] = a[1]; i <= n; ++i){
        r[i - 1] = max(r[i - 2], a[i]);
        Update(2, r[i - 1], 1);
        Update(3, MAXM - r[i - 1] + 1, r[i - 1]);
    }
    for(i = 1; i <= n; ++i){
        res = (res + 1LL * l[i] * Prefix(2, l[i])) % mo;
        res += Prefix(3, MAXM - l[i]); if(res >= mo) res -= mo;
    }
    for(i = 1; i < n; ++i){
        ans += res; if(ans >= mo) ans -= mo;
        segcnt = (segcnt + 1LL * (n - i + 1) * (n - i)) % mo;
        res = (res + mo - 1LL * l[n - i + 1] * Prefix(2, l[n - i + 1]) % mo) % mo;
        res -= Prefix(3, MAXM - l[n - i + 1]); if(res < 0) res += mo;
        Update(0, l[n - i + 1], -1); Update(1, MAXM - l[n - i + 1] + 1, -l[n - i + 1]);
        res = (res + mo - 1LL * r[i] * Prefix(0, r[i]) % mo) % mo;
        res -= Prefix(1, MAXM - r[i]); if(res < 0) res += mo;
        Update(2, r[i], -1); Update(3, MAXM - r[i] + 1, -r[i]);
    }
}

void Solve3()
{
    LL N = 1LL * (n + 1) * n / 2;
    if(N & 1) segcnt = ((N + 1) / 2 % mo * (N % mo) + mo - segcnt) % mo;
    else segcnt = (N / 2 % mo * ((N + 1) % mo) + mo - segcnt) % mo;
    ans = (ans + 1LL * segcnt * l[1]) % mo;
}

int main()
{
#ifdef MYCP
    freopen("data.in", "r", stdin);
#endif // MYCP
    Init();
    Solve1();
    Solve2();
    Solve3();
    printf("%d\n", ans);
	return 0;
}