// Arup Guha
// 6/22/2020
// Solution to 2019 February USACO Silver Problem: Triangles

import java.util.*;
import java.io.*;

public class triangles {
	
	final public static long MOD = 1000000007L;
	final public static int OFFSET = 10000;
	final public static int MAX = 10000;
	
	public static void main(String[] args) throws Exception {
		
		// Get # of points.
		BufferedReader stdin = new BufferedReader(new FileReader("triangles.in"));
		int n = Integer.parseInt(stdin.readLine());
		
		// Store points in two ways, by x coordinate and y.
		ArrayList[] listX = new ArrayList[OFFSET+MAX+1];
		for (int i=0; i<listX.length; i++) listX[i] = new ArrayList<Integer>();
		ArrayList[] listY = new ArrayList[OFFSET+MAX+1];
		for (int i=0; i<listY.length; i++) listY[i] = new ArrayList<Integer>();
		
		// Read through each point. In the x list, store y. In the y list store x.
		for (int i=0; i<n; i++) {
			StringTokenizer tok = new StringTokenizer(stdin.readLine());
			int x = Integer.parseInt(tok.nextToken()) + OFFSET;
			int y = Integer.parseInt(tok.nextToken()) + OFFSET;
			listX[x].add(y);
			listY[y].add(x);
		}
		
		// Sort the y's matched to each x.
		for (int i=0; i<listX.length; i++)
			if (listX[i].size() > 0)
				Collections.sort(listX[i]);
		
		// Sort the x's matched to each y.
		for (int i=0; i<listY.length; i++)
			if (listY[i].size() > 0)
				Collections.sort(listY[i]);
		
		// Bookkeepping for our sweep. sumX is running sum of X's for each y.
		long[] sumX = new long[OFFSET+MAX+1];
		
		// This stores the current index into the listY arrays.
		int[] curIdx = new int[OFFSET+MAX+1];
		
		// For each y value, we need to precompute the sum of x's for it.
		for (int y=0; y<listY.length; y++) {
			
			// Skip lists of size 0 or 1.
			if (listY[y].size() < 2) continue;
			
			// Sum of the delta x's from base x, for this y.
			int base = (Integer)(listY[y].get(0));
			for (int i=1; i<listY[y].size(); i++)
				sumX[y] += ((Integer)(listY[y].get(i)) - base);
			sumX[y] = sumX[y]%MOD;
		}
		
		// Add up answer here.
		long res = 0;
		
		// Go through x list.
		for (int x=0; x<listX.length; x++) {

			// Stores # of y's for this x.
			int len = listX[x].size();
			
			// Skip lists of size 0.
			if (len < 1) continue;
			
			// Min y value in this list.
			int base = (Integer)(listX[x].get(0));
			
			// Sum of delta Y for this x.
			long sumY = 0;
			for (int j=1; j<len; j++)
				sumY += ( (Integer)(listX[x].get(j)) - base);
			sumY = sumY%MOD;
			
			// This loops through the valid specific y's for this x.
			for (int j=0; j<len; j++) {
				
				// our y value here.
				int y = (Integer)(listX[x].get(j));
				
				// All of these triangles.
				res = (res + sumX[y]*sumY)%MOD;
				
				// Difference in y, for advancing sumY.
				long diffy = 0;
				if (j < len-1)
					diffy = (Integer)(listX[x].get(j+1)) - (Integer)(listX[x].get(j));
				
				// This is how sumY gets affected.
				sumY = sumY + diffy*(2*(j + 1) - len);
				sumY = sumY%MOD;
				
				// Length of list of x's corresponding to THIS y.
				int lenX = listY[y].size();
				
				// Index we are at in this list of x's.
				int idx = curIdx[y];
				
				// Difference in x for advancing sumX[y].
				long diffx = 0;
				if (idx < lenX-1)
					diffx = (Integer)(listY[y].get(idx+1)) - (Integer)(listY[y].get(idx));
				
				// This is how sumX changes for next time we get to it.
				sumX[y] = sumX[y] + diffx*(2*(idx+1) - lenX);
				sumX[y] = sumX[y]%MOD;
				
				// We can advance this now.
				curIdx[y]++;
			}
		}
		
		// Output to file.
		PrintWriter out = new PrintWriter(new FileWriter("triangles.out"));
		out.println(res);
		out.close();		
		stdin.close();
	}
}