joschkaschulz / cordova-plugin-image-resizer Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Hello,
i'd like to use this library for a commercial project.
Could you please add a License?
https://forum.ionicframework.com/t/i-can-not-add-plugin-imagepicker/90318
like this issue, need to add package.json file.
ionic-team/ionic-cli#2208
https://github.com/apache/cordova-docs/pull/699/files#r114967465
https://github.com/Telerik-Verified-Plugins/ImagePicker (for cordova 6 without package.json)
https://github.com/Keko94/ImagePicker (for cordova 7 with pacakge.json )
WebKit discarded an uncaught exception in the webView:decidePolicyForNavigationAction:request:frame:decisionListener: delegate: *** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
This code cause silence in ios:
PHFetchResult *savedAssets = [PHAsset fetchAssetsWithLocalIdentifiers:@[fileName] options:nil];
[savedAssets enumerateObjectsUsingBlock:^(PHAsset *asset, NSUInteger idx, BOOL *stop) {
//this gets called for every asset from its localIdentifier you saved
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:imageRequestOptions
resultHandler:^(NSData *imageData, NSString *dataUTI,
UIImageOrientation orientation,
NSDictionary *info)
{
sourceImage = [UIImage imageWithData:imageData];
}];
}];
Hi @JoschkaSchulz ,
i just noticed on iOS the resized image file url returned from the plugin is always an auto generated filename (img%d.jpg
with %d being a static count variable, line 124 in ImageResizer.m
).
Looking into the code, it does seem like fileName parameter on iOS is used as an asset name which can be used instead of the uri parameter to load the source image.. (lines 58 et sec., correct me if i am wrong..)
If this is the way it works on iOS - why fileName is mandatory like stated in #16 ?
Different behaviour on different platforms is not the way a cordova plugin should be implemented and different parameter meanings on different platforms is really bad practice (i would actually say a no go).
Even worse, the documentation does not mention this. Doc says: A custom name for the file. Default name is a timestamp.
, which is absolutely not true for iOS.
I would recommend to at least clarify the meaning of fileName parameter in the docs with a big hint on different behavior. Better: implement a new optional parameter like assetIdentifier
for this iOS specific stuff and change the filename generation to work like in Android..
Would it be possible to add windows 10 support.
I don't mind creating a pull request to implement this feature myself.
PluginManager: THREAD WARNING: exec() call to ImageResizer.resize blocked the main thread for 150ms. Plugin should use CordovaInterface.getThreadPool().
Hi when we are going through multiple resizes, we get the message that the thread has been blocked.
Is this something you are looking into or planning to fix?
My full code is
var options = { uri: "data:image/jpeg;base64,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UYpKKBhRRQKYAKUUmKUUgCloHSkoAM0vWkpRQAUUUCkAtFFFABQaKM0AFAopKYDqKSlHSgAApaBRQMUVPbDk1BVi1oJZZrLvz++NalZF4czv9atGTIab1p1JWggpQaTFLjkUAW7bpmrFV7UZFT96zZaFpr9DS02U/IaQykOZqsYxVWI/vjVupKEopT0pKBh2opDRSAWiiigApaSlpgGaWkFLQMSiilpCEoApaKBhRRQKAFFBopKAClpKWgAooooEFKKSigQopaQGjrQAtJmlpKBi0AUlKKACilpKAAUtFFAgFFFAoAKKWigAooooAWjFFFACUtJRQAuaKKKBi0UUUAFAoooEKKBSCloGFFJS0CEopaKACiiigAooooASiiigYUUUUAFFFFAC0UCigQUtJS0AFFFFABSUtJQAUUUUAFJS0lAC0UlLQAYooooAKKKKACiiigAoopaACkpaKYCUUUtAwooopCCiiigApaSlFAgooopgFFFFABRQKKAAUtFFMBKUUlKKACiiigAooopAFFFFMApaSigBaKKMUhBRRRQAUUUUALRRRTAKSlpKAClpKUUAFFFFAgooooAKa54p1RynAoGjOvD8xNUHOTVq6bkiqhoGV7k8Vi3jfvMHoRWtcvkEVjXDHcc4q0JkEu7b8vGOmaEDMOeuKACMnJxnpRk4JXp/OrRHUQZ44NPBx296Zk7hxxilPzHg8UE3sP4IB7Go2PPQ05jtK8Hp1pPvdwPamD1EDjJ4P4inBTg4bBPrzTCH5CsMZHGKeiDOeuKAHKuAOevX2pQGHLcKemfSg8g8frSncyAsc44FAMdg8EdD3oAHeo1RlUKBx25qRATwRSFcntOJGzn8a6nw3HxJJwQBjNc1EGGFXHPrXX6BD5WnLkfMxyamWw0aYoooqCxaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAxOtLS4pKRqBo7UUvagBDSCloFAAaTpS9KDQAlL60lFAhaKTNLQAUCkNKKACkNLmigYClxxSiigQlKKSloAQ0lLQBQAhFFLQBQAmKWkooGOFApBxSg0CCkoNKOlIBBRiijNABQKOtAoAU0gpetJigApaCaKYAaO1FFAAKKUUUgCijFGKYCUCjvRSGLQKBRQAUYpaAaBhSUtFMQUtJS0gCgCiikAd6KSl7UAHakoooELRQKWmMSlFFAoAKKKKYDhVm2qsKtWv3TSJZPWNdczMfetmsOdsytz3rSJmxtFITQDViHUYpA1OpAW7XhamqK3HyVLUMpC1HP/qjUlRXP+rNSUUoOZGq1nAqta5y1WaRSCiilpDEooo70AFFFKKBgKKKKYBRRRSAKKWigQUUlLQAUCigUDFpKWigBKKWg0AFJS4oxQIBRijFGKBC4oxiiigYUUGigAooooAWikFLQAtFIKWgQUUUUALRSUooGFFLSUCCiiloASiiigYUtFAoAWikpaACiiigQUUCigApaKSgBaKKBQAUUUUAFFFFAAKQ0tJQMKKKKACiiigBRRRRQIWikooAWikooAWkpRSUAGKMUUUAFFFFABiiiigAoopaAEpaKKAEopaSgAooooAWiiimAUUUUAFFFFABRRRSAKUUUUAFFFFMQUUUUgCiiimMKKKKBC0UlLQAUUUCgAooopgFFFFABRRRQAtJS0lAhaKKKACikoFIBwooFFMApKWkoAKUUUtACUUtFAgpKWigBKr3BwKsGqd22AaCkZlw2W5qBzwaklOWNQyngihAULtgoJJx61kTSK0uPXoK0b/hCKyj17VokQ2x4PJHbFIDjhfzpo/IUuACMDHpVEXAjJHYGkU7Sw3AjNHCA87znoDTVkzkZ5B9KBXsDOc4HfpTiG42MCQMEGlVmxyB9cU3I3EigEJu2vyp59+KkiwFwetN9yM04AFhxgEUx63HA5+hp6D92B1wOaj8tRkAcHvTh+7Hyg59qAux3C4boOlSJjPXmmD7uDyKmtkUcc4z3OaQFq3jLbV7g13FrH5VvGncKM1yWkoJLuJPVv5V2VRIaFpKKKkoWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAMUGijFGKRqFFAooABRRRmgAoopKBBRS0UANxmlopaQCY4pe1LSUwAUUZoFAxwopKOtAAKWkozQIM0UUlACjpS02gUALSUo6UnegBQKXFAoNACGlHSkpRSAMUYpaCMimA0UCgccUtAAKQ0tJQAd6WkpRQAUUtJQAvaijtRg0ALRSYpcUAIaKWkoAMUYoxRikMKKBS4oABS0CigYgopaMUCCijHFGKQBQOlFAFABSU4UUwAUUCigAooopAApe1JSimAoq1bD5TVUVctx8tMlkh4BrCl/wBY31rbl4jb6ViMcux96tGTG0YpRRVAApwPNNpy9aALtv8AdqYCo7f7makqGUgqG5+4anqC6PyGpKRVswNpIqxUNn9w/Wp+9ItABS4pKWgYlIBTqSkIAKWiigYlFFFABRSikoEKOlFAooASilooGFApaSgQUUUtAwFLSUUAFFLQKACiiigQtJRRQAUUUUAFLRRQAYooooEFKKSlFABSikooAWikFLQAUUUUDCiiigAoooxQAA0tIKUUALRRRQIKKKBQAUtFFACClopKAFoFJS0AFFFFABRRRQAUUUUAFJS0UAFJRS0gAUUUUwCiiigAooFFABRS0UAFFFFACUUUUAFFJS0AFFLmkoAKWkFLQAlLSCigBaKKKACiiigAoxRRQAUUUUAFFFFAC0UUUwCkpaSgBaKSloEFFFFMYUUYopCCloooAKKKSgBaKKKACiiimAUUUtABRRRQISiiigApaSikAopaQUtMAooooAKWkpaQgooopgFFFIaQDT0NULtuCKvOcKazLtuDTKRRfqagnbC1Oaq3B4oQGVeNkNmqJJ9BVm6fcSMdqqBmwdoyR0Ga1RnJj27k4AoDZxmh0JjLHHTse9MHLLg4UfrTJbH/ALs5yVJxyKaV3AYPT35pzY38EY6YpD8vfFAhgbaxU/Ng8+1AxzjoaccAEtzu7jvQv3c0AhGKphRyAMfhToSTyBnsKZ9/5v8AJqVPlGwgh/T2phre/QeqbUOTyTT1GFPFRqN5BJ6VKSFHPFIoQcAYqeJPMXvUSHLZHQ9qsRKcbc4ye1AG34ZtVMpZuTGK6cVkeHohHBIwUjcRWvWb3GhaKKKQwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDGpKdTT1oNQooFFIBKXikooEHegUAZpcUAJiloooAKBRQKAClxSUtACUCigCgBRS4pFp1ADe9FA60poGJRijFAoATFFLRQAGkooAoEKKXtRQKAEopaBQAClpopaAEPWlWkpRSAWkIpRRTAQUCloxQAUUUUAKKKO1FAwozRSUgCigUUwFFFAopAJThSYpaAFFFJRQMUUUlOFAgxRiiigBtLRRigAoozRSAXFFFFMApMUtFACCnYpKWgBQKuQ/cqotW4fuU0TIJv8AVN9KxG+8a2rg4hb6Vit941aMmIKXNJS1QBnNOQfNTKkjPIoBF+H/AFYp/amRfcp/aoLCq94cJViqt4QQRSZSGWn3PrU1RwLhBUuKkpCUoooHSkMKKKMUAFFFAoAKKWigA7UUUUAApO9LRQISilpKACiiigAooFLQAUopBS0DCiigUIAooooEHaiiigAooooAKKKM0ALRQKKBBS0gpaBiUtFFAAKWkFLQAUlLRQIKDRRQMKKKKAClpKWgQUZoooAWgUgpaAFopAaWgAooooAKKKKACiiigAoxRRQAUUUUAFFFFABRRRQAlLRRQAUUUUAFFFFAC0lLRQAlFFFABRRSUALRSUtAC0lLSUAFFFFAC0lFFABRRRQAUtFFABRRRQAUUUUAAooooAKKKKACiiimAUUUUALRRRTADS0lLSEJQKKKAFpKWkoAWikpRQAUUUUAFFFFAhaSlpKACiiimAClooFIAFLSUtMAooooAKKKKBBS0UUgEooopgiKc4Q1kXLHNady3ymse4bL5FBRG3FUbt8Katu2AayrqblsHI9apAzOuj85UHk8mo1BXkDk06SQbtwwc0sLGbecAKnGSep+laGOjYjfOBnIA9+tCjA4IzTXZsERgFutIj7jwCPrQhD3LBBggYI7c0wlWXOMk9SaeOc5OMUzAZQVJwelMAOGUAHBFIuQwHUY4pyL260FQGBJIoHy6XHDKtzRjdI0hBz0BNJvUHO7j3qRTxxSFcItu7LHAz1p3mrKAUyVPTIxQuOe+KUuC2CfpQBInoOtWIkZiAB3FV0TZKctzWlZwNNIqqeSQMUmNHW6anl2UYxjIzVqmou1FX0AFOrMoWiiigYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBjZ4pKQc0tBqFAoFFACGiiloEApabSg0AFFFLQAhoFLQaQCClzSUUAGKUGk70tACiikFOoGJSiiigBCKTmnUhoAQUUtGOKAExxQKKWgQUgpaSgYtGKBRSABRS0hpgJSgUUopCCiiimMKKSigBaKKBQIXrRQKKBhSGiigBRQaBRSAKDRRQADpQKBS0AKOlJS0lACr0paaKdQAUGkooAWiiigBKKKUUgEpaSigYoooFFMBaKSloEKtXYvuCqS1dj+6KaJkR3hxbufasUHPWti/8A+Pcj1rI24q0ZgKBRmkqhCinxcuKjqWD71AI0I+FFOpi/dFOqDQWqN8SMEd6vdqo31JgSW/8AqhUlMgGIx9KfUloKB0ooHFIYtJQaBQAYoFLRTAKKKKACiiikIKKKKACiiigQYooooAKKKKBoBS0gpaBhRRRQAUCigUCCiloNACClpBQKBBRRRQMUUUUUALRRSUAKKKKKACiiigAooooAUUUgp1ACUUUCgApc0UUAFApKUUAFLSUUCFFFAooADRS0lABS0lLQAlFLSUALSUUUALSUUtABRRRQAUUUUAFFFAoAKKKKBhRRRQIKKKKACiiigAxSUtFACUtFFABRRQKBhRRRQIKKSigYtFJRQA6ikFLQISilooAKKSigBaSiigBaKTNFAC0UUUwAUtJRSAWiiimIKKKKAFpKWkoAKKKKAClpKBQAtFFFMAooooAKKWkpCCilooAKKKKAFopM0UwFooooELSUUCgBaKKSgApDS0jcCgaKd22KyZjlzWleNxWY5yTQUQTcCsq72gMpGc8YrUuG4rGu3LEnPfiqiSygBtYjAAHAof7uQoJBp5XikK9q0MbBGo3nrkihGUk8gkfpSZweKWNVGeOvNAxsmXzgjFOG3JIGATSNhSBnB9aRj8vA707iJARjimj52K9aQDoeh/nQ3JyDQVfQRk4O5i3PcdKlRW35ZgUx0A5piKzDAznuR6VOqhQRzmkTYRQMkj+Lmpdisu1u9R7fu4faO/FSAp53HzFV5Pagdh0Kndz17Vu6FE73sJH3FyW+vasaMZIIrpfDA3pLJtI2/L9algjfooFFQULRRRQMKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAxcYFIKKWkahRRQKADFJS0GmIKKAc0UDEHenUgooELQaKSgAoFKKKQCYpaKTFADqKB0pccUDCikNL2oASijtRQAdqWkFFAgNFLikoAKMUYopAAFFLSUxhS0lL2oAQ0tJS0CAUmKUUtACUUUUAFFFFIAFLSCgUwFpKWikMKSlxSYpgLRRRQAYpaKSkAopaQClNAAKUU2lFAC0mKBRQAUUZpaBiUooooEFApBRQMWiilFACUoooxSAVetXk+6KpL1q6v3RVIiRW1E4grKOcVp6n/qB9azGNWjMSgUUVQC1JAPmFR1Lb/foYIvjoKdSdAKWsywPSqF38zEZq+elZ9z98fWkNE8P3BT6bHwoxS9aRSDvS9aSikMKBRRQAtLSCigBaKKTtQAtIKKKBAKUUCigAoFFFAhaSiigYUtJS0AFFFFMYUUtJSEFLSUtABmkpaKBCUtFFABRRRQAUUUUDFopKBQAUtJSigAFFFFABS0gooAKcKbS0ALRSUtABRSUtACUUUtABmiiigQUtFFABRRRQAUopKBQAtFFFACUUtJQAUtJS0AFFJRQAtFJS0AAooooGFAoooAKWkpaBCUYpaSgAooooAKKKKACiiigAopaSgAooooGJRS0UCEzRRiigYtFFJQIWigUUAFFFFABRRRQAUUUUALRmkooAdRSUUwFooFFAhaKSloAKSiloASiiigAooooAWiigUwCiiigApaSikIWikooAWikpaAClpKWgAooopgFLSUtAhKKKKACmSHCmn1FOcKaBozLxsmqJPJq1dNliKqEUIZVu3AzWNP8ANJgHn61rXZxmsW5MZcsy/d46VpEmTEPXGQcelIaYgdclFPlnkj0pzHIB9aozuNU89OPWn4B3cZwaarnABXGPendjjmgBsiZUHOGpMknJIP4U58HrUQCqaCWOPXNOQjJHfHFNLc9OKcgJ5Az9KYIepXfkEbu4p5Cg7juJz0FIuWbgc04c8HselBYFPlDBuO9PJ2DFNUAIQB1NSJyaRJYt496jcAQeea67QIBDYAjHznPArlbdd5C9s84ruLWMRW8aAYwoqZFIloooqChaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAMWikzRmkahRRniigBelJ1ooFMAoooNABS0gpe1ABS0UUCEpaO1FIAo70UUALml7U2loAKBRRQAtJS0UDEooNAoEKKBRRQAUUdqDSAKDRQaBiUtHaigAoAzR2oHSmAUUUUCCgUtFABRSUtABRRRSGFAopKYhaMUUUgCjFFLQMMUUUUAKKM0CigBKUUUCgBRRSCloAMUUtJmgBKOtFHSkAYooooGLRSCnUAJSg0UUxD06irq9KpJ94VdHSmiJFLVD+7Ue9ZzVe1U/cHrWfnNWiQo6GiimIUdKmtR84qAcirFp9+hgXjSim5pRUFg3Q1n3B/eL9avseDWexLT8jgUgLS9KWkXgUuaRYUlGaTNIYopaQUUAOopB0paACiiigAoopaAAUUUlAhaKSlFAC0lGaOtABSikoFAC0UUUDDNLSCigQtFJS0AFFFJQIWkpaMUAJQKWigYUUCigAooooGKKBRRQIKKUUlABS0lLQIKKKKBhS0lLQAlLSUtAgoFFFABRRRQAtFFFABRRRQAUUUUALRRSUALSUUUAFFLSUAFLSUooASgUtJQAUUUUDClFJS0CFooooAKSiigAooFFABRSUtABRRRQAtJRRQAUlLSUDFooooEFJS0UAJRS0lAwoopaBBRRRQAUUUtACUUUUAFFFFABS0lKKYBS0lFAC0UUUAFFFJQAUtJRSEKKWkpKAFooopgLmikooAWlpKKBBRRRQAtFFFMApaQ0CgBaKKKQC0UUlMQUUUUDA1VunwKsmqV4c5oGjNnOWJqB2wtSyHmq8p4NNAzNv5CFOBlh2rKkYqSTjmr9++0gHqf5VQyF6dq0RlITc3TJA9PWigNnkgUDBGaZI9TnqcYqKRmGCFyT6GnqDnnH1pGI7g5HQigA2kRq54z2pF5ORjP0pABkM2455pc4bigQi9T9eaXBB9qQd8k809SAOee9AkKh2nJzzTy/zfMjZPcU2IiRAy5GfWnoS6KSPm6nFMq47HGQTUkCliWUjApiEAEYJqxCODSGjR0m3+0XEeMZyDwe1dnXM+G7cG4ZywO0bgB6GumqJFIWkooqRi0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAYQ5pRR2opGgopaaDilzTGBpM0HNANAC0dqTNKKBBRmigUDFozQaSgQ4Gim5pc0ALRSUd6QCilpBTqACkozRjNABmjNJ0pRQMKKKKBAKUUlFACiijpSigBKDRnFGaACkpRRQAdqAaO1FAwz1ooooEFLRRQAlKKSnCkMKSlpDQAgpaBRTELRSUUgClpKWgYUUDpRQAopKWikAlKKKBTAKWkxS0gFFJRRTGFJS0lIAooooAXFKKQUtACUUtJTESRcsKujpVOAfOKuU0QzO1XlkHpVCrupN+9x3xVKtEQBozSHpQOlADhVi0+9VcVYtDhqGMt04UgpagoR/u1QH+vIq+/3TVGMZuGpDRY6CiiikUhKSnUlIYgNOFNFOFACilpKWgBKKWkoAWlpopaAFzSUUUCCiiigANFFFAAKWigUALRSUUAFLSUCgYopRSUUCFpKKKBhS0UlAhaKKKAAUUUUAFFFFAwpaSigQtFFFABS0UUAFKKKKAEooooAKWkooEFLSUtABRRRQAoopBS0AFFFFABRRRQAUtFFABSUtFACUUUtAxKBRiigAopaSkAtJS0lAAKWkopgLRRRQIKKKSgAooooGKKKBRQIKKKKACiikoAKKKBQAtFFFABRRRQAUUUUAFFFFABRRRQAUtJRQAUUUUAFFFFABSikpaYBRRS0AFFFFACUUtFIBKUCiigQUCiigAFFFFMAoopaACiiigAooooAKWkoFAgpaSimA6ikpaQBRRRQAUUUUAIxwDWZdnnNaEhwprLum60DRTaqs7YFWieKp3ZwKpDZkXzYLPjnHyg9KqnbjPAB7CpL6TzJNobgVC7BQBjOSK0MJMAeDQo+XHIzS5UA5xgUbht+tMQoXAwDTVI83B64oV9zDFDH5sjpQIRhznNKFJPHalcrnj9KQAZyeWxzQMRxzTo+vPPFJgk9sY6Uqg7t3GKBDgCOBj6VLEMLzTMgDJY5z6UvPYkigFuSKuOKtRFflXPJ4qomdwJq9GMocYyPWhjTOm8NRbLaRipzu2gnuBWzVPSofI0+JMH7ueauVky0LRRRQMKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAMPtRUJlAxk04SgDNOxpckpR0pnmDGc0B80WBMkptH1oyKQwoozRmkAtANAopgFA60ZooELmkoooAUUE0lFIBy0p6UzpS9aADPtThTaUUDFNANIaBQAtFJSUALS02lBoAWigUmaAFNApKWgAzS0lFAhaKQUA0ALS0UhNIBaSgGigBaKKKBi0hozSUALRRRQAoopBS0AJRRS0DFopKBQAtFFFAhaDRR1oGFFFFABRRRQAlLRRSEFGKWkoABS0lKKBhRS0lMRJAPnFXKq233qtVSIZk6kc3BqrVnUDmYn3qrmrRAGlFNpQaAHVZtRmquat2Y45pMaLK07mgUVJQx/umqkWBIfU1bl+4aqQcs1SUieg0UUDCkoopDDFKKSloAUUUlOoAKSig0AKKKQUtABRiiloASlpKKACiijFABSikooAWiigUCClFFFABS0lLQAgpaSloGJRRRQAUtJS0CCiiigYUUUUCClpKUUAFGKKM0AFKKSlFABRRRQAUUUUAFFFFABRRRQIWlFIKUUAFFFFAwooooEFFLRQAUUUUAFFFFACUtFJQAUUUCgYtFFJQAZooopAFLSdKWmAUUUlAC0UlFAgpRSUtAwFFFFAgooooAKSlooASloooAKKKKACiiigAooooAKKKKACiiigAooooAKKKSgBaKKKACloopgFLSUtABRSUtIQUUUUwCiiikAUUUUAFFFFABRRS0wCiiigAooooAKKKKAFoooFMQClpBRQAtFFFIApKWkNMCC4bC1lTnJNad0flNZM5O40iiFuBVG7k6gdauyHisi/fD5LADBGMVcRNma+GYn1prAE8DimBQcMScrnine4HX0qznYqqMcjOaDg8ClPTpTAdp9/SmAAgErjnrQM/UU5xjg9cU1RxjNACquc5PSlAwckUYwp/nTUB2YJOc9aYxx+XJBAPv0pygkZYjPsMVF25JyD3FSKx6dqBXJOqkbj1z04pyoOPSo8sQQMcHvTowxX7wTnuKBXJUxuFaFgm+VY+W3sOKoQrjgnJ9a3dBh3XkRVT8vJNJjidWihVCjoBinUUVkaC0UUUDCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDlc4PNBagEkfNRirAXdxSo5xzTCKKAuTiU9zSiSoOtFKw+YsiQU8OKp7iKXeaVh8xb3dqFbmqoc45oEpFAcxcHr2oLDtVYS8UqyUDuWOtKKhD+9PV80h3Hk0UgIpcjFABS0DpQaADsaWkopDFopM0vagApBRRQAUCiigAopaCKAEzS0go6UALS00UvagQtIeKO9L2oAAaOtNFOBzQAUClpMUgHUUlLTGApKKXNABRmig0gF7UlGeKBQMWkoooEKKKSgUAOFFFGaBiiikpRQIKBRQKBhRRRQAlLRRSEFFFFAwpRSUUCFoFFFMCa2+9Vqq1sPmqyeBVIzkYt6R57jPQ1X71Ld8zMfU1FVkBSUtGMUAKKu2n3aoir9qMRikykWAaKQUtSUMlJCmqtv1J9as3H+rNV7YcGpGibtSUtFIsSinEcUlABRRRQAoFLTRS0AJS0hooAXNLTRS0ALRSUtABRRRQAYpaTNKKACkpc0UAGKSlooAWikoFAC0UUUCCikpaBhRRRQIKWkpaBhRRRQIKKBRQAClpBS0AFFLRQAlFFFACiigUUDCigUUCCiiigAooooEKKWkooAWikpaACiiigBaSiigBaKSigApaSloASlopKACiiigYUUUUAFFFFIApaKKYBRRQKBCUUUtABSUtFABRRRQAUUUUAFFJRQAUUUUAApaKKACiiigAooooAKKKKACikpaACiiigAopKKAFooopjFooooEFFFFIAFLSUtMAooooEFFFFIAoopaAEopaSmAtJS0UAJRS0UAFFJRQAtFJS0AFFFFMApaTtS0CClpKKACg9KKR+FNAyndvwaypDkmr923JrObOaQyKVsKax71wTz1rVuDhcVh3sgLEA8A1pEmRX49Ka+BjBpQ/GCKRjx261Zix3UU0IoORnd9acMA9RTWHcdaBMbn58Ac0iqc8dSacq+vWlKjB5+agBuDjrk04ZApAAOBnPWlBOCBQAZx+NPXP8ACR+IzTFXOQR1qQD5cCgLAG65xUoVcA45NRhdxIAJqUAHapPzY6UwsSxfex610/hiIgSufTArmYFG5dvIJxmu00GIRWA9Sx5qZDiaVLSUVmaC0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAHLhMd6Nue9LRmrAaUxRinE02gQmCDSnpRS0xDaKXFGKQCUUCloGJQtFFADs0BiKaDzilosO48Sn1pfNqKilYVydJak82qhJxQGIFFh8xcDj1pd1Uw59acshpWHzFsGlzx1qqHPc05ZPWlYaZZzRUIlHrThJnvSsXckozTA49aduFAXCjNNLgUoOeR0oFccKDQDRmgYClpKM0ALQKBRmgBKUUlOoEFLSCikAE0Zo60AUDFopKMUALRRRQAtFNpc0AKBRQDRQAUCjOKBQMdRRRTAKKTNLQIM0opKKQxaKSigBRS0lFABR3oopAFFLRQIKWkFFMCxbdanY4Un2qG271LJxG30qkZyMKfmQn3plPk5dvrTKskWim5pQc0CFXk1fgGEqjGPmNX4vuCpZSJBThTVpwNSURXP+rIqG1+6akuj8pqO2GE/GkUiaijFFIoWkoFFACAUuKKWgBKKKWgBKSlooAKBRQKBBS0lFAwopKWgQtApKWgYUUUooASlpKKYC0tIKWgApKWkpAFLSUZoEKKWkzRQAUUtFAw7UUUUCEpaKKACiiigBaKKKACgUUUALRQKKACiiigAopKKAFFLTadQAUUtFAhKWkooAWiiigAooopAFFFGKYwooooEFFJS0DCkpaKACiiigApaKKACikopCClpKKYxaKSloASloooEFFFFABRSUtABRRQaAEpRSUUALS0lLQAlFLSUAFJilooAKKKKACiiigBKWkpaAEoFLRTAKKKUUgAUUUUAFFFFMApaSloAKBRRQIKKKKAAUtJS0AFFFFABSUtJQAUUUtABRRRQAUlLRQAlLRQKADFLRRQIKKKM0wAUyU4Wn1BcnC0DRnXbdapmprlsn2qBjgUhlW5OOvpWFKRIzDpWpqMvp1NY5LbsnoTWiIkxikoxUkMB/FQSG/ClbHel6dhVmItJ0zSjlc8U0HgH2oGOXATJ65xUUmSw2kg56gU4HBIJ60ob0NAARnOOKQfrRt3cCnRkAYIJz0PpQIF4GTxTt4U8HJPoOlI+857g+g6UqqRigB4Ypz0zU8Z3HJ61DuPADD8Rmpox82M5OaBlqABWX1LDArubSLybdEPUDmuS0uES3cIwPvjrXZ1EikgoooqShaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigDlgSRyKU9KQ+lL+GKskO1HFGeKbQMXmkZ1QZYge9KCaXNMQZyOKKM0mc0AIKWgUY4oATFOApOlKKAG4OeKMcU7NITQAg60uOaQUtACHvQKMZo6UgFxSY96XtQKBiE4FApSM0AUAANBY9jRikzSsFxyuad5hFRgUZosFx5kNKkpx1qI9KVRRYLk4m560/zRVYUueKLFcxbEoNKDVMORTlkNKw+YuBhRVUSGniWlYfMWBS1B5vFOElIdySlHNMDUu6kFx1JmgEGjigBaKKKYwFLSCg0gFoopM0AKBRRRQACnU2jNAx1FJRQIWjNJRTAdRSUUDFopKKAFooopCFozSCloAKWkoFAC0UUUwLVv0p9wcRN9KZbdKdc/wCpb6U0ZyMSQ5Ymo6c/3jSVZAlGaKMUAPQ81fj/ANWKz0+9Wggwg+lSy0PFLmkFFSUQ3R4+tFuB5Ypt0eKdD9wUhokFLTRTqRQlFBooAKWkzS0AFApKKACiiigBKKKKAClxQKWgBKBRilxQIMUgpaKBhS9qKKAEooooAUUUUUAFFFFABRRRQAoopKKAFoFFFAhaKSloGFFFFAgooooAWikooAWikpaAClptKKAFoopKACiiigApwptKKAFopKWgAooooAWikopALRQKKYBRRRQAUUUUAFFFFABRRRQAUUUUALRSUUgCijFFMAooooAKKKWgAooooAKKKSgQtAoooAKSiigBaKQUtABRRRQAUUUlAxaKKKBBRRRQAlFFLTGIKWkopCFooooAKKWimAUUUUAFFAopAFLRRQAUUUUxBRRRQAUtJRSAKKKKAFpKKKYBS0lLQAUUUUAFFFLTASlpKKQgpaSigBRSUUtACVVu24xVkniqF4/FAyhOOc1XlPy1Mxyear3DYQmmDMu8OTxWYwy3ToavXD9c1RLFT3Oa0Rmxr5OccGjdhQO9ORgM7gSfWkGH5FUQOUYU03cAFHfvxTsjBXvmmt6kg96AYxMlckc0obv3oBBHB+tCqGGaCRedue1Kg4BFI8ZVc9VFAXgdc9eDTHYlXg9M4p4HtTByMU9MscKM84pAKFAPHWrES81XUgnPBzVqJSQNvUmgDd8NRbrtnxwi/hXT1jeHIQkEkmMEnFbNZs0QtFFFIYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAHKUuaarDuaXINVcQoNFJRTAdRSCigBaSjOKTIoELQKDQKYC0maCaQUCFzzS0UlIApaKBTAKTNLSUgFpaSjNAxaWmilpgFJwKWkxikAfhRjJpc0ZoATFJ0p1FACAc0H6UtFADaUUYooEAFLRSZosO4uacHxTaMUrDuPEtL5xFR4oFKw7k6yGnCQHvVfNGaLDuWhIKcGFUw1O3kClYakW80uc1UWU1IJqLFcxYoxUImFPWQGlYLj6Wm7qNwoGOopu6lBFAxwoNJS0CAUtJRSAKUUgpaYBRSUUALmikopAKOlKKSgUAhTSg0lJ3oGPFJ3ozQOaYi3bfdouzi3altxhabff8e5poyZiMcsaSlI5NJViCiijFADox8wrRH3B9Kz4vvir4PFSykOU0tNHSlzipKK10ecVJF9wVFcH5qmT7opFIfQKKBSGFJS0lAC0ZpKKAFopKKAFopBRQAUUtFAhRQaBRQMKKKKACig0UALSUUUCCgUUooGFFFJQAtJS5pKBC0UUtAxKKWgCgQUUUUAFLSUUALQKKBQAUtFFADaWiigBKWikoAWlFNpRQAtLSUUALRSUZoAKUUlKKACiiloAKKKSgBaKKKAAUtJRQAUUUUAFLSUUALSUUUAKKKBRQAUlLRQAUUlKKACiiigAooooAWiiigQUUUUDCiiigQUUUUAJQKKKAClpKWgAoFFFABRRRQAUUlLQAlLSUUDCilpKYBRRRQAoFFKKKQgpKKKAFooopgFFLRSAKKKKYgooooAKWiigBKSlpKQwpaSigBaKSimAtFJRQIdRSZpRQAUtJRTAKKKKQBRRRQIKWkooGNc4BrNu261fmOFNZN2xLH0oAgz1qpdthD61aPAqhdPwR3qkDMi6JPGc9OtQEgEZqScDJxkE1Fg7Tz0OCatGTFJBGAeKbnawHrTgARkD8aQrlxg8CmIQfeYnPtTc8lcduMU98A8UzBVsg49aZNhIwq8McsfWnDCnIppO58rz604dxjgUCsPDbhtJ+XuKeFC+9RqvzcHJPanIG3uGGGU4xmmUOA74NKenQ0biDSoN/Qc/lSEPRMKMDircKEtGV7YqugIbB7cVfs1Mk6x7cg4FJjSOv0uEQ2KLjGeauU1F2oq+gxTqzLQtFFFAwooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOIWXr2xTvOPY0xlzzQBx70hEyTD1p4lB6VUI9DzTlOBTuBb34FAfNVFc7femrIxZgrd+9O4F6lxVcS46mnLNxyaLgS0tReaKUSAnrTuA8UtN3D1pdw9aLiHZopoNKGGaYgpc0h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OAcn0pFPsadjdwDg0AOQfLx196kTOMd6iGVOD0qRAWBwQPqaARJtP94Usf3sZBPtUcYK7xkHLCpo1G4EdaYixD97njNdfoMPlWGf77Zz6iuUhA3rlc5IFdxaRiG1jjHRVAqJFImoooqCxaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA5ooTSbCRU+BSYqBldos9ab9nX0qyRSYoApta7ulM+zEdqvAc0uygZmNA4JxTQhGa02jHcVH5ANAGdgmjdtYA96vm2FNe0BHbNO4rFLdSE54qwLYhQOvrTWhx0FAiLcAwB7in44qMxuTwpGKdsbaQcnikAtIOopADikzzwaoB9NxknNKGzS9+tACAYFLSBuOadn34ouAmT68UZPaj6UgouA4ucdakSTioc0UXAseaO9AlFV6adwPAyKVxFzzB60ocYqnvOacjHHWncC3uHajINVw5Bp3mVVwsT5yKUGq6zADFOEnNFxWJe9LTA1G6i4DxQaaDS07iFXPcUppoOOKdmi4wpRSZ5ooGBoFBNJmmIcaSiloAKKKKACgUUUALSUZooAM0tIKKAHCg0gooAKUfpSCloAKKKM0AGKSlBpcUANxxSCn4pDQAnalox70uKAEpDTqMUASQSbDxT7mTfjnmoOlIWzQAh60UUtAAKKBR3oGPhPIqyDzVVOKlD81LGiwCKjlkwpphkqCRiQRSsO5nzzk36gdAMmti3fKLWQ9nun80E5HatC1bC80rFJl7NFR76UNSsVcfmim5zSjpRYYtFHFFIBRS0gNLmgBKWijNABmlFJS5oGFLmm0UCHUU2lzQAtLTKcKAFooooGFLmkooAWiikoEFLRSUALQKOtFAC0UlFAC0UUmaBBSigUtAxKKKKAFopBS0CCkoooGLRSUZoEFKBSUtAwpaBRQAlFLSUCCgUlKKAFopKWgYUUUUCFoFJSigBaKSloAKSiigAooooAM0UUlAC0UUUDCiikoAWikooELS000oNAC0UmaWgAooooABRSUUDFFLSCigQtJS0lABRRSUALS0gpaACikooAKKWkoAWkoooGFGaKKBBQKKKAFopKKAFpc02loAWikozQIXNFJS0wAUtJS0gCiiigBaKKSmAUtJRQAtNpaSgAooooGLRRRQAUUCigQUUUUgFpRTaUUCFooopgFFFFABUcxwpqSq9y2FNAGbdHk1VPAqaZssaryH5aaGUrxxg+orFlcMSxOfpWpesMGscfez2q0RIQnAHvQQeCD+FBUZzml3YAxzxVGQUcEEHkUJ1PP4Uh49qYEasduD8p7inYXdkE4PrQQASeue1NT7p4I9KBEi4JIFKDzz0psBf72AcAjFPGSACOnpQNClhnHOakGAvI5NRpg80/AYgsTgelAmPX06+9SJ7VGOD8ueatQABSMdTmgFcv6Vbie6hRgeucV2grmfDKb7jd18tOtdPUSNELSUUVIxaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAwBS0UYqBiUYpQKAKBjcUtLRQAlJTsUlACEUm3Jp2KKAGbAKayA1NjmkOKBEHl4zxTWgB7VYxRigCoYB6VG1tnNXitG3imIzGtmBAVc56mmCFwTmtQrSGMelAGW6lVyRimjPoa1PJU9VBpjQj0oAz0Zudw4zxRuq29uDxUZs8gjkCgCsWpQc082ZXoSfrSCBlNAgGM0jGlIYD7pNMVwykgUhjlw3WlxjPBpobn0pdw9aYDqMU3PvSg+9Fxi0ZPYUA0tMBvmsKPMU4LZx14pdvWmFRgCgmxKZwDncKcs2e9QqoHYU7bxQFidZBT/MqpgjpS5YUXCxb3ZoBqosjDvTvPNNMC1mlBBqqJSetO84KKYFjNGaj8ylDU7gSUU3cKUGi4C0gozRQAuaWm0opiFzxRRRQMM0Ug606kIM0lJSimAtJRQKAFFOzTRRQAuaKKSgQuc0tNBpTQMWigUCgBCcCmg5pW6U1TQMcKU0gooABRRmkJoEODCnA1BuwalU8Uikx2aQilBoPNADSBSqcUUUAODU4PimDpRSC5IJaestV6Wiw+YseZTw4NVMmlDEUrD5i2HHrQGqqJDThJSsPmLQbNLmqwkp4lFKw7kwoqMSClDigdx9LTQwpQc0DuLRQDRQAUopKWgBaBSE0A0gFpaTPFANAC0lFFAC0UlAoAWiiigBaKM0ZoAKSlooABTqbTqACkpaKAEooooADS0lFAC0UlLQAUCigUAL0ooooASloooEJSiiigAooooAKKKKAClpKUUAFFLRQAlFFFACUtFFABSUtFABRRRQMSiiigQUUUUAFAoooGOooFJQIWkoooAKKKKAFFFAooAKSlpKACiilFABRSUUDHUlJmloEFFFFABSUtFAwooooAKKKKACiiigQUopKWgAooooASloxRTAKWgUUhBS0lFAC0UUmaADNLSUUALmkoooAKBRRTGLRRRSEFFFFABRRSUALS0lKKAFopKWmIKKSigAzVO6brVtjwaz7tutAyhIf3hNQSng+1Ssck1WunC/lTQMy76RefmwxGFrNjj2gAscAfnVi/G9gc4KnNRIcqT6VojFu40phs5pNvXJJzSkjoRmkzVE2GKCDnPFP+vIPakUhmIJA780kh2tweBQC2Eb5SMYFIBubP6Ubg3PX6Uo5Pv6UCHlz/dINOQ5GT2poG4fSgv5ZAx1PXFA9tSVRmQlsY9qcVw3XNJzjPGfal3ZAHqKAJUNWI89hVRM5HWr0IIXnoB2oHFnTeGIdlm8hHLNgVtCqekwmGwjVhgkbsfWrlZspC0UUUhhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAGDRQBQKgYooopKBgKKBS0AJSClIooAOtHelFBoASkPWnUlAhBRRiigAxRSmkoEFAFKKKYxuKTbTzSAcUCI9vNBWpKUDNICHy6Qxg9RU/TNMxk0AVzCPSmNbr/AHRVzAppFMCkbZfSovspU4FaQUUhQCkBmNCyg0gUkZxWl5Y/Ck8lT2oGZnOelGSK0GtlweKiazBx2xQBUDH1xQMGrDW2DxTWtyOlO4iMGjNIYW9CKbtYN04oAeT1ozTeRRmgBcYoKgikz1pc5ouFhpQ9jShSRjNKGoBp3CwgZgxz0xQZCBmlYjHNIOlADxIwHNOWY8VGaBQBOJqXzqgxSEccU7gWhKCM04NVMdOKQO6g96dxF8NS7s9Ko+cwHvUizYApXAsg0vWq4mBqRZRg8ii4EgozUayZFO3Zp3EOB4pQaYCKXNMB4opoajORQA49KQHNJnIoHApiFFLmkpQaAFoFJQKQwY4FMTpSynikj+6KBjqXNAoNMQho7UUUCIjjPPWpl6VEfvVKooGKKXNIOtBoC4ZozSUUgH0lAoNAwooooAWikzRTAWkpRSYpWGLmkzSmm4osK44ORT/MNRUUrDUiYSGnCWoQaKLDuWRLSiQVVBpwOaVhplrzB604PxVPdigSEUrDuXQwpc1UWU07z/Wiw7lnNANVxNmnCUUrBcnzRmovNHrShwaVh3JKKaGpQaAHUZpKWgBc0optLQMWiiigApRTc0tAC0UZooAKKM0CgAooooAKWikoAKBRQKAFpaSigAoozRQAtApKUUCFpKO1FAwooooAKWkooAWlpKWgQUlLRQMSiiigApe1JRQAGiikoEKKSiigYtAoooEFFFFAxaSijFAgpKWigBKWkFLQAUtIKWgApKKKACikpaACg0UUAFFFFAC0UUUDCiiigQUUUUDCiiigAoopKAFoo7UUCClpKBQAtLSUUAKKSilFABRRRQIKSiigApaSloASloFJQAtFJRQMWlpKKBC0UUUAFJS0lAC0UlLQAUtJRQAuaKSigBshwprMum61oTHCmsq5bJIpgVzVLUGwpI9KuPWffv8AJ71SE9jJuGy3vUNOdtxJ96bmtEZXEbFDDLD6UMMnOeKUj5eOuaBMBlfxppxzT2bI5A+mKaeRnApisMVTyTT0B/D6U0HdTgTnjpQApbbmlzubcaZvBBJHANPxzxjFAMcGyBjpT1+7ntUYUjjtUkTrjYOqj0pEkiHy8EDduxWnYR750A5yQCKo243sMjAA6Gtnw/BuvweGA6+1DNEdZGu1FX0AFOoorMoWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiig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BcbyKXJ9adim4pWHcAxpwkxTcUmKVhpkolpwlqCjOKXKPmLQmp4lqmDShiKXKUpFwSU4MKp+ZxSiUilYOYu5o3VUEp9acJaVh3LOaKhEtOEmaVh3JaKYHFLuFMLjqKM0ZpAKKKSlzQAUUUUDCigUUAGKKKKAClFFJQIXNFJRmgY6ikooEFFFFAC0UlFAxRS0gpaBBRRSUALRSUUALRSCloAKSlooASlpKKBhS0UUAJRS4pKACiiigAooooAKWiigApKKKBCiikpaAClpKKAFpaSigApaSlpgFJS4oxQAUUuKSgBKKXFJSAKBRS0AFFFJQAtFFFAgooooAKWkopgFLSUUALUNw3ympaq3LcGgDOuG+aq7ng1JN96opDhc0wM69cbTWNI4cnCkDPQ1pX7NyFGSO2aymOSc8A1aIkxQFxnvSgKRknkcYpg4PFOCjJJHWmZodTS454JpcdetNPHAzTBh94Y6UKAc89KRT15zQJMNgg4xgj1oJHZxwRTgy555PtSY3AE0A4NMLjxyakA5GMA880xRuNPVQrd6BhtwQGwT7VahBAz2qJenvU6glcL1pDRu+HLcPdebgYRevvXT1i+GIito7kcE4FbVQ2UhaSlpKQxaKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAOfGdvWnDmgCisxhRSHrSimAUUYo6UDCjtRRQIKKByKKADNJS4o49aBCUtFKKBgDRRRQAlAoNAoAMUpoooASig0o4oAKTNLjIpMUAFKBRiigApKWigBMc0tIOtLQAUUUUAJRS0lAC0UUCkAUUUlAwooopiCiiigQUYzRRQACiiigBe1JRS0AJRRQKACkpaSgBcUmKWigBMUUtJQAYopaSgBKKWigAFIRS0UANxSYp1JTAaQKrTLVk1BP0NMCNKk7VHH1qWrQhRQaKKBiYpGPFONMYcUhFYffNSkcUxPvGn4zSGRulVZX2jpVx6ozKXlCrjNIBUfKjjFOBoFuygZ60CJs9KAHrRSYII4oGcnigBcA0owOBTM80oPNAD896QOeo6GkHSlyKAFDt2p4mI60wEY4FHU0CJlnxUiXB/CqhA9aUHHFFwLnnAGpBLkVRB4pQxHei4WL4lXHWnK4Pes7eQDQspTFVcVjTzS1RF16U5Lo55ouBdo4qAT+9PWUHvTuMfilpocU7I9adxBRilGDS4oAbilApcUYpgNpRS4oxQAlApSKQCgAFLQBS0AJRS4oAoEJS4pcUUwExRS0UAIKXGaAKdigY3FGKUUtAhm2jbTqXrQBHto2VLijFICApSbc1OVpAuKAIdtG01Nto20DICDSYqcx8U0x0rARiinlaTZRYLibiKcHNJtpMUuUq4/zDSiU9%E2%80%A6", folderName: "Protonet Messenger", quality: 100, width: 100, height: 100, base64: true};
window.ImageResizer.resize(options, function(image) { debugger; // success: image is the new resized image }, function(i) { debugger; // failed: grumpy cat likes this function });
Always execute the error function and i="Error"
Thanks for the great free plugin.
Documentation should be slightly more clear. I don't clearly get if the proportion of the image is changed.
width: 1280,
height: 1280
Shouldn't it work also by just providing either width
or height
and not mandatorily both?
Thanks
Hi,
This plugin is working as a charm but suddenly it stopped working, we found that its working well till till Android 7.0 but not in Android Oreo 8.0.
We are getting "Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference".
I see that its not able to create folder and compressed file in given folder.
Please let us know if you found any work around for Android 8.0.
thank you
Bonjouur, on IOS, I can not display the image, do you have a solution?
(On android it works well)
In package.json and config.xml, this plugin has an ID of "info.protonet.imageresizer" but has a name of "cordova-plugin-image-resizer" in package.json. This is confusing either npm, Ionic, or cordova, and causing the plugin to be put into package.json twice:
"cordova-plugin-image-resizer": "https://github.com/protonet/cordova-plugin-image-resizer.git",
"info.protonet.imageresizer": "https://github.com/protonet/cordova-plugin-image-resizer.git"
The simple solution seems to be to make these match. I would submit a PR, but I'm not sure what name would be preferable.
Hi @JoschkaSchulz,
I am using your plugin and upon using it the Image dimension is not working by setting the width and height in the actual device but when i use the emulator it works fine.
Regards,
Greg
I Captured and image and then selected that image from galary and it is showing -90 degree rotated
If you add orientation option this plugin will be best
@JoschkaSchulz,
Are you open for PR?
I've made following enhancements (all for android):
fit
to fit input image within bounds (options.width and options.height)For Android, if we give the nested value for folderName property, it throws exception:
Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference.
sample object-
{fileName:"test.jpg",
folderName:"ParentFolder/ChildFolder",
height:768,
quality:100,
uri:"file:///storage/emulated/0/img1.jpg",
width:1024
}
Basically, i would like to copy the resized image in a nested folder, not in only parent folder.
So, if the value of folderName is 'ParentFolder', it works.
Can you please fix this issue so that the resized image gets copied to other nested folders.
Hey all readers of that issue...
At the moment I don't really have much time to take care of this repo... I never thought that it would get mentioned in the documentation of ionic and I have no idea how it get there. If someone feels fine to help maintaining this or at least fork this repo and done more cool stuff with it in the future I would be happy to add the person here or would write a link to the fork in readme,... someone interested?
I would like to be able to access the DCIM / Camera folders and save my images there is some way to save my images in that folder
Here's my build log:
:CordovaLib:compileReleaseJavaWithJavac
:CordovaLib:transformClassesAndResourcesWithPrepareIntermediateJarsForRelease
:app:preBuild UP-TO-DATE
:app:preReleaseBuild
Download https://maven.google.com/com/android/support/appcompat-v7/maven-metadata.xml
Download https://maven.google.com/com/android/support/appcompat-v7/23.4.0/appcompat-v7-23.4.0.pom
Download https://jcenter.bintray.com/com/android/support/appcompat-v7/maven-metadata.xml
Download https://jitpack.io/com/github/ergovia-mobile/android-transcoder/v0.1.10R_ergovia/android-transcoder-v0.1.10R_ergovia.pom
Download https://jitpack.io/com/github/ergovia-mobile/android-transcoder/v0.1.10R_ergovia/android-transcoder-v0.1.10R_ergovia.aar
:app:compileReleaseAidl
:CordovaLib:packageReleaseRenderscript NO-SOURCE
:app:compileReleaseRenderscript
:app:checkReleaseManifest
:app:generateReleaseBuildConfig
:app:prepareLintJar
:app:generateReleaseResValues
:app:generateReleaseResources
:app:mergeReleaseResources
:app:createReleaseCompatibleScreenManifests
:app:processReleaseManifest
/usr/src/app/platforms/android/app/src/main/java/info/protonet/imageresizer/ImageResizer.java:15: error: package org.apache.cordova.camera does not exist
import org.apache.cordova.camera.FileHelper;
^
/usr/src/app/platforms/android/app/src/main/java/info/protonet/imageresizer/ImageResizer.java:92: error: cannot find symbol
BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(uriString, cordova), null, options);
^
symbol: variable FileHelper
location: class ImageResizer
/usr/src/app/platforms/android/app/src/main/java/info/protonet/imageresizer/ImageResizer.java:99: error: cannot find symbol
Bitmap unscaledBitmap = BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(uriString, cordova), null, options);
^
symbol: variable FileHelper
location: class ImageResizer
I'm trying to install this plugin but I have the next issue:
Failed to fetch plugin https://github.com/protonet/cordova-plugin-image-resizer.git via registry.
Probably this is either a connection problem, or plugin spec is incorrect.
Check your connection and plugin name/version/URL.
Failed to get absolute path to installed module
This is my enviroment:
Ionic:
ionic (Ionic CLI) : 4.2.1 (/usr/local/lib/node_modules/ionic)
Ionic Framework : ionic-angular 3.9.2
@ionic/app-scripts : 3.2.0
Cordova:
cordova (Cordova CLI) : 8.1.2 ([email protected])
Cordova Platforms : android 6.4.0
Cordova Plugins : no whitelisted plugins (15 plugins total)
System:
NodeJS : v8.11.1 (/usr/local/bin/node)
npm : 6.4.1
OS : macOS
When trying to resize an image on iOS 12.x no errors shown but the resized image is empty (just white background).
The problem seems to be due to the path assets-library:// which is not supported (for example "assets-library://asset/asset.JPG?id=8458AC82-B00F-4595-8B78-A135643A3AB3&ext=JPG")
Using cordova file plugin and window.resolveLocalFileSystemURL to convert the file to cdv file path seems to fix the problem and the image is resized correctly.
I have real problem on resizing images before upload to firebase in my Ionic 1 app , i just found this plugin and i hope it can help me , can any one advise if it is tested in ionic 1 app .
Hello!
it doesn't work for iOS, nothing happens when I use it:
ionic 2 code ex:
//Start
Camera.getPicture(options).then((imageUrl) => {
console.log(imageUrl); //it's displayed the right image path
let options = {
uri: results[i],
quality: 70,
width: 570,
height: 430
} as ImageResizerOptions;
//Starting with this line nothing happens, any error/log displayed
ImageResizer.resize(options)
.then((filePath) => {
console.log(filePath);
}, err => {
console.log(err);
}
);
}
});
PS: on android it works fine
Thanks, Victor
It seems to be dependant on the cordova-camera-plugin which I'm not currently using in my project.
const options: CameraOptions = {
quality: 100,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
alert(imageData);
this.imageResizer.resize({
uri:imageData,
folderName:'trouble',
quality:50,
height:200,
width:200,
}).then((path:string) =>{
alert(path);
if (this.platform.is('android')) {
this.cameraUrl = path;
this.uploadPhoto(path);
}
})
//this.uploadPhoto(imageData)
}, (err) => {
console.log(err);
});
Here is my code....my resize function does get executed without the error , but the new image is not populating(generated), the rest of the code is working fine ,as i have tested it . I have to upload an image which has to be resized.
Thank You
Hi!
I am developing a iOS app using Ionic 1.7.15 and Cordova 6.2.0. The app downloads a lot of imagens from the internet and I want to generate a thumbnail for each imagen downloaded. So I can have two versions of each image, the thumbnail and the original one.
The plugin works just fine in Android. But in my iPad 2, the app crashes after resizing lots of imagens (lets say after 500 imagens).
I wonder if I am doing something wrong, forgetting to free some resources or something like that.
Here is the code I am doing:
var filePath = cordova.file.dataDirectory + image.fileName;
var options = {
uri: filePath,
image:image.fileName,
folderName: "Thumbnails",
quality: 100,
width: 170,
height: 140};
window.ImageResizer.resize(options,
function(thumbnailPath) {
RepositoryService.updateImage(resultado.nativeURL, thumbnailPath, image.id)
.then(function() {
resolve({"id": image.id, "fileName": image.fileName});
}).catch(function(error) {
console.log(error);
reject({"description": "Error updating image on the database", "error": error});
});
}, function(error) {
// failed: grumpy cat likes this function
console.log(error);
});
I have also posted on Stack Overflow, hoping that someone could help me identify the problem:
https://stackoverflow.com/questions/37923566/ionic-ios-app-crashes-after-resizing-lots-of-imagens
Update NPM please.
In NPM 0.1.1 is last version, but I need 0.2 features for Android (base64), thanks!
Note: NPM is not auto sync
Alternative solution
Install using command:
npm i github:JoschkaSchulz/cordova-plugin-image-resizer#v0.2.0
Or put in your package.json
"cordova-plugin-simple-image-resizer": "github:JoschkaSchulz/cordova-plugin-image-resizer#v0.2.0",
Plugin does not compile with latest version of java.
build 1.8.0_66-b17
[removed for brevity]/ImageResizer.java:15: error: cannot find symbol
import org.apache.cordova.FileHelper;
^
symbol: class FileHelper
location: package org.apache.cordova
[removed for brevity]/protonet/imageresizer/ImageResizer.java:84: error: cannot find symbol
BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(uriString, cordova), null, options);
^
symbol: variable FileHelper
location: class ImageResizer
[removed for brevity]/protonet/imageresizer/ImageResizer.java:91: error: cannot find symbol
Bitmap unscaledBitmap = BitmapFactory.decodeStream(FileHelper.getInputStreamFromUriString(uriString, cordova), null, options);
^
symbol: variable FileHelper
location: class ImageResizer
Hi, here's my build log:
`$ cordova build android
ANDROID_HOME=E:\android\Sdk
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_161
Reading build config file: E:\movil_phonegap\indata1\build.json
Reading the keystore from: E:\movil_phonegap\indata1\largekey.keystore
Subproject Path: CordovaLib
null
The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
at build_2a96tzvbki9m3komuie0misov.run(E:\movil_phonegap\indata1\platforms\android\build.gradle:146)
org.xwalk:xwalk_core_library:23+
The JavaCompile.setDependencyCacheDir() method has been deprecated and is scheduled to be removed in Gradle 4.0.
Incremental java compilation is an incubating feature.
The TaskInputs.source(Object) method has been deprecated and is scheduled to be removed in Gradle 4.0. Please use TaskInputs.file(Object).skipWhenEmpty() instead.
BUILD FAILED
Total time: 3.543 secs
FAILURE: Build failed with an exception.
Could not find exifinterface.jar (com.android.support:exifinterface:27.1.1).
Searched in the following locations:
https://jcenter.bintray.com/com/android/support/exifinterface/27.1.1/exifinterface-27.1.1.jar
Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
(node:19588) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: cmd: Command failed with exit code 1 Error output:
FAILURE: Build failed with an exception.
What went wrong:
A problem occurred configuring root project 'android'.
Could not find exifinterface.jar (com.android.support:exifinterface:27.1.1).
Searched in the following locations:
https://jcenter.bintray.com/com/android/support/exifinterface/27.1.1/exifinterface-27.1.1.jar`
base64: true not work in Android, returns file:/// uri scheme, code:
(<any>window).ImageResizer.resize({
uri: url,
quality: 90,
width: 320,
height: 240,
base64: true
}, (data) => {
console.log('RESPONSE', JSON.stringify(data));
}, (err) => {
console.log('ERROR', JSON.stringify(err));
});
Is returned a url like this: file:///storage/emulated/0/1554074577205.jpg
Hello,
After installing the plugin on Android platform, I get the following error:
/platforms/android/src/info/protonet/imageresizer/ImageResizer.java:12: error: package org.apache.cordova.camera does not exist
import org.apache.cordova.camera.FileHelper;
Guess, this happens because of missing FileHelper class from cordova-plugin-camera. I tried copying getInputStreamFromUriString to this plugin, but it requires other imports and methods, so I gave up after dozens of build errors.
I guess we should specify dependency on cordova-plugin-camera in your plugin.xml or ship the FileHelper with the plugin.
My builds started failing after the latest changes to the plugin.xml
file. I'm getting this error
A problem occurred evaluating root project 'android'.
> Could not get unknown property 'ANDROID_EXIFINTERFACES_VERSION' for object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
After looking at where the build is failing it pointed me to my build.gradle file. It's failing here
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
// SUB-PROJECT DEPENDENCIES START
debugCompile(project(path: "CordovaLib", configuration: "debug"))
releaseCompile(project(path: "CordovaLib", configuration: "release"))
compile "com.android.support:support-v4:24.1.1+"
compile "com.android.support:exifinterface:$ANDROID_EXIFINTERFACES_VERSION"
// FAILS HERE ^^
// SUB-PROJECT DEPENDENCIES END
}
It looks like the variable ANDROID_EXIFINTERFACES_VERSION
isn't getting properly replaced in the build.gradle file. Any idea why this is happening?
On IOS 12+ the base64 string is empty.
In options I gave a base64 image string but in return only this string "data:image/jpeg;base64," was coming back in success function.
I am unable to use the resize function in iOS... it is giving the following error:
TypeError: undefined is not an object (evaluating 'window.ImageResizer.resize')
please advice..
code:
window.imageResizer.resizeImage(
function(data) {
console.log("resizeImage : \r\n" + data);
}
, function (error) {
console.log("Error : \r\n" + error);
}, imageURI, 750, 750, {
resizeType: ImageResizer.RESIZE_TYPE_PIXEL,
imageDataType: ImageResizer.IMAGE_DATA_TYPE_URL,
format: ImageResizer.FORMAT_JPG
}
);
If you imageURI is an image chosen from gallery "content://media/external/images/media/5045"
the plugin crashes the app.
More info:
cordova -v 6.1.0
cordova platform version android 5.1.1
cordova-plugin-image-resizer 1.0.0 "ImageResizer"
android version 4 - 5
code for getting the image from the device:
navigator.camera.getPicture(
that.photoTaken,
that.onCaptureFail, {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
mediaType: Camera.MediaType.PICTURE,
saveToPhotoAlbum: true
}
);
Am I correct in my impression that the plugin does not keep the aspect ratio of the resized image in ios. In android the aspect ratio is maintained but not so in ios. If true is there a way we can keep the aspect ration as we resize in ios.
“Cannot read property 'apply' of undefined”
my code
`getPicture() {
var options: CameraOptions = {
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit: true,
mediaType: 0,
};
Camera.getPicture(options).then((fileUri) => {
let options: ImageResizerOptions = {
uri: fileUri,
folderName: cordova.file.externalCacheDirectory,
quality: 90,
width: 1280,
height: 1280
};
ImageResizer.resize(options).then(img => {
var d = img;
}).catch(err => {
alert(err)
});
});`
Hi guys, I have an issue about synchronous executing of resizing an image.
It works ok when u have small size one image, but when u try to resize a lot of large size images the app freezes. I just wrapped up code into runnable and it works much faster and app doesn't freeze. Maybe someone could create pull request to fix it(I am not an expert in Java, but it takes just few lines of code)? Don't know if contributor is still here...
i have a question about displaying a resized image
i'm doing this with cordova on android.
cordova has a property called cordova.file.applicationDirectory that maps to the uri file:///android_asset/
thru trial and error i have discovered android_asset contains the standard cordova directory named www
i have placed sample.jpg in www and referenced it in the following example
var options = {
uri: cordova.file.applicationDirectory + "www/sample.jpg",
folderName: "www",
filename: "resized.jpg",
quality: 90,
width: 32,
height: 32};
window.ImageResizer.resize(options,
function(image) {
alert("resize success");
var htmlToAppend = '<img src="www/resized.jpg" />';
$('#scaled').append(htmlToAppend);
},
function() {
alert("FAIL");
});
however, when this runs, no image displays.
what is the recommended way to reference a resized image?
Is it possible to resize base64 image data? Thanks
2016-09-15 21:29:21.145 thumbnail[239:11885] IMAGE RESIZER START ----------------------------------------------------------------------------
2016-09-15 21:29:21.146 thumbnail[239:11885] Image Resizer Image URL : file:///var/mobile/Containers/Data/Application/288FAECE-4A71-450E-A35A-2F9A7A175772/tmp/cdv_photo_007.jpg
2016-09-15 21:29:21.173 thumbnail[239:11885] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]'
*** First throw call stack:
(0x2507791b 0x24812e17 0x24f8c871 0x24f96a21 0x11f02f 0x135c09 0x1354df 0x136955 0x258a16df 0x25039dff 0x250399ed 0x25037d5b 0x24f87229 0x24f87015 0x26577ac9 0x2965b189 0x109cfb 0x24c2f873)
libc++abi.dylib: terminating with uncaught exception of type NSException
The same code works perfectly in Android.
My environment is Cordova 5.3.3, Xcode 7.3.1, Deployment target 9.3
I attached the js source code too.
Thanks for all
app.txt
An obscure JSON exception is triggered on android if you forgot to include folderName key in your config. Should probably mention this in docs.
In general, it seems errors don't bubble through to the web console and with logcat they are also obscure as the original error isnt printed.
This probably applies to other config keys too.
Using XCode 7.3.1, Cordova 5.4.1, building for iOS 9.3.
I needed to add the element <framework src="Photos.framework" />
to the iOS platform element in plugin.xml:
<plugin>
..
<platform name="ios">
..
<framework src="Photos.framework" />
</platform>
</plugin>
Otherwise the build was throwing errors such as:
Undefined symbols for architecture armv7:
"_OBJC_CLASS_$_PHImageManager", referenced from:
objc-class-ref in ImageResizer.o
"_OBJC_CLASS_$_PHAsset", referenced from:
objc-class-ref in ImageResizer.o
"_OBJC_CLASS_$_PHImageRequestOptions", referenced from:
objc-class-ref in ImageResizer.o
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
** BUILD FAILED **
Currently as mentioned in the doc fileName(String): A custom name for the file. Default name is a timestamp. android and windows only. Could you please add this support to IOS. This will be of great help as it will work in all 3 platforms.
I am trying to resize an image which has a transparent background. After resizing the image comes with a black background. I did some google around this. I found this solution.
I have used the following code for compressing the images in android. Now it's working fine.
bitmap.setHasAlpha(true); bitmap.compress(Bitmap.CompressFormat.PNG, quality, out);
Please do the above changes in source code.
Thanks in advance.
Hey,
I am afraid that thid plugin is losing all the EXIF data after resizing!
It means that the portrait pictures will be saved as landscape, which is a main issue.
I'm using Android Samsung A5
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.