Type: INTEGER (long)
+ */ + public static final String ID = "_id"; + + /** + * The parent's id for note or folder + *Type: INTEGER (long)
+ */ + public static final String PARENT_ID = "parent_id"; + + /** + * Created date for note or folder + *Type: INTEGER (long)
+ */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *Type: INTEGER (long)
+ */ + public static final String MODIFIED_DATE = "modified_date"; + + + /** + * Alert date + *Type: INTEGER (long)
+ */ + public static final String ALERTED_DATE = "alert_date"; + + /** + * Folder's name or text content of note + *Type: TEXT
+ */ + public static final String SNIPPET = "snippet"; + + /** + * Note's widget id + *Type: INTEGER (long)
+ */ + public static final String WIDGET_ID = "widget_id"; + + /** + * Note's widget type + *Type: INTEGER (long)
+ */ + public static final String WIDGET_TYPE = "widget_type"; + + /** + * Note's background color's id + *Type: INTEGER (long)
+ */ + public static final String BG_COLOR_ID = "bg_color_id"; + + /** + * For text note, it doesn't has attachment, for multi-media + * note, it has at least one attachment + *Type: INTEGER
+ */ + public static final String HAS_ATTACHMENT = "has_attachment"; + + /** + * Folder's count of notes + *Type: INTEGER (long)
+ */ + public static final String NOTES_COUNT = "notes_count"; + + /** + * The file type: folder or note + *Type: INTEGER
+ */ + public static final String TYPE = "type"; + + /** + * The last sync id + *Type: INTEGER (long)
+ */ + public static final String SYNC_ID = "sync_id"; + + /** + * Sign to indicate local modified or not + *Type: INTEGER
+ */ + public static final String LOCAL_MODIFIED = "local_modified"; + + /** + * Original parent id before moving into temporary folder + *Type : INTEGER
+ */ + public static final String ORIGIN_PARENT_ID = "origin_parent_id"; + + /** + * The gtask id + *Type : TEXT
+ */ + public static final String GTASK_ID = "gtask_id"; + + /** + * The version code + *Type : INTEGER (long)
+ */ + public static final String VERSION = "version"; + } + + public interface DataColumns { + /** + * The unique ID for a row + *Type: INTEGER (long)
+ */ + public static final String ID = "_id"; + + /** + * The MIME type of the item represented by this row. + *Type: Text
+ */ + public static final String MIME_TYPE = "mime_type"; + + /** + * The reference id to note that this data belongs to + *Type: INTEGER (long)
+ */ + public static final String NOTE_ID = "note_id"; + + /** + * Created data for note or folder + *Type: INTEGER (long)
+ */ + public static final String CREATED_DATE = "created_date"; + + /** + * Latest modified date + *Type: INTEGER (long)
+ */ + public static final String MODIFIED_DATE = "modified_date"; + + /** + * Data's content + *Type: TEXT
+ */ + public static final String CONTENT = "content"; + + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *Type: INTEGER
+ */ + public static final String DATA1 = "data1"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * integer data type + *Type: INTEGER
+ */ + public static final String DATA2 = "data2"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *Type: TEXT
+ */ + public static final String DATA3 = "data3"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *Type: TEXT
+ */ + public static final String DATA4 = "data4"; + + /** + * Generic data column, the meaning is {@link #MIMETYPE} specific, used for + * TEXT data type + *Type: TEXT
+ */ + public static final String DATA5 = "data5"; + } + + public static final class TextNote implements DataColumns { + /** + * Mode to indicate the text in check list mode or not + *Type: Integer 1:check list mode 0: normal mode
+ */ + public static final String MODE = DATA1; + + public static final int MODE_CHECK_LIST = 1; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/text_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/text_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/text_note"); + } + + public static final class CallNote implements DataColumns { + /** + * Call date for this record + *Type: INTEGER (long)
+ */ + public static final String CALL_DATE = DATA1; + + /** + * Phone number for this record + *Type: TEXT
+ */ + public static final String PHONE_NUMBER = DATA3; + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/call_note"; + + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/call_note"; + + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/call_note"); + } + + + /** + * author: FeilongZuo + * AttachMent of Note + + */ + public static final class AttachMentNote implements DataColumns { + + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/attachment_note"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/attachment_note"; + public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/attachment_note"); + + } +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java b/MiNote-master/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java new file mode 100644 index 00000000..cf62d38b --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/data/NotesDatabaseHelper.java @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.data; + +import android.content.ContentValues; +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; + + +public class NotesDatabaseHelper extends SQLiteOpenHelper { + private static final String DB_NAME = "note.db"; + + private static final int DB_VERSION = 4; + + public interface TABLE { + public static final String NOTE = "note"; + + public static final String DATA = "data"; + } + + private static final String TAG = "NotesDatabaseHelper"; + + private static NotesDatabaseHelper mInstance; + + + /* + author:feilongzuo + 便签基础数据表 + 1.ID + 2.父ID(floder) + 3.提醒日期 + 4.背景颜色id + 5.创建时间 + 6.是否有附件 + 7.更改日期 + 8.(文件夹)所含note数量 + 9.文本内容 + 10.类型(文件夹还是note) + 11.装饰id + 12.装饰类型 + 13.同步id + 14. + 15. + 16. + 17. + */ + private static final String CREATE_NOTE_TABLE_SQL = + "CREATE TABLE " + TABLE.NOTE + "(" + + NoteColumns.ID + " INTEGER PRIMARY KEY," + + NoteColumns.PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ALERTED_DATE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.BG_COLOR_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.HAS_ATTACHMENT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.NOTES_COUNT + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.SNIPPET + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.TYPE + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.WIDGET_TYPE + " INTEGER NOT NULL DEFAULT -1," + + NoteColumns.SYNC_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.LOCAL_MODIFIED + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.ORIGIN_PARENT_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.GTASK_ID + " TEXT NOT NULL DEFAULT ''," + + NoteColumns.VERSION + " INTEGER NOT NULL DEFAULT 0" + + ")"; + + /* + 创建数据表SQL + 1.id + 2. + 3.附属的note id + 4. + 5. + 6. + 7 + 8 + 9 + 10 + */ + private static final String CREATE_DATA_TABLE_SQL = + "CREATE TABLE " + TABLE.DATA + "(" + + DataColumns.ID + " INTEGER PRIMARY KEY," + + DataColumns.MIME_TYPE + " TEXT NOT NULL," + + DataColumns.NOTE_ID + " INTEGER NOT NULL DEFAULT 0," + + NoteColumns.CREATED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + NoteColumns.MODIFIED_DATE + " INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000)," + + DataColumns.CONTENT + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA1 + " INTEGER," + + DataColumns.DATA2 + " INTEGER," + + DataColumns.DATA3 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA4 + " TEXT NOT NULL DEFAULT ''," + + DataColumns.DATA5 + " TEXT NOT NULL DEFAULT ''" + + ")"; + + /* + note id和data id映射 + */ + private static final String CREATE_DATA_NOTE_ID_INDEX_SQL = + "CREATE INDEX IF NOT EXISTS note_id_index ON " + + TABLE.DATA + "(" + DataColumns.NOTE_ID + ");"; + + /** + * Increase folder's note count when move note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_update "+ + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when move note from folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_update " + + " AFTER UPDATE OF " + NoteColumns.PARENT_ID + " ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0" + ";" + + " END"; + + /** + * Increase folder's note count when insert new note to the folder + */ + private static final String NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER = + "CREATE TRIGGER increase_folder_count_on_insert " + + " AFTER INSERT ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + " + 1" + + " WHERE " + NoteColumns.ID + "=new." + NoteColumns.PARENT_ID + ";" + + " END"; + + /** + * Decrease folder's note count when delete note from the folder + */ + private static final String NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER = + "CREATE TRIGGER decrease_folder_count_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN " + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.NOTES_COUNT + "=" + NoteColumns.NOTES_COUNT + "-1" + + " WHERE " + NoteColumns.ID + "=old." + NoteColumns.PARENT_ID + + " AND " + NoteColumns.NOTES_COUNT + ">0;" + + " END"; + + /** + * Update note's content when insert data with type {@link DataConstants#NOTE} + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER = + "CREATE TRIGGER update_note_content_on_insert " + + " AFTER INSERT ON " + TABLE.DATA + + " WHEN new." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has changed + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER = + "CREATE TRIGGER update_note_content_on_update " + + " AFTER UPDATE ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=new." + DataColumns.CONTENT + + " WHERE " + NoteColumns.ID + "=new." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Update note's content when data with {@link DataConstants#NOTE} type has deleted + */ + private static final String DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER = + "CREATE TRIGGER update_note_content_on_delete " + + " AFTER delete ON " + TABLE.DATA + + " WHEN old." + DataColumns.MIME_TYPE + "='" + DataConstants.NOTE + "'" + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.SNIPPET + "=''" + + " WHERE " + NoteColumns.ID + "=old." + DataColumns.NOTE_ID + ";" + + " END"; + + /** + * Delete datas belong to note which has been deleted + */ + private static final String NOTE_DELETE_DATA_ON_DELETE_TRIGGER = + "CREATE TRIGGER delete_data_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.DATA + + " WHERE " + DataColumns.NOTE_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Delete notes belong to folder which has been deleted + */ + private static final String FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER = + "CREATE TRIGGER folder_delete_notes_on_delete " + + " AFTER DELETE ON " + TABLE.NOTE + + " BEGIN" + + " DELETE FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + /** + * Move notes belong to folder which has been moved to trash folder + */ + private static final String FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER = + "CREATE TRIGGER folder_move_notes_on_trash " + + " AFTER UPDATE ON " + TABLE.NOTE + + " WHEN new." + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " BEGIN" + + " UPDATE " + TABLE.NOTE + + " SET " + NoteColumns.PARENT_ID + "=" + Notes.ID_TRASH_FOLER + + " WHERE " + NoteColumns.PARENT_ID + "=old." + NoteColumns.ID + ";" + + " END"; + + public NotesDatabaseHelper(Context context) { + super(context, DB_NAME, null, DB_VERSION); + } + + public void createNoteTable(SQLiteDatabase db) { + db.execSQL(CREATE_NOTE_TABLE_SQL); + reCreateNoteTableTriggers(db); + createSystemFolder(db); + Log.d(TAG, "note table has been created"); + } + + private void reCreateNoteTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS decrease_folder_count_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS delete_data_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS increase_folder_count_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS folder_delete_notes_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS folder_move_notes_on_trash"); + + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_UPDATE_TRIGGER); + db.execSQL(NOTE_DECREASE_FOLDER_COUNT_ON_DELETE_TRIGGER); + db.execSQL(NOTE_DELETE_DATA_ON_DELETE_TRIGGER); + db.execSQL(NOTE_INCREASE_FOLDER_COUNT_ON_INSERT_TRIGGER); + db.execSQL(FOLDER_DELETE_NOTES_ON_DELETE_TRIGGER); + db.execSQL(FOLDER_MOVE_NOTES_ON_TRASH_TRIGGER); + } + + private void createSystemFolder(SQLiteDatabase db) { + ContentValues values = new ContentValues(); + + /** + * call record foler for call notes + */ + values.put(NoteColumns.ID, Notes.ID_CALL_RECORD_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * root folder which is default folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_ROOT_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * temporary folder which is used for moving note + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TEMPARAY_FOLDER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + + /** + * create trash folder + */ + values.clear(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + public void createDataTable(SQLiteDatabase db) { + db.execSQL(CREATE_DATA_TABLE_SQL); + reCreateDataTableTriggers(db); + db.execSQL(CREATE_DATA_NOTE_ID_INDEX_SQL); + Log.d(TAG, "data table has been created"); + } + + private void reCreateDataTableTriggers(SQLiteDatabase db) { + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_update"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_content_on_delete"); + + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_INSERT_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_UPDATE_TRIGGER); + db.execSQL(DATA_UPDATE_NOTE_CONTENT_ON_DELETE_TRIGGER); + } + + static synchronized NotesDatabaseHelper getInstance(Context context) { + if (mInstance == null) { + mInstance = new NotesDatabaseHelper(context); + } + return mInstance; + } + + @Override + public void onCreate(SQLiteDatabase db) { + createNoteTable(db); + createDataTable(db); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + boolean reCreateTriggers = false; + boolean skipV2 = false; + + if (oldVersion == 1) { + upgradeToV2(db); + skipV2 = true; // this upgrade including the upgrade from v2 to v3 + oldVersion++; + } + + if (oldVersion == 2 && !skipV2) { + upgradeToV3(db); + reCreateTriggers = true; + oldVersion++; + } + + if (oldVersion == 3) { + upgradeToV4(db); + oldVersion++; + } + + if (reCreateTriggers) { + reCreateNoteTableTriggers(db); + reCreateDataTableTriggers(db); + } + + if (oldVersion != newVersion) { + throw new IllegalStateException("Upgrade notes database to version " + newVersion + + "fails"); + } + } + + private void upgradeToV2(SQLiteDatabase db) { + db.execSQL("DROP TABLE IF EXISTS " + TABLE.NOTE); + db.execSQL("DROP TABLE IF EXISTS " + TABLE.DATA); + createNoteTable(db); + createDataTable(db); + } + + private void upgradeToV3(SQLiteDatabase db) { + // drop unused triggers + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_insert"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_delete"); + db.execSQL("DROP TRIGGER IF EXISTS update_note_modified_date_on_update"); + // add a column for gtask id + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.GTASK_ID + + " TEXT NOT NULL DEFAULT ''"); + // add a trash system folder + ContentValues values = new ContentValues(); + values.put(NoteColumns.ID, Notes.ID_TRASH_FOLER); + values.put(NoteColumns.TYPE, Notes.TYPE_SYSTEM); + db.insert(TABLE.NOTE, null, values); + } + + private void upgradeToV4(SQLiteDatabase db) { + db.execSQL("ALTER TABLE " + TABLE.NOTE + " ADD COLUMN " + NoteColumns.VERSION + + " INTEGER NOT NULL DEFAULT 0"); + } +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/data/NotesProvider.java b/MiNote-master/app/src/main/java/net/micode/notes/data/NotesProvider.java new file mode 100644 index 00000000..edb0a606 --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/data/NotesProvider.java @@ -0,0 +1,305 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.data; + + +import android.app.SearchManager; +import android.content.ContentProvider; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.net.Uri; +import android.text.TextUtils; +import android.util.Log; + +import net.micode.notes.R; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.data.NotesDatabaseHelper.TABLE; + + +public class NotesProvider extends ContentProvider { + private static final UriMatcher mMatcher; + + private NotesDatabaseHelper mHelper; + + private static final String TAG = "NotesProvider"; + + private static final int URI_NOTE = 1; + private static final int URI_NOTE_ITEM = 2; + private static final int URI_DATA = 3; + private static final int URI_DATA_ITEM = 4; + + private static final int URI_SEARCH = 5; + private static final int URI_SEARCH_SUGGEST = 6; + + static { + mMatcher = new UriMatcher(UriMatcher.NO_MATCH); + mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); + mMatcher.addURI(Notes.AUTHORITY, "note/#", URI_NOTE_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "data", URI_DATA); + mMatcher.addURI(Notes.AUTHORITY, "data/#", URI_DATA_ITEM); + mMatcher.addURI(Notes.AUTHORITY, "search", URI_SEARCH); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, URI_SEARCH_SUGGEST); + mMatcher.addURI(Notes.AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", URI_SEARCH_SUGGEST); + } + + /** + * x'0A' represents the '\n' character in sqlite. For title and content in the search result, + * we will trim '\n' and white space in order to show more information. + */ + private static final String NOTES_SEARCH_PROJECTION = NoteColumns.ID + "," + + NoteColumns.ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_1 + "," + + "TRIM(REPLACE(" + NoteColumns.SNIPPET + ", x'0A','')) AS " + SearchManager.SUGGEST_COLUMN_TEXT_2 + "," + + R.drawable.search_result + " AS " + SearchManager.SUGGEST_COLUMN_ICON_1 + "," + + "'" + Intent.ACTION_VIEW + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_ACTION + "," + + "'" + Notes.TextNote.CONTENT_TYPE + "' AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA; + + private static String NOTES_SNIPPET_SEARCH_QUERY = "SELECT " + NOTES_SEARCH_PROJECTION + + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.SNIPPET + " LIKE ?" + + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + + @Override + public boolean onCreate() { + mHelper = NotesDatabaseHelper.getInstance(getContext()); + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + Cursor c = null; + SQLiteDatabase db = mHelper.getReadableDatabase(); + String id = null; + switch (mMatcher.match(uri)) { + case URI_NOTE: + c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.NOTE, projection, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_DATA: + c = db.query(TABLE.DATA, projection, selection, selectionArgs, null, null, + sortOrder); + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + c = db.query(TABLE.DATA, projection, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs, null, null, sortOrder); + break; + case URI_SEARCH: + case URI_SEARCH_SUGGEST: + if (sortOrder != null || projection != null) { + throw new IllegalArgumentException( + "do not specify sortOrder, selection, selectionArgs, or projection" + "with this query"); + } + + String searchString = null; + if (mMatcher.match(uri) == URI_SEARCH_SUGGEST) { + if (uri.getPathSegments().size() > 1) { + searchString = uri.getPathSegments().get(1); + } + } else { + searchString = uri.getQueryParameter("pattern"); + } + + if (TextUtils.isEmpty(searchString)) { + return null; + } + + try { + searchString = String.format("%%%s%%", searchString); + c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, + new String[] { searchString }); + } catch (IllegalStateException ex) { + Log.e(TAG, "got exception: " + ex.toString()); + } + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (c != null) { + c.setNotificationUri(getContext().getContentResolver(), uri); + } + return c; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + SQLiteDatabase db = mHelper.getWritableDatabase(); + long dataId = 0, noteId = 0, insertedId = 0; + switch (mMatcher.match(uri)) { + case URI_NOTE: + insertedId = noteId = db.insert(TABLE.NOTE, null, values); + break; + case URI_DATA: + if (values.containsKey(DataColumns.NOTE_ID)) { + noteId = values.getAsLong(DataColumns.NOTE_ID); + } else { + Log.d(TAG, "Wrong data format without note id:" + values.toString()); + } + insertedId = dataId = db.insert(TABLE.DATA, null, values); + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + // Notify the note uri + if (noteId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, noteId), null); + } + + // Notify the data uri + if (dataId > 0) { + getContext().getContentResolver().notifyChange( + ContentUris.withAppendedId(Notes.CONTENT_DATA_URI, dataId), null); + } + + return ContentUris.withAppendedId(uri, insertedId); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean deleteData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + selection = "(" + selection + ") AND " + NoteColumns.ID + ">0 "; + count = db.delete(TABLE.NOTE, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + /** + * ID that smaller than 0 is system folder which is not allowed to + * trash + */ + long noteId = Long.valueOf(id); + if (noteId <= 0) { + break; + } + count = db.delete(TABLE.NOTE, + NoteColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.delete(TABLE.DATA, selection, selectionArgs); + deleteData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.delete(TABLE.DATA, + DataColumns.ID + "=" + id + parseSelection(selection), selectionArgs); + deleteData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + if (count > 0) { + if (deleteData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + int count = 0; + String id = null; + SQLiteDatabase db = mHelper.getWritableDatabase(); + boolean updateData = false; + switch (mMatcher.match(uri)) { + case URI_NOTE: + increaseNoteVersion(-1, selection, selectionArgs); + count = db.update(TABLE.NOTE, values, selection, selectionArgs); + break; + case URI_NOTE_ITEM: + id = uri.getPathSegments().get(1); + increaseNoteVersion(Long.valueOf(id), selection, selectionArgs); + count = db.update(TABLE.NOTE, values, NoteColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + break; + case URI_DATA: + count = db.update(TABLE.DATA, values, selection, selectionArgs); + updateData = true; + break; + case URI_DATA_ITEM: + id = uri.getPathSegments().get(1); + count = db.update(TABLE.DATA, values, DataColumns.ID + "=" + id + + parseSelection(selection), selectionArgs); + updateData = true; + break; + default: + throw new IllegalArgumentException("Unknown URI " + uri); + } + + if (count > 0) { + if (updateData) { + getContext().getContentResolver().notifyChange(Notes.CONTENT_NOTE_URI, null); + } + getContext().getContentResolver().notifyChange(uri, null); + } + return count; + } + + private String parseSelection(String selection) { + return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); + } + + private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { + StringBuilder sql = new StringBuilder(120); + sql.append("UPDATE "); + sql.append(TABLE.NOTE); + sql.append(" SET "); + sql.append(NoteColumns.VERSION); + sql.append("=" + NoteColumns.VERSION + "+1 "); + + if (id > 0 || !TextUtils.isEmpty(selection)) { + sql.append(" WHERE "); + } + if (id > 0) { + sql.append(NoteColumns.ID + "=" + String.valueOf(id)); + } + if (!TextUtils.isEmpty(selection)) { + String selectString = id > 0 ? parseSelection(selection) : selection; + for (String args : selectionArgs) { + selectString = selectString.replaceFirst("\\?", args); + } + sql.append(selectString); + } + + mHelper.getWritableDatabase().execSQL(sql.toString()); + } + + @Override + public String getType(Uri uri) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/MetaData.java b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/MetaData.java new file mode 100644 index 00000000..3a2050b0 --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/MetaData.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.gtask.data; + +import android.database.Cursor; +import android.util.Log; + +import net.micode.notes.tool.GTaskStringUtils; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class MetaData extends Task { + private final static String TAG = MetaData.class.getSimpleName(); + + private String mRelatedGid = null; + + public void setMeta(String gid, JSONObject metaInfo) { + try { + metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); + } catch (JSONException e) { + Log.e(TAG, "failed to put related gid"); + } + setNotes(metaInfo.toString()); + setName(GTaskStringUtils.META_NOTE_NAME); + } + + public String getRelatedGid() { + return mRelatedGid; + } + + @Override + public boolean isWorthSaving() { + return getNotes() != null; + } + + @Override + public void setContentByRemoteJSON(JSONObject js) { + super.setContentByRemoteJSON(js); + if (getNotes() != null) { + try { + JSONObject metaInfo = new JSONObject(getNotes().trim()); + mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); + } catch (JSONException e) { + Log.w(TAG, "failed to get related gid"); + mRelatedGid = null; + } + } + } + + @Override + public void setContentByLocalJSON(JSONObject js) { + // this function should not be called + throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); + } + + @Override + public JSONObject getLocalJSONFromContent() { + throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); + } + + @Override + public int getSyncAction(Cursor c) { + throw new IllegalAccessError("MetaData:getSyncAction should not be called"); + } + +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/Node.java b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/Node.java new file mode 100644 index 00000000..93344903 --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/Node.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.gtask.data; + +import android.database.Cursor; + +import org.json.JSONObject; + +public abstract class Node { + public static final int SYNC_ACTION_NONE = 0; + + public static final int SYNC_ACTION_ADD_REMOTE = 1; + + public static final int SYNC_ACTION_ADD_LOCAL = 2; + + public static final int SYNC_ACTION_DEL_REMOTE = 3; + + public static final int SYNC_ACTION_DEL_LOCAL = 4; + + private String mGid; + + private String mName; + + private long mLastModified; + + private boolean mDeleted; + + public Node() { + mGid = null; + mName = ""; + mLastModified = 0; + mDeleted = false; + } + + public abstract JSONObject getCreateAction(int actionId); + + public abstract JSONObject getUpdateAction(int actionId); + + public abstract void setContentByRemoteJSON(JSONObject js); + + public abstract void setContentByLocalJSON(JSONObject js); + + public abstract JSONObject getLocalJSONFromContent(); + + public abstract int getSyncAction(Cursor c); + + public void setGid(String gid) { + this.mGid = gid; + } + + public void setName(String name) { + this.mName = name; + } + + public void setLastModified(long lastModified) { + this.mLastModified = lastModified; + } + + public void setDeleted(boolean deleted) { + this.mDeleted = deleted; + } + + public String getGid() { + return this.mGid; + } + + public String getName() { + return this.mName; + } + + public long getLastModified() { + return this.mLastModified; + } + + public boolean getDeleted() { + return this.mDeleted; + } + +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlData.java b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlData.java new file mode 100644 index 00000000..d3ec3be1 --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlData.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.gtask.data; + +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.DataConstants; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.data.NotesDatabaseHelper.TABLE; +import net.micode.notes.gtask.exception.ActionFailureException; + +import org.json.JSONException; +import org.json.JSONObject; + + +public class SqlData { + private static final String TAG = SqlData.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_DATA = new String[] { + DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, + DataColumns.DATA3 + }; + + public static final int DATA_ID_COLUMN = 0; + + public static final int DATA_MIME_TYPE_COLUMN = 1; + + public static final int DATA_CONTENT_COLUMN = 2; + + public static final int DATA_CONTENT_DATA_1_COLUMN = 3; + + public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mDataId; + + private String mDataMimeType; + + private String mDataContent; + + private long mDataContentData1; + + private String mDataContentData3; + + private ContentValues mDiffDataValues; + + public SqlData(Context context) { + mContentResolver = context.getContentResolver(); + mIsCreate = true; + mDataId = INVALID_ID; + mDataMimeType = DataConstants.NOTE; + mDataContent = ""; + mDataContentData1 = 0; + mDataContentData3 = ""; + mDiffDataValues = new ContentValues(); + } + + public SqlData(Context context, Cursor c) { + mContentResolver = context.getContentResolver(); + mIsCreate = false; + loadFromCursor(c); + mDiffDataValues = new ContentValues(); + } + + private void loadFromCursor(Cursor c) { + mDataId = c.getLong(DATA_ID_COLUMN); + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); + mDataContent = c.getString(DATA_CONTENT_COLUMN); + mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); + mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); + } + + public void setContent(JSONObject js) throws JSONException { + long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; + if (mIsCreate || mDataId != dataId) { + mDiffDataValues.put(DataColumns.ID, dataId); + } + mDataId = dataId; + + String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) + : DataConstants.NOTE; + if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { + mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); + } + mDataMimeType = dataMimeType; + + String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; + if (mIsCreate || !mDataContent.equals(dataContent)) { + mDiffDataValues.put(DataColumns.CONTENT, dataContent); + } + mDataContent = dataContent; + + long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; + if (mIsCreate || mDataContentData1 != dataContentData1) { + mDiffDataValues.put(DataColumns.DATA1, dataContentData1); + } + mDataContentData1 = dataContentData1; + + String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; + if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { + mDiffDataValues.put(DataColumns.DATA3, dataContentData3); + } + mDataContentData3 = dataContentData3; + } + + public JSONObject getContent() throws JSONException { + if (mIsCreate) { + Log.e(TAG, "it seems that we haven't created this in database yet"); + return null; + } + JSONObject js = new JSONObject(); + js.put(DataColumns.ID, mDataId); + js.put(DataColumns.MIME_TYPE, mDataMimeType); + js.put(DataColumns.CONTENT, mDataContent); + js.put(DataColumns.DATA1, mDataContentData1); + js.put(DataColumns.DATA3, mDataContentData3); + return js; + } + + public void commit(long noteId, boolean validateVersion, long version) { + + if (mIsCreate) { + if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { + mDiffDataValues.remove(DataColumns.ID); + } + + mDiffDataValues.put(DataColumns.NOTE_ID, noteId); + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); + try { + mDataId = Long.valueOf(uri.getPathSegments().get(1)); + } catch (NumberFormatException e) { + Log.e(TAG, "Get note id error :" + e.toString()); + throw new ActionFailureException("create note failed"); + } + } else { + if (mDiffDataValues.size() > 0) { + int result = 0; + if (!validateVersion) { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); + } else { + result = mContentResolver.update(ContentUris.withAppendedId( + Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, + " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE + + " WHERE " + NoteColumns.VERSION + "=?)", new String[] { + String.valueOf(noteId), String.valueOf(version) + }); + } + if (result == 0) { + Log.w(TAG, "there is no update. maybe user updates note when syncing"); + } + } + } + + mDiffDataValues.clear(); + mIsCreate = false; + } + + public long getId() { + return mDataId; + } +} diff --git a/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java new file mode 100644 index 00000000..79a4095e --- /dev/null +++ b/MiNote-master/app/src/main/java/net/micode/notes/gtask/data/SqlNote.java @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.micode.notes.gtask.data; + +import android.appwidget.AppWidgetManager; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.util.Log; + +import net.micode.notes.data.Notes; +import net.micode.notes.data.Notes.DataColumns; +import net.micode.notes.data.Notes.NoteColumns; +import net.micode.notes.gtask.exception.ActionFailureException; +import net.micode.notes.tool.GTaskStringUtils; +import net.micode.notes.tool.ResourceParser; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + + +public class SqlNote { + private static final String TAG = SqlNote.class.getSimpleName(); + + private static final int INVALID_ID = -99999; + + public static final String[] PROJECTION_NOTE = new String[] { + NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, + NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, + NoteColumns.NOTES_COUNT, NoteColumns.PARENT_ID, NoteColumns.SNIPPET, NoteColumns.TYPE, + NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, NoteColumns.SYNC_ID, + NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID, + NoteColumns.VERSION + }; + + public static final int ID_COLUMN = 0; + + public static final int ALERTED_DATE_COLUMN = 1; + + public static final int BG_COLOR_ID_COLUMN = 2; + + public static final int CREATED_DATE_COLUMN = 3; + + public static final int HAS_ATTACHMENT_COLUMN = 4; + + public static final int MODIFIED_DATE_COLUMN = 5; + + public static final int NOTES_COUNT_COLUMN = 6; + + public static final int PARENT_ID_COLUMN = 7; + + public static final int SNIPPET_COLUMN = 8; + + public static final int TYPE_COLUMN = 9; + + public static final int WIDGET_ID_COLUMN = 10; + + public static final int WIDGET_TYPE_COLUMN = 11; + + public static final int SYNC_ID_COLUMN = 12; + + public static final int LOCAL_MODIFIED_COLUMN = 13; + + public static final int ORIGIN_PARENT_ID_COLUMN = 14; + + public static final int GTASK_ID_COLUMN = 15; + + public static final int VERSION_COLUMN = 16; + + private Context mContext; + + private ContentResolver mContentResolver; + + private boolean mIsCreate; + + private long mId; + + private long mAlertDate; + + private int mBgColorId; + + private long mCreatedDate; + + private int mHasAttachment; + + private long mModifiedDate; + + private long mParentId; + + private String mSnippet; + + private int mType; + + private int mWidgetId; + + private int mWidgetType; + + private long mOriginParent; + + private long mVersion; + + private ContentValues mDiffNoteValues; + + private ArrayListZ7p4?E#Zy(kAaqu=FDNQ3{z((TJp-0T@6A=s1$kr2vv-r!Xw$UQY7%ly#j&WC4I9 z1Hb~315&_*%?trBBj!&dc~;8WmJ^Y541nk3a2xdQB)>=j6GRRJ@LJ5DN%G{BwJjx5 zV&J!tydniiHb;^@*sS sw9aIsiAu!9P0QhA|)Q@bdq+tjuo~S+l^%z$-T ehp*VRO30~i#CE+u(D zkXRSMCjjipEH{%JQ-jDf$C? -3#{%hMX=#yg1`PHE{p45c^?u#+IYP;-8E|w}CA|k1H<0DB<4ibj| zSR6oXxV=f*R;onOreWazYZ*W?a}23GI%Xr1o(7NwEEhz3l3XRpmEQ*ddIpj^NnTb% z8+Nbf#MnHNF1#ut$x(d;NuSfMG_4Uy`5X5keMwd{AjzP!9O)N(ERr_hqBimd?iyuR zlHbH0rvi8~792}5%N9xrHAST4#%GW`B>=dL{Sv^&aiUZA=_Mq5cHY3plN=j+c&+!y zN@54m$J$d#vqUb5LdbhNa@(cawOShneOes)7D?awY9eVkfGIKHwcSWsE8fE%>(UrA zp`P`OzhNShiZ?!nWF<}%Vu9ny-XxcmXrpN0gGpBMD@nF1+n4Rk(x2qQb`7MNfG8;+ zef^%Tjg|4--p<8>$s|YC(8m1$&X2LhB>QIbB-zevf0kJ!-MFYL4QZrs zB^mTpF_vWDd6G#)N}}&Xl9fXx?GTZ9E&puCz>6+*1WDKD-ou%(qrUStOOk;%Lu4F) zijN0SmBC7K1?Qs4@+`?Lx2k#-g@VbMu`}dKYe-VQ#-B?vD+f|vR{a!3()s|LPHz;u zR#k11oG?0Zw6xuF9zlsqJ& 3&vG8+n)dI7yehCQ)qSm99@Al|m$67`4?JIU;WLyd1y3w?`uRQw^e3 z1(PJ#_pb9T)`GQBiSCU`3X!`3jEap{YX*c{cJ%HYbAA9|tvE&u1>p8hCT$J3k{bVL zk}oz&Ae)~;#D<);WZF`R{DG3(qjj^oz0U?q0Q4jIZ#*k!v+jXe=93)QED5hmA#yK( zi{g->B%dlfP*M+jtz3$dO*3$(H7>fc*3eM^UWf@z8+aZ^3X!~ft!s>ujsS2_^nL9V zoZ>rTSER(iZzSnY4IPpcBJM#sH?mYEc+H$FDc{8FkbyU(k+{WA?NMT(Ywr)6BvJfq zFo@*bX7(zssjHD7l8+UONcu}u!y?Je>CB5QB-y{=O=>JiB~r{x+lr}FAd>R&$RB+A zkn~5LmPitj(2CvToLuGRFRv!l7UjzjNpdnd8o ENh;$X$_Rd*ji2Mg-1f@}Bj_fr6 O0000 |k1|%Oc%$NbB7I?ZihD5l(ofgQ|pdjFq?jL5p zIxkKAw!kj|MfcCjha+DoyA@PeuajcamOjIu(oyQt@=W>3JMD%aN4e6(Bw8oko2yuU zpE2jVTKmkS|F5e$^UUSwyb!ZoN4m=YZTzK!91m11HTljz(mdTJcRG1(oXoua##8PE z-`~Dw8T+o&5~_kiif#=rPX(|p+$i_+Ou_1Ve_L|zPFOo#Q80;RhFwgXUYJ3V>XhsD R=0LYHc)I$ztaD0e0s!a(Q+xmb literal 0 HcmV?d00001 diff --git a/MiNote-master/app/src/main/res/drawable-hdpi/attachment_audio.png b/MiNote-master/app/src/main/res/drawable-hdpi/attachment_audio.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9f4af09156ea84eb5045db42a056be16131f21 GIT binary patch literal 8115 zcmeHM `)bm`6o>1OHDMOwORS3qE;8x&BaOS-w- zd!Kv%ir N99nBtOrh{`@7tK)dMVSHoN~Y(P%y&78SBo||S?Z%*1+Z;@CqES}txd&P*H$pSt>itz8Tn7kOd zX@LeUl~owy$dw(&7G?B50LrkKOgoTjY~>NJpSv`uW{Lx-g35gkR|+Xn{rQEtFeuin zr6>(oj46UT>}A `n8 ztN8EMEp80#3!T;b?;e%$m7q%0hK@1}`zJRAf4IgUObc8(GjkWrjjhrnSME>njnK~Y zxg-s5O+HszrPqPHJyv{i?UB}R S4Kh9C0(BtL973kn{ zRp;(n9_^mwmlb|B7jQAeWnNbergrT`+<;UB- hkMdM{Gmc&Nva#alzc2&xdU2 zf%mGPT6yw|I9;-JQerOUJiz$4_I2hX;jG#PwJuQC&+%BYa!YAeHu&GajC?D;b_DHD zmW6Bc?k2^Pn^?Rn%ejwJ=)sQ|NfPiVh|07HU-F1T;1CXwXqGb(udfxnG3aQ+z=*az zYTs*}^Ru5Mv?%Y*(@z>X&W^4cKoqg|aWnJYFx1i*%<(t*-0VVP{L9`~4Hg!4d>;Kn zn;7<4e|H}zE13e{l?0lBgo3E;%gA(_N7(U1-1@V`uJ1>KYbwpbyc098l{e6yQa2M} zoVG+opCYmrOo;^=<}arI)XWx*jn>;~T3}vd=jEAKE`Rm>?(3v+Y(!zWH??+E@|)NB z%Rj5fV}ff>xqXXlBB 1letdDj^};V8FLT?G)RwmX9n8qS#Qb) zYOX%*Y&Ucj=kGhq^gEn$XK8xyHB|i_q}gq6k$_$#>laf4dJzl6CW& zn+tl}4TN!)&Y!+;F8D#~+4l19D$1aY0K6vC8TK zPhq?z$Mo!3bBuy@xNAZFPHk5?aCWbelOI}0A>`$9xq7r60s1i^;f-*M<0XfT7`pqV zL@vkd32fS)5P`MkUOB%zMus!m+N`t3Yt8>Or_up}Jb$*W{*I*a(t6y4ibTV4rc$ER z3=lB$&Bp5 s&|VqtpP zJnhO$TysMdTFEzl;geG2qJuanO;V3A_MCshR$^eAB%-7{&pM{pI2c{$E@jJE5cGXZ z?D&VEcr=LH(J_kvHpwzjurFRTpCQBJNQI1AYAIvgQQR_4{S(oCe;c3pqFo(pi?5y) zOu`!jI+l5tU$?or`|eLa5R;Hx%tmTA&hhfA3@MWC%)xo5XP1mmX%RO?0TDX(3tGg4 zS=k$(8&mgm-EUX;Q2vns%yxBjS4RLoNVCf=qOLQXRd8@~8@|X3lVnG6Q8gOda-lFW zO}Uo*vh?+?! ~;Xx?_V zUv@TE2d6@WaR)p}MTH5Y{&wh=x;}9tH_76A ~(_!4kSwL{+ zh61AXYv#STB4Sb0v)z1~#?-;hsqeI|oj~ZGf>Sqv3ByF12jOEjN7&ufHa6zL`zgf4 z;Cp-P)F%ER0}swH#3=2XT##Ucx7WnNgr>78ejZ&O8YU|vMH4!x7Lf&g0~?0EBB*b# zh;2&XF) o<1wNz3C(hy22Ln}3Mi(QZqJpjq0xK%*SJoS^A5l^vFC^! zg7+qHAuOr_ {P^!^KSwj|AMz2@WXD^>jf#k_jniFbA+-8& zqNwc1jjLPxky&Q78_6up|E{}zkw$8 n>y~pehVee$Bl?h@l^R3L5 zoiD;7m~9u)Ap~G$(`Zn*&GL4gB0@G>DT4adwP7YV>gj|86NX{Fxy^;tE@@qb90@-K z+&z26$|3#?j|U6+DxC}U^xM-~IdB%wljj9#=CpXUK4!g7AE>{ef1rN7kSsnLUjdPk zWgOv{CHpvx8TB;!;x2|9Vq%vRvJwr#X0nKIr2d!DOA1-APnrj4YJ~~TMy7IybGQRA zAq4e3I3$Ap)I-GSwG#mkmRaTxqC)+OL4*kt5>5GXlK(e%I5VnYl;O9viCrqg17NsS zU )`MtpKmfn14m^;LPwgv#8RxauHwY0aN4KKm&&1(L)G$ z3LO`S3{ogHEh#b(kMsdQ2j|fP7dSf)`2B5x4=5S)3IXcFPoF=dCAE|J7MuA0!9V-Q z$6c@T?7>9#D~}ZNKj8nH)Bn)&pKAG^LnI2?v8F>HS3pF6Lf!-V`|f^`N3%y`2?C{N zzN+?qAo+y@tmpgk)V3Z{wQ>+J5eg$u>vNH|=(VWr9>6*UY=@W-Ij1c223VO2Z7LuF zjdN(j92rHl&^mxA?T^zdkJEb!Bz*u5Ljn(13sRl@rZxQCo>eyd4_O4 kBw8{6u9T@ z?!055x4)RwMS4Q7$<%4$D$TlPwF#G2dabelGNUk&e{+A)9rQ@{#JRjt$;zlKQbCgh zT#y&y6Fioxwt6#h{@P50Yx0AOpW7Gt5gka2Jemmb##TGo0JzREmwU9E0F=U~t?0SP z!)7H)r#Az*sGk=Sz(9D%cY*9U!W=Ccy(8g&-2#+XxXEv!AAp}%-B)mM+lewrzJ8C4 z4Nbgq#Ant;Tt}|r7IsKK7M#LP#D+;A>}hXgzk7w$Joba!O5V zho>PHoES%fo(!KW$Gu=a%*L K-hPX ^m+ste<+R`|r5Td1ZJjX@Z#f!qc-YLu4+wYOX#YZ+^PpX;!=|v9~ z2pedMe##l61B~FKd}Ypz*rrZ@^08ITt@XSlyHNtZm)h>dBr{;#MSvZmLVZ+K^tpH) z)>1VEra=*BCxq;$SrSwXt`xwZOY^Ivx$f(AugP-r`q?+IW P0w$G*gego# zm_O4YL{I`G774-CnOX~sx__2R8m 2k8O s%axJ;Zo3!A>;J3owM>v1Q?QlF5=wtST3FCtX4)$**TEK?4&0)j3 z!CYiqxC!c49iP_u61`XAZS2J ;3(PVvY(Nr(cl1b~=){O}rhoxcZo&8F<5h z8w-LpV~U8mbU4sDMBt81ePykf_-qReqRlmnfGgStJ6QWpe&+%8@DKOPCD|bkYRLXt zk1DR66SL^gzo@G9@V23&`-+vQNT#5#0gK`tMrY#w^WzH#G||d_MiHV^$=Ja)s6#g= zk}s>IB-QE^pAWW#({#7O!dn@sR$Qwbv%6ciPPUfKogd3#<7TMJBN$u6aJn^D*8(XM zgc!HrF?GC`s*-x3elW)8E+u25)bhOc3C~HU0)qNO);=Hph|##{mcqo>@o@Q&nN1Rp zc`4QUmba3&oSIeh0)N&MYXV&%!}ZwujjtlgXfNLO-u;WoW~{_ldUVjFuL+#}SZ`7! zl^p)#__%!LF8EiS7vyi)`W?mS11(l!v_Hc#w|S_HSZlXAb&cJ;9^=wlP4Xt@wS8h0 zgXRkn1w-H^;@Ho1g!D9s68#US=Xlq^09#gAm2%$CyX@Ohlcw&S>^_;mhn~a#H61DZ zT-R^dNK#qBjyYYg>q!xQ9WPTb)X>1&EO;%lVt>m%a_o>2i9Pxnk*}Ubs25^Ol&+_F z{G>BmTI@J=vL?UU`2BUbDKR-@JxVJz7Q0(#yew+Xqm8g8iv;+ZM0|{;L*M{5V{9nv z{L}CEtYLS9llefTV;$8QY6%^>kQQHcY$j4x+FZ$=Q<5geqP7n>%ih_Z2_H3WQd4U$ zFoB;S=4 -iyNpet}%%dxVD=WCJTjk6xsZ?R3o-kMM z+f~a;kS9?o0hrK9-W^6@$I`w1hPk!^W1l=b?50p*K}cN3j%290S?zP>T|SA`u+PW_ z>6N%2v>p2D4YtM9RjHPB0#J7O{E|WIs!|J9O 7jU@W=Nh4!uKpwIeO-AlS`Fr-8&j zVc20l0hrPbJ)X}u-XbXRr;j2&XRD3}W%^;Td+Z>{Yk_||=lLR7<2~Asz1@fk!}?d@ zXw?t)%rH=KzR`pO#*i_+Rc6HWtJ&Uw1zMRw58I@G(Qc|f!D2NGP~=3K#R0PPb}BWD zmRq~lFGYz8G#`spMv8K%AFL$6k0pJIy6SeDf$49 29h_&AP`IUVUNf@sz(h> | zMrjLOSN5Cply~up!=}P{r&Ymw=Fd?AIYpBvh|*RNo33#ap8nBT;o+{GG3pyEV`3>= z8%Y4$ltAwA@g~q!K7@S3tv^cA)VLKs?YgMheO02B9s??kC^A|zK;zO&SQ_ax>2joZ zJeoHtQ5Ug(lK1mteTX7LzFEJGVMQ>=rFq=l-I;<18lQVx6`XZ>?gO0ZEeI;9^GyFs zsPEzZaazUshefH&y{n2v094Suy(jCh4;{w<+%0j)Fyj_?%8DixyJ~#b8)(XVdDph) z*lpAyVY#SX2{_xuxEG3EDtHi)_#Ij%$J9~kY x8J+IowXxK`QcA44zTRa843GVv~v*u6E6mAijv*n7hsM z{l)JkyjeN7#VY7l`kTg0nImm0GlcXbH`Vf_d4^7 u9wlW29@Z{X(+5PGbnOeu?M+|3;)J0V)l3MqB7Cice4eNajM)?LL2XX7m zg5NfUw}2*HQ@V=p8s#lK^62W@6dDjS*P}Tz+O1zjEo|Q9LHYR7l#P}8N3K-#2cizH zL25?Nt7mPwoA$UqV!Iw3-rSCuP)sZyJT~2yn|E(i3pl@bz{hOO4i3OOR#6`x>Wifi z19yC_XBsv7={R$8AsNAWS(Y<(ZTe)vLYom^h+P?j%X%;nr=KPr`TMmH>V8t1$?Q6{ z+{R%Y8A9XwE&B=bTP-c|4Rl+!Z5=0Exi76=n-M(K$bY*Z>ALixThvg9FM!WJho|ZJ zE(j}qUma3t&+- xEwB1P6m%;f^t%+|N0 +)fO|c7&}?1}x
AeEg3EUUr08-ldtzn=+-(m#E87tv_ynaQFf#Wi9Nnvt_o!Tes z%?herd#`nk@2K2Wo_TzF^GDF-aOLX-IkBwOkbTyzIofT1Kp>~opWAA7Obm8K4-WR* zlj_!0WqG-pq@{klK0Uo>P4S|mv1Q{bt_9?;Y03@=A$=Q-&0CQcxdK$Dx(PUUv{UNO zkj~oYpO@1;J=rB#&NomD;0uMj@%ov|Z^Q59Q0xxBZl6q&iAf24+JlvxWNK0$|HOwb zp0~ZrM^HF=Wc>?o?6_V%Yb{>`YY`4jd>;vj!;Zab)mg}uyy>A%E@imDEc+zuk?* zS %+CCB6U-%{irCzaJ2ho zU`GzNyw`a$9R XYQWbP*4KGPx^}RlW+{`c_tSb>4hn>O1n$nn$LL?&t|-ZF y_Zv{VeNy7{dL$7Xlv6&n0cd1Ey5|(-Ri$h3EURA@%dMe-`z3FrnH A;q3=F5YjYxoepWC?-7;`g`<%yz8r7)siQ;Dv|sd-gu1LAgL?L2^QAU# z0|)kRh^kImT2BfIGaIiSbebcr!}?oDEN)@fe(! 83v?=61`a4 z<@)eIjr8hwbGC#J`UR^8R v zmvRWpc+@SDbg?=J&05OI3{Px^G@4Lx8^P*S7;?a^d22pL!W6{We0O%7*0wg#^MhgQ zpqippPbEdp=auDSvl%m@bDzU=i4EsKuT}uqqL+gaK@kQMq)q=(WA8HICv=#GKl-RM zPkpD1ETl)45#hEF2DjGRm!(c)sMnV1m3w)&9WFY7oZUW=1+y37AF*I;RQtt18odx; zKL-`bF8Ou4Jw2wf)8H@}t|;adjoZ_%V3elJNrWf0)zb $=p^a^2Kd!#NQ!JgWVG`bnnm0SPV3p_>b3*~Y@arah`dX))Z25>jK|q+8 zC(%Pqhx3#Rdk0wKL^K%ceY;uvvs*`}%0!j{TSD{60%ChbQ^%>oZ_9H-2HgqPd}Igq z3Hps#bnMtO0gfCW30C5E0l6L>eq56FbW$#SKm}jUr{C1VdA(cH!`-pXC*Rq}ws{?E zYMldePgQ#GcPi+zZD|PTVvY-}lzAxqe3ajlL{I=;OZinKXKrhlysF0=;v8tf;!9m7j&I}Us5X-)F1`RNH z yfn`C=(m=@-n%sK*ni1W5dZ%2A#;RgE{1yOg_`^fl zyLngSPlq(BQM)S!TP CiXtDdGF!VQdDQLmB+`-0lPkmzMt1T3msr)(~($@&;b`FhdFOBi7Gvb&suk%yqjd zGQe@WdfqFt+W_Ya(NB)tH)<<$llK9oT-7pkSzqg^QB!;61c}hX1#8Hlv9HVg4&zzA zzt1EK$!?EkYQNgU+npUuo|<4(ml*QL)7>_VYnbIs0(2>CLQc1}iJoahaS#vS+7YSP z?1<+s#7E!R-wgP65(hs<66I{wcf>mZj*Tk@S%;-zqD$)v5pKDaDzPVL>r&k#rmA!q zm)f(w5*)10z~0(wE5NRAkNhco#>#gdbRTU2&KwCtfiSa(R2QP7+Ku!5%xgawn2_a} zf}sh;zcUcOs^6S)A!hoYmgS;W W64o(AX6g}2Yh{O*&fyU=^vGI4rxE8i^5}oXHx)y za+77XvgP9q0q^V1V|KInP5E6j6cqG8u0Q)a)* <2?;9a#)E6|z423IICXoyDo>5=^#1` vO&37JrgV%>;KDzDur9c&I5V-0T p+7FQ+}tyZfCwMD%N*ZeF-WL3n1hfjLl`GFEU&6?+$OUX{a42(p4?9kq;a zIhMy*-me8YvnBKB9Z(!@dJ5{+|4jfxuP;f{B4c~x!%b0QfX}p3a#+bIj0*j6qf#&C zS^_W=t0M0`s357x{n2~A7;6O@xVlvs!D-5C3ng0c%7U`oL;KdHxRIAA9BbBSQpckJ z`Ir;gD3CLKvZ8GH)~OSO2}Z7!&DIMfk!4C^NhB0?WwLVm)rNiDBN!nX@w$Utgv1yu zQr@5r2P(q;f8G!SH{PQ?UI7`EPD3Euq&V1pDBeQ0XA^sKnw}9uBGpdB3rS17N5$9T z3Q%BJP+#wR^hgVy9GTxgnEi5S^_Ei!DFuLy$QDIxYvya7ms~`|P=pcD&{1q#kwS8z zP8%o h+k6w{{Q!qZe?u{od)&C;7a2Qbg^>I|)XGdU;;irs&qwM1EUX%a9=}!;* zve)T4V(MBIu=>%J319L7DR^Gk2`c#Fl6`UYlFM;*zk$(jpilq9o o{2A7~}#b(MvbB+@Di1M9mi{uy2OJ%uz$ VWqpV&t(@XNj|_!s^>7ndd3Iw zc2_TSA9nroXYC bnDwGa8UVW-9pg52-Fu4x+`zp}E z$iQ6M1>=USGd57=n=8b!QQX`1wv^C+H-I(7xu}$-PpIktG$a*k_{N_P^< ;vPE`LJrgsAHAwQg;@+qhflwIqf zs=Ebb4}9=M{@E@^k4xOLPa5WqE>gk_74rzoKCyw6Rjp9}tU}YedFCg`?0D@C4@rgn z6tI#IIiac}qqfF}9Cb;a5e&gQHe%7f4R0tg+|m(nX;b<+#r9&VBwbmBl;(fBcwI5} z7IOU#FOpe1g^6xIEB*Cvuglm4D-6Sz6p`>9cph=e z&uO(7(*mHAm5E-9?UGpoa3cSjcu~6rg%*pDl>cbs+SehB#49o!-=1-8VG0}gfGzBD zPx$oO4L&V{+rS1utb*434>n!8F7WCny#Q3{h?Id*TfmRoVqL32UiGqK2lK-448VdC z{^XQOCF`vOhsNfN?_l>9i qfE9wr z_fygd!Kq_OYG$zj)=bK=P^z-$)`0w^D|(c?-NKJ_eH?is2%<*E`ka%v1|U936 m<1U~&@V`prc?S%2{5qnPH_6Nx z3^joCO^wI6X>y+`zE1$h2(#)ts8r>qm|aiN!+EY%G|VjKDYd0NkZSJolr~S|uuHfv zi7Jb+d#`%J3Rt<^l#_V4Y*vcRXIxuvagG9+i6XgPjVo#AeFaUxUOhrpT0IekH{{g$ zrE;C09|!XqQ42;N>bS1%gyr0X=0u*()R-?qRLNnGA=uv1M-8#RY6LeEEG9{-Pww5y|0G(7dMjp&u7Pj6G^o zW0QWj@!qyiiD5JZ27d%Oq9U3eKf!Vq2 !`+|Jd701HPwHC#sEB@=Sn2@{8#jo3NE>|}ccb1K4b;trS6mDhc@!PEa z`q>+DkrN`lE?zf8rJ7%?fS|d9LM%b=RuhKvDWbj!j0k t}A%;r0gcK&)vy41sr6<=~oPzyoB=5?j%!KGivP))SXA;;sD2tG`UadXq z@V?;GH)9|4aM|s$zYM<~%$lK$+Bj0tp^*>a_rkAC1S!a|=&D9Acpug_JnivH@rAFx zD0+i8_Mt|GqGvo!?Fi9XjY!+2W8QAcRiTx;Qi~7S-(Eahx#4(5AKK?la`mo@Ho7HR z%QUxSZ1fE-u+&od&S-z|yXjQKd~nTZsYj##+XYa*E+Q044ptfNjr!zeE%5T&K?rrM z$5Zj0iT(8(pUeu@VccV-l{aLTT6rHwnp~Pl%)3G7`E!?_mzAcrALtuO92L_4bke>$ zb37&8NC*>?j_PFXmdz|vDQWb59QCCLmrveS9FAb7V8b>2sGSv0|KhGpJ?u_5xbaP+ z`?Kq6Usz7(HFj|KVn}e=dd390@`_k%0suKa;kIqB|8A<8DS3)Beq^N>6#Lqo8ccxi z@q4^9Y%3~H?@Sb^>0*La2fnx}MvZM|ZO@K$h_AQ57bconX!7jmZPeJW8q3XBz>%Ma zDRfTE^v9WEx$GxfNdK-9w461yo}7>N>7o?SBQ#ZTO8z?EA1E6*X~PD?600b-%bffw zmz7&V47F9W5glZ6c2?hyFm!g@IXyW%(`7Z&H+yX@PF`X?#2XUMhD|$J1my|zG3nc| z3Hca1jmNVr@>K5X8Ul~jt;t-xz%tcICq6<>
w4GEnsaGNQshe&$PhO zWdXp*@dJqT8-$^YV?w|C-Mm7})Hh`$bvGZkexFWJQafC(j33gva`N+djDKvjywZJv zd!=6(-c_4$y8r=S_Cy69nS;I#RNYHU?h}@OpOUZ%9ck&iad#)xW@M+*){q*;SPdkU zHbQgfo|oy0)C+Ok`O1ah_yJR-p+bG=6)DH1Pgeu`twgSVnB oN-tRW@o9S}}N} z@3}Z@AO`m)gz>fqrBOc35R7lg_$s9^uUWtE fZhPgDw}teyzRQ3bQf tO%^ut8FM2D`Xa4Q7u!gP7=h6YlJnS&5?xi^}(VCkfV&ZTQ(Tw zSX*=M53|N%@O?rUge`Lqz17|>yYx5ZwUxHLP7mh`;ssX%+mOV>WIbOn#7XR<*;8^; zE0Nv#m8JCo;7Hv@Tr+Lx?^f650roc4{IdF_z$N#`l9GEEj0Bs9l)UuXk!tvr6;k)W z0`e`pn0<9S+{7))uxHfK|BKAeS-+O2;SeXs%@>R*cW3lI>b!WN_{WYD7UmakGV(2E z5X$u3!!zM|oawNf5vsGa@fV}i5A~#SW79)T8Avb+0KK^E?yDiJH-BeWF6bNm)yM);Bfvs_?}-9v_So;4{~J3`5zMk2{36GfR&yG=S>7 za6a@Et=<=z=Avm$&p*l^u|bBeQ&>hslI^q4oE*RsLMCf8CLlSA@cech#!@2D=K1$@ zCz!fULJO7N*{~}svZ&J{P_~=Y)SyQ#o(JWaM-2;CLa*P#3EC1ppB{ZQps8-(tq7A} zQ!U$-58i0p`SfS|DsaFMaTu8zQ8mR@Oh ZTr@mGT3nlCL_P@7dtX6$`u$H+n2h#cUr| zjR9ZiO5DjvS*pf^%p!1nPv)s6uU+nqSC6@8B-v)@Ti+fOf^S~gCGR35Ygm8cI(nxi zh0{^9{2gCrvEo%C@F;_DiBbPehBGg6$8O1Xf-w#xnW!f{VEFYu^p>@Q8pmmqSzPrq zB?w!aNPgMwSR(A2t0*=oa4abPWFge>OsmLc-R0K4Yff5eqZ!hT7ACoNHgRPCQGV5l zS1efs6|licc`@wTZm^M712Vh$B6~5x3fkw~E@L5F0X9{9pyW;~@Od9BW1&sjQj|ef zA 1%2yl6$G8_r%3?3 z)2P7iiS>n^XBxDPTpYc`N}CN NMsEU>rx=SzvyvhbP Yv0tW({zmb5A+55 AEC2ui literal 0 HcmV?d00001 diff --git a/MiNote-master/app/src/main/res/drawable-hdpi/attachment_photo.png b/MiNote-master/app/src/main/res/drawable-hdpi/attachment_photo.png new file mode 100644 index 0000000000000000000000000000000000000000..c8ee88ec8ce3f7047fdce66eb45fc7e7b0932bcf GIT binary patch literal 3749 zcmds3XH-+$*3AhCgx-4#5IT`Aa1jj )~`&o{<9W1MrwSZlAf=bmfty(W$1d`OT_jt>Td z2@(l-SLpxh_lx3&zBR{ci(oLJ5F*~19DDpnVe%zOcgdF>>pv2D+PAHTPtCh(JLyF= znjp(VT`yN?*ah7YLz)^kYH0YCl}K_V7qav25kphUJ-J>qeeNRPf0aEbQ_kJURQBvc zHLkq3Ngr_iG|KqChp| X@I{T4Y>#IjJHdHd$cy3SHIABp;q zPb=6KS&557qEPo!`5a4OfNvZLfIpKfhWqm^3HepX*SOw+0Yu^**@}EPqRY|Dvm6h= zb8_&;j>bq-R(@E6Jq?b)sMGxO{P{#gjK2lm5JRE}_F``h-b$d+{w@7F>U<*f>zD%H z0&N`bO;qVod&sU$G zO z7Z)K$&wG&pxT=nRp{6%P(we~8ojVXIhvVk=&GVJP>6YPa-OqA7IYqkfd~npoN7#+m zqv6;E3rX-hr4cBMbmo2KaFggh);BMtmr%`-hX2kHx#I@qfVHL``#^G%7Z-uMzDI`1 zD*!6!CR6hJUx+ktFpBzx`w$M56)O0l!3uJidXF_d6%~Q|dD)tVy5LX*C+X(U2x#P| zk0hrr|DWP2cUdiOV1h7tG8*^%JUUsBB*SHQWovh>FR6G-7*uL}tNsHCRm&AL(a$J& zq>%UX9B#V8#oJeAE>4L3Q?YX?88P5^vjW051Xk(|wjS-gp(}9K2uNHZjy2vD3<**# zfdOZD35h&|DO(^1&Y%c##M$NHfcW;gq`=S`$cZF)^A8HTz=qux$~J`TcKF+NjX|Zz z$?W5opqa104i_#^XVmS8TBiqp%Fo?YKD%&j#0J_)6xcw#{Gfb?l>J6=>Q5?z`iLh* zXx98CgoOvJTrlI>Jgs Ju79sJacsyi~X-&i_fUn7!zL%I8S>WG654i^G=JXEYaor|p-SL@qy?}5y`geP(j zh8wK0iBjOwuV=HzQ+I|6^~Pl+#uU3|gmQvX;(LTP8=M4iEYnRR{R54j9dMu?K*&~> zTTY)o*~$|?dT6@txh@6T@bz#6>0&bP$vQf=<`GYcaP`$T?zUA~{FLkz+X dfh?SkyIITgFE(o1j-?bN0?{|{Dbi+@cZbzW^9zMX)tvz{%N zM5CL)N`=9R+g#CDBh$U{aP|wA?*F5qwGQo`2yeEZu}t6p3*EQPxImkN$wEYM;fk3h zBb= mGeT)#nHdNx&LMI|S{gL> p&yOH?pKu|K zw><0Rx?zmfPDX~` wf*v6WB6;b9g&l>B`Lv)d#^ HDn^hM~ zTyTlg0%WhX1D3o5GANRAfp6}|+dj*l^AT Xqj*({Qgv~@!xVR5etWID)#ym#17+r~xsj0HQM%}O)};yCxDq3U z7t(2R!A@p_g0rgmX20VkJYQSB?58Y8FUI1`H4056iWjZ8J{YR(kAd6Zx-M2@6zWcv zC>IFEDkGeBY85ise$wQN-)~_duVeT7Zo75=Vpcd0n_0~{@zkQSH`>~xB|l6I0o?(T zL4?y*l^0^JT$2=% Aopf?AZ$qhw2z=rp*?~QPl<0`0e72cb>9+Zy1 HER5vazlE!${7ps@RA!t zN(V;6MCAY#^qwBE&!<)5BK8_E=TtiV&(+LIdwTo>*6&Elk=qu|L)LY-Lq}~ULhQg$ zOFk&Vxw}7HWz*R*LSv!pwu9#0f7Wnp=#J9iKH vC+ zmBV@r@B|#&6gAsR`3KRNP`d#ezkLj`3~v4!h)BadPoMSr!+T9-zr6ID!#1qAsm-K@ zqMRY{hYOiLrnbADbB+?Fvgrn%CZ3cbr7 IEe=YpSG{HRA&>R($Us+ zVpgte(k_zkyVNO8uX;;EVCXtrWlMu^CWg v8a5>Q0TUkKZ*)o-X vEP#Rl1Z|rZ)9)A9E>T6@dxEtu1l~vX;7CHTB}?u^qJZ z+r(#otxP>c-TyW;FC6%_B?ikvpZR9J*1p>2^uF-H)VD>}qEu>ExXQAW71C ht~2 z;~cx$V7+^q=z31qK;}DXf4X>X8oGZ(+hyeJaPX(}E?-~9*@HO0c*2n8qdwuZuSzcs zF%T1v`%~t%U25+=xUelkmx0wYL(d|J!JY)YaW%9k*F>2CR^?1$_q9`kZjBZIO+=)_ zpzVmaPjmz)kB7EyXjrCOb)@KCOE*^I5Ka}|70&t6$KCopf>n7?jdVW&ZmSyKeeIyA z+aqm&27_WdhPV~PK3VD@Fi4iy#VKu<50v?gNHz2`aN~0Fao@$)@)cU32aK@x%YUwr z_ggv!M7Y|bvJB8ktK+xTK3N9K5!Pxo=CGngE107-h8ybW6cE4Nac<}<(2yJ*(QVA@ zMfhH+inamqiF-#0zHmlnOJ9G{^IIRYH|QH)YawB$_-RNr1ResjxkL->ov}3ent5ch zG)X&_9yMYNgybo*v|XgqJ+KvsE<-f6Kv*##d1cXXzKQt3_e_u8$>_pK-SS>V;0%gT zIb)mI*u)AEW^4R?K3hrbqP$l>MS6w*&hyQ|99{SXN+eOwog*T1#yw !nAnM!GFCBOQPDbZCj&Kk5}Iam(LIAC({#EuLmyednMrE5w_H zL_6OS7G$1US+q76=;9Bw!3hAOLHh;rOu|1^)%z;Q$#%9 `NXMi_m1KyCaN#() z%ZJhmgt;nMn@^4Nj^4Bl*gwoOj1Vwu@ }bk|gWm^ZbMkbB`$7`bnOdG@C4VBVwp<}UNa z1MmrRu9wP1R2zPv{%T|Gp-HB`L`(#2D;qR_2gw)d>)@x;<}Yl^kAx}ugn7nnKMput znLW!{)tbEC>gG@Ooq4yk9Viw#p@_FR%C3ea2H|a44wV3Dehj(1w*b=mgN{0~S!r;@ zzZp=x7v@o)5NB5vZF)_T+trj$qG2TB{1 jy9+ Q5)68X2c7Y?HYZa41;mwcoB#j- literal 0 HcmV?d00001 diff --git a/MiNote-master/app/src/main/res/drawable-hdpi/attachment_video.png b/MiNote-master/app/src/main/res/drawable-hdpi/attachment_video.png new file mode 100644 index 0000000000000000000000000000000000000000..26295834530426c5a0cb370b24962f7e9c4aebca GIT binary patch literal 5007 zcmeHL`8yQc+aHW4WSOyN9a}VZWpAuw89PO?mMu%DvByKChmmb&%-EHs$dV<4VklV# zgUUo=5EEZzX_D;bo#(yY>w15B|AY63bIx@>XSwhDT%YTF?(0T5Iau* 7Zm`2fExmCdNtl>vpgaCs%yn?ims~(w=KWUIU$4#Cw1cU19A(8 z#6REeO9h1Fv+1;DIm53P1l=wgG6e?;fbz}L+DFfSG(lcg{k-16t}hXAE?8$URR!+k zfd|Rs0JwU?wQ138>$ `de7-%hI z9-^jpx?Fs50WD|w{^3~>GB`i`-hV1Hf G}*901tm;J<85Vxr~vJL<9%oHGNWu!7&?Ib%i zuA-sQOY=1XJ1IBVb+A{*PkXq$+^&Y=xy1-eGGk=l+Z7|-2V=O!b+XmGU&{*w-BZbx zfA---{%17ADfaU=Lu303p>QGeLlvo_@lPO%%hU&!`1Vob8oPdx+YPrD!WX$31Cg#E8Oyap)b;WoGYpF)ubf*> zF3RchE?wL_u{Qk9cK4$UyqwW}jPE$~q)tfduv046nOCx;W!pl`mjt5coPvCGhi&%v zYzXQkF&m4?{NB6+lKfe?ef*;B*USS9)^^hu-I|?y_Sc`moyon(f=djC=FZ$!{_&hN z`PD9}+Gq#@uKM)tjc;lU-18FwY~km=D$+Sg0ou2yHL>VNd5a4K(+9CqtK{~4`Cq&c z!+suw9#~RoZ`-)Ssc%?m=(tVW^V~M6!r<#lp490dB4I9BH_*l_gIBVVqAYn9QG>SN zzGKesOwmm>IWX#Dpslc2<45i__G|@bwPJRp6*s&)lGYEld;Md+Qz~5>+|c5f%cuJ* z(FeZ*OIxT$_Kowb3oSR<2%(=w!OvW=Uf*PrH@*`Pn*#g`NI$=)X~(hOMxPqCy;R&k zIThdOQW!xAC dIoR^k%6PpS_P1l>C@G(YzRhdlv`kN<=*xSI zf^yh~+so;OYk6*s?xy7iF)qa3$21X4wuC;WmvNeCwYoV~>$p!4tnH+)3{T}s8cGzq zS+@m^i`m%Q#{~4&BL-qd3TL3g^U{xhR*j-?99jy>VQ+o$>W@9naZub7RU{F@>OOXN zbzp0nZ5Q=Uw(y=-n4g2)iwwV`zj%a2zxoAbZ>HHL>`~X^R6INCdU`JVZMmaseEX6w zMJ`;n_6y?60bLo<-@MSL^*ZdqfHv31D+A^3K_Azmbou7HZ#Yjp#qhsNkU??ZeAU{D zl&5EyRpy +`;W2#l_Xxyo++gUuj+~cDjc %~ zi${;A$X2Pk?_skHB4_P0L2xY1jyxLra+|n!n*6Grf>di&vi7?cmQtZ8`~so&m$EWr zi>|XdUZm>yP<5M9ecnN7c5lWJvw2%tz7@Ob7&VwCe`ahfj*)nB=)LhI7?F<>pUyj& zYiK5lbD^5in^Xvjc)8(L!zLzkO|I0&Hqi)Q) -cq`->Yoxt z_^PxZue9z&%F@fp0!dhePeHuH$0ko* ?A~uB7=1v1wr9A*X~sA`2{}DJ_!#5C zBdQxAu{r;0DpbszZeMbVvu~*ggYgUQ!I>J4jpjy&eQwFYNj%Gi?8HV$cm0_~y~5#e zZmak#p=~WxA)^f7No?6!o4gVcp~fDu<5NsAljV+}zSiFT{^?PXxik)iOnVCnpX AH6+fuXO!sJEYtoj(4PI zBI216cx5^S*A=CZE8#GbIt6{1Xid|*`x=_eR%w6qCp9N*W;#cLz5{kivn$ho`Oa52 zqCMJoHW(ctsXq`-&C24c4)hRPn?|pUC_b*Cc84>fm+>m|2FT22y=yPL5~`nx+!_xx ziv7>~oi-jUf55NfSEV}(36U)u@@*?r%)61P`c$?vAItPRh|!^ %1&$ts&|Y$${k0h1?GgZ$2r2I66M|>AI+UZFbYU%x$D&azCC (^Vu z-nXvo^0_tRleI1=SeKrW;_&Xi=L$XVqAX)2Z??+d)lUv6{Jula>x{si4pV zhph6Xh{3(yow?B~GEd?s{`EkdkEPj%D3)y28@XuI?HN0kv@Emqg%Bp$2N5~S+Xwes zd;0mwZc@8vexCZ^ChxpSFTObUciY|S@N4mUNO pii-e7kUlf1e;eYR({4#suQ&;kSh4(<&%wlw24R9Y~|$Tyde USO!N^q_$^*+#v`tsFql>Q3$JoOA9+Mp z(anijY5z__%YBs`ey&Jcj@g>=O`) UBs1r-vT~P}Ne*4IRo|^(GFuUCb*k5|X$r}( z^P~-#@%r~vxq(PG8&iWUO?g)+RWAANX!H5ea>KY6)zXGc2$_j?R^*`Nhdm(&({a^Z zkYOs6xzC1qsON5*95cRBod0m{$Uh}w+tXCZF{o=bJh(5LxtvkB8lq*Ssh~UkM6K zl~@%Qy}*xz%SIpdb*pjETBhI3Sqx`MG+b-uUEFYLy&x3Ok5LdXzTR3jG+elxK|OC@ z0uP`2a>yuz)2?2 pyy}G3y@{jw`U(Quk8#YWD^KPb5-nyh!uG0E7OO#{8;8 zlEW=NP2c)XF?w|IB0~kc`13)()OOEQ>o0Q1t==y5b(W#D`=+d%&qK~7$XTt5OGrrt zx#zPyeAriKUfCRg@mJx13$RG75tS7czBSs}gW&%N4~5zT(t@c*g3ToWptHT`0pUEr zv^_#P>lzcUJD+{*A#fk!(aAU1z{IZ#SSB|y)9a?WjAd6QUe77lH_c3(r#H>%^-TOz zI@&jk6$JnBr!xK%6A$etHEXkQRK*-Q^@K8U?VGe2rkM|~|5oz(7cbHH754w;|Nrs- zPwF{AN%>V(!ZK2q8? S78iBpGWMfN`svK;o8_?Oue2LuUU z%bwfz|FDBmXGB(`W;r#afK_RL+A+_hbwnG1#OadnYm?0%sQ5M>bf*-c2%SLKI-;A* zZSt+oI!gHsd?7ic(IHDZEDpyn%i6QI+G4D^Fbo#Cdv>w>*=JZfIqx{k>i7P>74Rcp zpk|3Smfc$1hP`o_qs#t&)E~3l$-QT{C0)|Ep`#3YiCUijS%M5)XLvo{mYX%G0j_&` zl}Si*dqJx7W>HM%=4Bxf^m|HM6ZS@nfwN*YK=8=jO0`F#E7bEh{;+yeR8>h!X~(*# z4*{JbIR~b1l$b#(>-T0C=HxaTIe6r!*8Vz*H)|g!2V}Ca=yIel$FI#7WKWKhRaLFy zCWtwYxF$5J49D# 6K-~h5h zrpSzim=vkUa^8{MLhT&tJgpHdetP3O2ftC4V8y)ofI&&Q=v~N@lKZ&sYp#T1ks75G z$lXy_qBZRd%S)i>3QVUqXhTCh@=&lLwBPFN4x DwYgOBog2ZSmk(Hhp8sDjk8al@7Ktnwo*QV)>v- z!Q)EN>6&hnxoP=qKo#&(kIIXPV|87^?Sq`BmyLm*!tzOi7sx3%@OVo#ga%+y2I_sF zl(qkU=!U$SN3h73u6VH>1mE0*awnL)0j5fNy8I18Y0f1Zz7;k-Whl9P&QfX@X?{`^ ztZb$t09q{D0mYE)9gT14Unc-NIQj9ktI2%ARgRk~pjReuI9MjGXGlDb>_fL|`QH|T z+hsTN2LAMK #bAIn(AMpHnFyd}fWoN5gY1L{daBFig1JqXZfcLf%f$L6%~Kl(k0IZa|g1Irm@Mt@sr+)>45KD$_zf)wXijY9)! zn-e66TL?O_8`b(l%?;@vI>Y|FUS7rK8(}zeXHmnC&x%cgvLwiI>YUlSTkj*%+Ll!Z zt~r!FOgRdlG7vhg%x=xd+>sh^ms5TOzfA#m!OJ>!^bQ{>4j5_dRDX16Qi8I-N}xY* zDBl=Jqm*Y7g0fxooS|}|-vs5!{uO|=p8H_K!E-{IRRU!%C7}ziwSB*C$`L>{&lI>X zC|PrB;RjHd%kZ2`c38cMOfw7XyZ{YexT2@7YRiR7o|j)qWOH_g!NW|eN>s8Mgn$t1 zreHbY$}Fa$S_mhEv9oZvD1XVcsFP(%DB5Dd!xWH4$ KLZ*U+ 5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1 ;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008g y@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} z l4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe- O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+# `N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2WpIS+6pmtC%Q-`S&G F4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ib hIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyE n!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>> ;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr< 8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^H O&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9 Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8 oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t 0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j 6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>R I+y?e7jKeZ#YO-C z12IWNK~#9!#FyV|990y@Kj+@tN!CQ0O+r^fG3rCwCxf>AC-lJ|P+JQkNEQ0#Q?cMf zNfrB6UqnH$4}B7Sh#=MCyZ!|hTB3rL#%Qx9?rwHFJNF(RX1X)GO}1$#um=uvf6UDH zo^!tE%o$NtMj?g~$;g0ZVD5nN%OAXOwi4L|F@h06j35HW2$Ic>kd6!c={&t=avfMI z0<2uy&za?A9Kb8*zF_&|cL2tLIcHcnarWYgvR3{0<%O?`^P4|Bfsx!o0FIx(!q?~D zjDV{53MlxsM@O|aLdc1G Ag#p`kyP)b^YzRy@;b`z}K%nhO_s_ zbQWXh&%AN+{r@)Bx%K-^X6oOPK2k2#LQsDBZVc=0-*dp@!FvGyX)5(Cr4lP>rjKl{ z(!9g-z@>qm72s0`7@q;>Ck=a&GS41bTzLJpw-<_QpD!(a(j!+2EIrl0o>;8y80z(W zty=AKHQpy=JVt>Yt4qaL2^w}hd 1j9iC;` VlIrBbJsV zmwy1cf)6Q&CDlBQ%T}&Xd|BT(wK({~S5i>bo|ehukPHA1vN~+%>OCkRA%x-S6hi1L zAR2&>AhuS*&q coxkV-Po*idmI|8H#l_gAR0xxYUCp4s5m#&)gj*6`1|y`r!V$5Zw3(| z=`u zY<6ZhWnfTXXvzD=pUd@}UFm|Znu@pErj(N&(|S@)PMW9_X*5YyIdW49OjJh_RTQMm zV;Vvfq*=uqAqvzCGyx$BG!ke6ijhDQ KLZ*U+ 5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1 ;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008g y@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} z l4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe- O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+# `N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2WpIS+6pmtC%Q-`S&G F4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ib hIR?(H}Q3Gzd138Ei2)WAMz7W9Vy`X}HnwgyE n!VS)>mv$8&{hQn>w4zwy3R}t;BYlZQm5)6pty=DfLrs+A-|>> ;~;Q z_F?uV_HFjh9n2gO9o9Q^JA86v({H5aB!kjoO6 zc9$1ZZKsN-Zl8L~mE{`ly3)1N^`o1+o7}D0ZPeY&J;i;i`%NyJ8_8Y6J?}yE@b_5a zam?eLr< 8@mESk|3$_SkmS{wQ>%qC18))9_|&j{ZT zes8AvOzF(F2#DZEY>2oYX&IRp`F#{ADl)1r>QS^)ba8a|EY_^#S^H O&t^Rgqwv=MZThqqEWH8 zxJo>d=ABlR_Bh=;eM9 Tw|Ih34~oTE|= zX_mAr*D$vzw@+p(E0Yc6dFE}(8 oqt`+R{gE3x4zjX+Sb3_cYE^= zgB=w+-tUy`ytONMS8KgRef4hA?t 0j zufM;t32jm~jUGrkaOInTZ`zyfns>EuS}G30LFK_G-==(f<51|K&cocp&EJ`SxAh3? zNO>#LI=^+SEu(FqJ)ynt=!~PC9bO$rzPJB=?=j 6w@a-(u02P7 zaQ)#(uUl{HW%tYNS3ItC^iAtK(eKlL`f9+{bJzISE?u8_z3;~C8@FyI-5j_jy7l;W z_U#vU3hqqYU3!mrul&B+{ptt$59)uk{;_4iZQ%G|z+lhASr6|H35TBkl>gI*;nGLU zN7W-nBaM%pA0HbH8olyl&XeJ%vZoWz%6?Y=dFykl=imL}`%BMQ{Mhgd`HRoLu6e2R za__6DuR6yg#~-}Tc|Gx_{H@O0eebyMy5GmWADJlpK>kqk(fVV@r_fLLKIeS?{4e)} z^ZO;zpECde03c&XQcVB=dL;k=fP(-4`Tqa_faw4Lbua(`>R I+y?e7jKeZ#YO-C z0{TfrK~#9!yp~N!ltCQEf3v&3?jo@k87tZw9we!Yv<6BNK?#*7Pa5K;37)b;bTU%5 z=#-~AY*JKcAKD>m^Qe*peSlVk5keWRRN#iGZMxsn!P#Xa*Vd2Mfj`VU@54OvJoBIb zjF3_ygy5OeDKWO?T2#m6A00K6DNs^kHmQD=!K#=Fg)B*BCWFZWv6$f;f3<`%L>j;% z5CY;r4v@VLvZOMZCib}9)X&axDjG#^X-SLAB>rpT?v@rbyB%RRQ{3E4+(>2Cyu2iM zyVHrKpkPg^$V6FaW+vGeW;2CVRmLfsA0JPGr-z1^>g!v-vUH&DUT>1@xywa#anZO0 zneccB`uzaxY-k{AWP(Hj0X}qe08r+3lT%qqDCK_~SOCHsp$y=&$HP~z7n7!Ow7(xm zZ7sinC=kiZV{dyq+p4RXQw3nn$`bLiu8!&9VKlp)BfY&G= H8XMDM!gF&x%FX>}d_>ptS5=7P;V`e8nt0`M zvEcJ9PnL2n(-z{@T+?5AdYJ6%qp+rit)-=GEiENmRhmy8&$4sLR2%PQVB>n)h_2_a zN!hyZGo#7mW|FblWEmgoM8v@FgSNL&ABK;sDa08olMws~w{8pJ8I$st8m_(!4GuVK z0{e#SSpc362yw+Lr4K2?ssu_vI}dl9LOiLL@{AoC#0qav%Sx*W!~1vOz7B7YGNK+^ zK_HT{Slg(Skx{tl65?UGlx ;fD>E?@=BtIY0fmXgH*=oLcjy9#$(b={GujaCIPD;0~%zStU$pircm zTC7dYGoK*KQa|F#is%NMbD_3LQ{ KLZ*U+ 5Lu!Sk^o_Z5E4Meg@_7P6crJiNL9pw)e1 ;Xm069{HJUZAPk55R%$-RIA z6-eL&AQ0xu!e<4=008g y@A0LT~suv4>S3ILP<0Bm`DLLvaF4FK%)Nj?Pt*r}7;7Xa9z9H|HZjR63e zC`Tj$K)V27Re@400>HumpsYY5E(E}?0f1SyGDiY{y#)Yvj#!WnKwtoXnL;eg03bL5 z07D)V%>y7z1E4U{zu>7~aD})?0RX_umCct+(lZpemCzb@^6=o|A>zVpu|i=NDG+7} z l4`aK{0#b-!z=TL9Wt0BGO&T{GJWpjryhdijfaIQ&2!o}p04JRKYg3k&Tf zVxhe- O!X z{f;To;xw^bEES6JSc$k$B2CA6xl)ltA<32E66t?3@gJ7`36pmX0IY^jz)rRYwaaY4 ze(nJRiw;=Qb^t(r^DT@T3y}a2XEZW-_W%Hszxj_qD**t_m!#tW0KDiJT&R>6OvVTR z07RgHDzHHZ48atvzz&?j9lXF70$~P3Knx_nJP<+# `N z#-MZ2bTkiLfR>_b(HgWKJ%F~Nr_oF3b#wrIijHG|(J>BYjM-sajE6;FiC7vY#};Gd zST$CUHDeuEH+B^pz@B062qXfFfD`NpUW5?BY=V%GM_5c)L#QR}BeW8_2v-S%gfYS= zB9o|3v?Y2H`NVi)In3rTB8+ej^> zQ=~r95NVuDChL%G$=>7$vVg20myx%S50Foi`^m%Pw-h?Xh~i8Mq9jtJloCocWk2Nv zrJpiFnV_ms&8eQ$2WpIS+6pmtC%Q-`S&G F4Q#^mhymh7E(qNMa}%YZ-ePrx>>xFPTiH1=E+A$W$=bG8>s^ zm=Bn5Rah$aDtr}@$`X}2l~$F0mFKEdRdZE8)p@E5RI61Ft6o-prbbn>P~)iy)E2AN zsU20jsWz_8Qg>31P|s0cqrPALg8E|(vWA65poU1JRAaZs8I2(p#xiB`SVGovRs-uS zYnV-9TeA7=Om+qP8+I>yOjAR1s%ETak!GFdam@h^# z)@rS0t$wXH+Irf)+G6c;?H29p+V6F6oj{!|o%K3xI`?%6x;DB|x`n#ib