#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <numeric>
using namespace std;

#define M 1000000007LL

struct llnode {
    int64_t previd;
    int64_t nextid;   
    int64_t val;
    int64_t tetwidth;
    int64_t contains;
    bool visited = false;
};

vector<llnode> lst(200002);


int64_t ans = 0;
int64_t rectsofar = 0;

int64_t FF(int64_t x) {
    return x * (x + 2LL) * (2LL*x+2LL);
}

int64_t tet(int64_t x) {
    return ((x * (x+1LL) * (x+2LL))/6LL) % M;
}

int64_t tri(int64_t x) {
    return ((((x+1LL)*x) % M)*((M+1LL)/2LL)) % M;
}

int64_t rectthingy(int64_t x, int64_t y) {
    int64_t a = x + y;
    int64_t d = x - y;
    if (d < 0) d = -d;
    return (FF(a) - FF(d) - (min(x,y) * (d * d) * 12LL)) / 48LL;
}

vector<int64_t> slowgen(vector<int64_t> A) {
    vector<int64_t> B;
    int64_t offset = 0;
    for (int64_t i = 0; i < A.size(); i++) B.push_back(A[i]);
    for (int64_t k = 1; k < A.size(); k++) {
        for (int64_t i = 0; i < A.size() - k; i++) {
            B.push_back(max(B[offset + i], B[offset + i + 1]));
        }
        offset += (A.size() - k + 1);
    }
    
    return B;
}

int main() {
    /* Enter your code here. Read input from STDIN. Print output to STDOUT */   
    int64_t n, a;
    ans = 0;
    cin >> n;
    
    lst[0].previd = 0;
    lst[0].val = -1;
    lst[0].tetwidth = -1;
    lst[0].nextid = 1;
    
    vector<vector<int64_t>> locs(1000001);
    int64_t mx = 0;
    
    vector<int64_t> A;
    
    for (int64_t i = 1; i <= n; i++) {
        lst[i].previd = i-1;
        lst[i].nextid = i+1;
        lst[i].tetwidth = 1;
        lst[i].contains = 0;
        lst[i].visited = false;
        //lst[i].val = (i*i*i + 48*i + 10000);
        cin >> lst[i].val;
        A.push_back(lst[i].val);
        mx = max(mx, lst[i].val);
        locs[lst[i].val].push_back(i);
    }
    
    /*
    auto B = slowgen(A);
    auto C = slowgen(B);
    for (int64_t c : A) cout << c << " ";
    cout << endl;
    cout << C.size() << endl;
    for (int64_t c: C) ans = (ans + c) %M;
    cout << ans << endl;
    ans = 0;
    */
    
    lst[n+1].previd = n;
    lst[n+1].nextid = n+1;
    lst[n+1].val = -1;
    lst[n+1].tetwidth = -1;
    
    // Go in increasing order
    for (int64_t i = 1; i < mx; i++) {
        int64_t leftextent = 0;        
        int64_t rightextent = 0;
        for (int64_t j : locs[i]) {
            if (lst[j].visited) continue;
            int64_t nextnode = j;
            int64_t ctns = 0;
            // Start going left
            while (true) {
                nextnode = lst[nextnode].previd;
                if (nextnode == 0) break;
                if (lst[nextnode].val <= i) {
                    lst[j].previd = lst[nextnode].previd;
                    lst[lst[j].previd].nextid = j;
                    lst[j].tetwidth += lst[nextnode].tetwidth;
                    ctns += lst[nextnode].contains;
                    ctns %= M;
                    lst[nextnode].visited = true;
                } else {
                    break;
                }
            }
            // Start going right.
            nextnode = j;
            while (true) {
                nextnode = lst[nextnode].nextid;
                if (nextnode == n+1) break;
                if (lst[nextnode].val <= i) {
                    lst[j].nextid = lst[nextnode].nextid;
                    lst[lst[j].nextid].previd = j;
                    lst[j].tetwidth += lst[nextnode].tetwidth;
                    ctns += lst[nextnode].contains;
                    ctns %= M;
                    lst[nextnode].visited = true;
                } else {
                    break;
                }
            }
            
            // Calculate my contents
            int64_t basecontents = tet(lst[j].tetwidth);
            lst[j].contains = basecontents;
            int64_t tosub = basecontents - ctns;
            if (tosub < 0) tosub = M + tosub;
            ans = (ans + tosub * i) % M;
            //cout << i << " " << j << " " << ans << endl;
        }
        if (lst[lst[0].nextid].val == i || lst[lst[n+1].previd].val == i) {
            int64_t ni = 0;
            while (ni != n+1 && lst[lst[ni].nextid].val <= i) {
                leftextent += lst[lst[ni].nextid].tetwidth - 1LL;
                ni = lst[ni].nextid;
            }
            ni = n+1;
            while (ni != 0 && lst[lst[ni].previd].val <= i) {
                rightextent += lst[lst[ni].previd].tetwidth;
                ni = lst[ni].previd;
            }
            int64_t rect = rectthingy(leftextent, rightextent);
            if (1) {
                //cout << i << " " << rect << endl;
                ans = (ans + ((rect - rectsofar)%M) * i) % M;
                rectsofar = max(rectsofar, rect);
            }
        }
    }
    
    int64_t torem = rectsofar;
    int64_t nn = lst[0].nextid;
    
    while (nn != n + 1) {
        //cerr << nn << endl;
        if (lst[nn].val < mx) torem = (torem + lst[nn].contains) % M;
        nn = lst[nn].nextid;
    }
    
    int64_t base = tri(tri(n)%M)%M;
    //cerr << base << endl;
    //cerr << torem << endl;
    base = (base - torem) % M;
    //cerr << base << endl;
    base = (M + base) % M;
    ans = (ans + base * mx) % M;
    
    cout << ans << endl;
    
    return 0;
}