#include <bits/stdc++.h>
using namespace std;
static const long long int mod = 1000000007;
struct Interval {
  long long int start, end;
  bool include(const Interval &other) const {
    return start <= other.start && end >= other.end;
  }
  bool operator==(Interval &other) const {
    return start == other.start && end == other.end;
  }
  long long int size() const { return end - start + 1; }
};
class STNode {
 private:
  long long int toBeAdded;
  long long int sum;
  Interval interval{};
  STNode *left, *right;

 public:
  STNode(STNode *lt, STNode *rt) : toBeAdded(0), left(lt), right(rt) {
    interval.start = lt->interval.start;
    interval.end = rt->interval.end;
    sum = lt->sum + rt->sum;
  }
  explicit STNode(Interval range, long long int value = 0)
      : toBeAdded(0),
        interval(range),
        sum(value),
        left(nullptr),
        right(nullptr) {}
  ~STNode() {
    delete left;
    delete right;
  }
  void addValue(Interval range, long long int d) {
    if (range == interval) {
      toBeAdded += d;
    } else if (left->interval.include(range)) {
      sum += d * range.size();
      left->addValue(range, d);
    } else if (right->interval.include(range)) {
      sum += d * range.size();
      right->addValue(range, d);
    } else {
      Interval leftPart{range.start, left->interval.end};
      Interval rightPart{right->interval.start, range.end};
      sum += d * range.size();
      left->addValue(leftPart, d);
      right->addValue(rightPart, d);
    }
  }
  long long int getSum(Interval range) {
    if (range == interval) {
      return sum + toBeAdded * interval.size();
    } else {
      sum += toBeAdded * interval.size();
      left->toBeAdded += toBeAdded;
      right->toBeAdded += toBeAdded;
      toBeAdded = 0;
      if (left->interval.include(range)) {
        return left->getSum(range);
      } else if (right->interval.include(range)) {
        return right->getSum(range);
      } else {
        Interval leftPart{range.start, left->interval.end};
        Interval rightPart{right->interval.start, range.end};
        return left->getSum(leftPart) + right->getSum(rightPart);
      }
    }
  }
};
class SegmentTree {
 private:
  long long int n;
  STNode *root;

 public:
  explicit SegmentTree(long long int n) : n(n) {
    STNode **temp[2];
    long long int count[2];
    temp[0] = new STNode *[n + 1];
    temp[1] = new STNode *[n + 1];
    long long int curVec, nextVec;
    curVec = 0;
    nextVec = 1 - curVec;
    count[curVec] = n;
    count[nextVec] = 0;
    for (long long int i = 1; i <= n; ++i) {
      STNode *newNode = new STNode(Interval{i, i});
      temp[curVec][i] = newNode;
    }
    while (count[curVec] > 1) {
      int front = 1;
      count[nextVec] = 0;
      while (front + 1 <= count[curVec]) {
        STNode *left, *right, *newNode;
        left = temp[curVec][front++];
        right = temp[curVec][front++];
        newNode = new STNode(left, right);
        temp[nextVec][++count[nextVec]] = newNode;
      }
      if (front == count[curVec]) {
        STNode *newNode;
        newNode = temp[curVec][front];
        temp[nextVec][++count[nextVec]] = newNode;
      }
      curVec = nextVec;
      nextVec = 1 - curVec;
    }
    root = temp[curVec][1];
    delete[] temp[0];
    delete[] temp[1];
  }
  ~SegmentTree() { delete root; }
  long long int getSum(long long int l, long long int r) const {
    if (l > r || l < 1 || r > n) {
      return 0;
    }
    return root->getSum(Interval{l, r});
  }
  void rangeAdd(long long int l, long long int r, long long int d) const {
    if (l > r || l < 1 || r > n) {
      return;
    }
    root->addValue(Interval{l, r}, d);
  }
};
int main() {
  long long int n;
  cin >> n;
  long long int *a = new long long int[n + 1];
  for (long long int i = 1; i <= n; ++i) {
    scanf("%lld", &a[i]);
  }
  map<long long int, long long int> pos;
  for (long long int i = 1; i <= n; ++i) {
    pos[a[i]] = i;
  }
  delete[] a;
  SegmentTree L(n);
  long long int sum = 0;
  long long int filledCnt = 0;
  long long int total = 0;
  long long int val, index, pivot, SL, RWidth, SR, ROffset;
  for (auto &&iter : pos) {
    val = iter.first;
    index = iter.second;
    pivot = L.getSum(index, index);
    SL = L.getSum(1, index);
    RWidth = n - index + 1;
    SR = RWidth * filledCnt - total + SL;
    ROffset = filledCnt - pivot;
    SL = SL - index * pivot;
    SR = SR - RWidth * ROffset + RWidth;
    sum = (sum + val * ((index * SR + RWidth * SL) % mod)) % mod;
    L.rangeAdd(1, index, 1);
    ++filledCnt;
    total += index;
  }
  cout << sum << endl;
  return 0;
}
