Categories
discuss

Setting values in thymeleaf using a map

I Generates a checkbox list from the map. Now how to set the value for the key (false / true) and now I can download it in UserConfig so that I can use this value in the rest of the project.

My view:

<body>
<main>
    <form th:action="@{/file/uploadFile}" enctype="multipart/form-data" method="POST"/>
    <fieldset>
        <legend>Generate Report</legend>
            <label> Upload File
                <input name="file" type="file" required/>
                <input type="submit" value="Upload"/>
            </label>
            <label th:each="item : ${userConfig.isEnableMap}">
                <input type="checkbox" id="" th:text="${item.key}" th:value="${item.value}"/>
            </label>
        </form>
    </fieldset>
</main>
</body>

My class UserConfig :

    @Component
public class UserConfig {

    private Map<String, Boolean> isEnableMap = new HashMap<>();

    public UserConfig() {
        isEnableMap.put(EnableProcess.MONTHLY_TIME_UPDATE.getName(), false);
        isEnableMap.put(EnableProcess.SUM.getName(), false);
        isEnableMap.put(EnableProcess.HIDE_COLUMNS.getName(), true);
    }

    public UserConfig(Map<String, Boolean> isEnableMap) {
        this.isEnableMap = isEnableMap;
    }

    public Map<String, Boolean> getIsEnableMap() {
        return isEnableMap;
    }

    public void setIsEnableMap(Map<String, Boolean> isEnableMap) {
        this.isEnableMap = isEnableMap;
    }


    public enum EnableProcess {
        MONTHLY_TIME_UPDATE("Monthly time update"), SUM("Sum"), HIDE_COLUMNS("Hide columns");

        private final String name;

        EnableProcess(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

Controller

  @PostMapping(value = "/uploadFile", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<Resource> uploadFile(@RequestParam("file") MultipartFile file, @ModelAttribute("userConfig") UserConfig userConfig) {
    String fileName = file.getOriginalFilename();
    if (getExtension(fileName).equals("XLSX") || getExtension(fileName).equals("XLS")) {
        XSSFWorkbook workbook = reportService.processFile(file);
        reportService.writeWorkbook(workbook);
    }
    Resource resource = new ClassPathResource("temp/" + reportConst.getTempFileName());
    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename="" + reportConst.getTempFileName() + """);
    return new ResponseEntity<>(resource, headers, HttpStatus.OK);
}

I do not use the database. It only needs the values to be saved for the purpose of generating the report

Answer

With Preprocessing (if I got you right), we could try something like:

<input th:field="*{userConfig.isEnableMap['__${item.key}__']}" ... />

… assuming the rest works. 😉

Categories
discuss

How can I specify location of AndroidManifest.xml?

I’m porting a module from Eclipse to Android Studio/Gradle, and need to specify the locations of my sources, resources, and manifest:

sourceSets {
    main {
        manifest {
            srcFile './AndroidManifest.xml'
        }
        java {
            srcDirs = ["src"]
        }
        resources {
            srcDirs = ["resource"]
        }
    }
}       

Android Studio/Gradle seems perfectly happy with my java and resources entries, but balks at my manifest entry:

No signature of method: build_b4wnchd9ct4a5qt388vbbtbpz.sourceSets() is applicable for argument types: (build_b4wnchd9ct4a5qt388vbbtbpz$_run_closure2) values: [build_b4wnchd9ct4a5qt388vbbtbpz$_run_closure2@35290d54]

All of my googling and searching SO suggests that this should have worked.

Arctic Fox, 2020.3.1. Not sure which version of Gradle came with it.

Answer

Ahh, figured it out. Leaving here in case someone else has the same question.

Add an android.sourceSets.manifest.srcFile entry to your module’s build.gradle file:

android {
    ...
    sourceSets {
        main {
            manifest {
                srcFile './AndroidManifest.xml'
            }
        }
    }
}

or simply:

android {
    ...
    sourceSets.main.manifest.srcFile './AndroidManifest.xml'
}

My biggest mistake was not putting the sourceSets directive inside the android directive.

Categories
discuss

How to setup lint-staged for Vue projects?

I created a new Vue3 app using the Vue CLI and selected Prettier for my linter config. I want to use commitlint, husky and lint-staged to validate commit messages and lint the code before pushing it.

What I did

Based on https://commitlint.js.org/#/guides-local-setup I setup commitlint with husky

npm install --save-dev @commitlint/{cli,config-conventional}
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

npm install husky --save-dev
npx husky install
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'

Based on https://github.com/okonet/lint-staged#installation-and-setup I setup lint-staged

npx mrm@2 lint-staged

and inside the package.json I replace

"lint-staged": {
  "*.js": "eslint --cache --fix"
}

with

"lint-staged": {
  "*": "npm run lint"
}

The problem

When modifying the README.md file in the project to

# my-repo

---

new commit

and try to commit that I get the following error message

> git -c user.useConfigOnly=true commit --quiet --allow-empty-message --file -
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *
[STARTED] npm run lint
[FAILED] npm run lint [FAILED]
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SKIPPED] Skipped because of errors from tasks.
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...

✖ npm run lint:

> my-repo@0.1.0 lint
> vue-cli-service lint "/home/.../my-repo/README.md"

error: Parsing error: Invalid character at README.md:1:1:
> 1 | # my-repo
    | ^
  2 |
  3 | ---
  4 |


1 error found.
npm ERR! code 1
npm ERR! path /home/my-repo
npm ERR! command failed
npm ERR! command sh -c lint-staged

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/.../.npm/_logs/2021-12-27T10_07_27_498Z-debug.log
husky - pre-commit hook exited with code 1 (error)

What it should do

Only fix the files that have been modified. The linter knows about files it is able to fix (js, ts, vue, html, …).

When having a modified markdown file I get no errors when opening the terminal and run npm run lint. But I do get errors when using lint-staged with this setup "*": "npm run lint"

What is the correct setup for lint-staged to lint “lintable” files only?

Answer

Update regarding the comments

Other lint-staged syntaxes

I’ve suggested "**/*.{js,vue}": ["npm run lint:js:fix"], first of, lint:js:fix is subjective and up to you. This is what Kent C Dodds is using, so I’m just naming it in the same way.

But you could totally have lint:watermelon-potato-hehe instead, doesn’t matter.

Now, about your propositions:

  1. "**/*.{vue,js,jsx,ts,tsx}": "npm run lint", this one is targeting more extensions, which is totally fine. You may not really use .tsx/.jsx since it’s not really popular among Vue devs.
    About .ts itself, it may probably work good enough (maybe you’ll need to add some plugins to your ESlint configuration). I’m not into TS so I can’t really help on this one but it’s out of the husky/lint-staged scope anyway.
    Last time I started a Vue3 project, I’ve used Vitesse which has some nice defaults with TS, this may be a good start for you maybe.

As for the second part, since I like to setup my own ESlint config, with some simple and well documented API, we’re using eslint --ext .js,.vue --fix. That way I’m sure of what is happening and how to troubleshoot it if needed.
vue-cli-service lint may be a good default package aimed towards Vue with some defaults, I’m not sure what’s inside it and even if it’s probably just an ESlint with some baked-in configuration, again we prefer to make our own Vue configuration with vanilla ESlint.

So yeah, if you need to go fast, use vue-cli-service lint for some quick linting, if you want to have a better flow in your project and want to fine grain your config, use vanilla ESlint, you’ll get less trouble overall IMO.

  1. "**/*.{vue,js,jsx,ts,tsx}": "eslint --ext .vue,.js,.jsx,.ts,.tsx --fix". On the right side, we globally have the same lint:js:fix scripts but with additional extensions.

So, you may ask why are we even writing the extensions on the left side for lint-staged and on the right side for lint:js:fix? I’d answer that those are not really needed on the right side (AFAIK), because lint-staged will only run the command to the left list of extensions.
Here, we wanted to be more explicit about the exact extensions we’re targeting and also, it enables you to run npm run lint:js:fix in your CLI at any given point without getting errors on files ESlint is not handling (.txt, .json, .md, .jpg etc…).
So it could maybe be removed (not sure), fastest way to be sure is to try!

  1. "**/*.{vue,js,jsx,ts,tsx}": "eslint --fix", this one may work fine as explained in the previous paragraph. Didn’t tried it myself thought.
What about the other extensions?

Regarding .html, you should not have a lot of those in your Vue project. You could use the W3C validator to check for any errors if you really need it.
If you’re speaking about your HTML in the template tags in your .vue files, those will be ESlint’ed properly. If you setup a Prettier on top of it, you will also get some nice auto-formatting which is really awesome to work with (once your team has agreed on a .prettierrc config).

Regarding .json files, those are not handled by ESlint. ESlint is only for JavaScript-ish files. If you want to lint/format your .json or even any other extensions at all, you can aim towards NPM, find a package that suits your team’s needs and add it to your chain like "**/*.json": ["npm run lint-my-json-please"] and you should be good!

At the end, husky + lint-staged are not doing anything special really. They are tools to automate what you could write yourself in a CLI, so if it’s working when done manually and you’re happy with the result, you can put it in your config but you need to first found what the proper package and it’s configuration.


In your package.json, you could have the following

"scripts": {
  "lint:js": "eslint . --ext .js,.vue",
  "lint:js:fix": "eslint --ext .js,.vue --fix",
},

In your .lintstagedrc

{
  "**/*.{js,vue}": ["npm run lint:js:fix"]
}

In .husky/pre-commit

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint-staged

In .husky/commit-msg

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit ""

You can setup ESlint to watch any errors in your files in VScode (a lint + formatter when your files are saved is also doable pretty easily).

That way, you can run npm run lint:js to check the issues by yourself.
Otherwise, let husky run lint-staged and apply the eslint --fix to all of your .js and .vue files.

Your commitlint.config.js config should be okay!


As a reminder here, lint:js will scan all of your JS and Vue files.
While, when you commit and husky is executed (by running the lint:js:fix script), ONLY the files that you have touched will be linted (that’s the whole point of lint-staged).

Categories
discuss

Android: Iterative queue-based flood fill algorithm ‘expandToNeighborsWithMap()’ function is unusually slow

(Solution has been found, please avoid reading on.)

I am creating a pixel art editor for Android, and as for all pixel art editors, a paint bucket (fill tool) is a must need.

To do this, I did some research on flood fill algorithms online.

I stumbled across the following video which explained how to implement an iterative flood fill algorithm in your code. The code used in the video was JavaScript, but I was easily able to convert the code from the video to Kotlin:

https://www.youtube.com/watch?v=5Bochyn8MMI&t=72s&ab_channel=crayoncode

Here is an excerpt of the JavaScript code from the video:

enter image description here

Converted code:

Tools.FILL_TOOL -> {
            val seedColor = instance.rectangles[rectTapped]?.color ?: Color.WHITE

            val queue = LinkedList<XYPosition>()

            queue.offer(MathExtensions.convertIndexToXYPosition(rectangleData.indexOf(rectTapped), instance.spanCount.toInt()))

            val selectedColor = getSelectedColor()

            while (queue.isNotEmpty() && seedColor != selectedColor) { // While the queue is not empty the code below will run
                val current = queue.poll()
                val color = instance.rectangles.toList()[convertXYDataToIndex(instance, current)].second?.color ?: Color.WHITE

                if (color != seedColor) {
                    continue
                }

                instance.extraCanvas.apply {
                    instance.rectangles[rectangleData[convertXYDataToIndex(instance, current)]] = defaultRectPaint // Colors in pixel with defaultRectPaint
                    drawRect(rectangleData[convertXYDataToIndex(instance, current)], defaultRectPaint)

                    for (index in expandToNeighborsWithMap(instance, current)) {
                        val candidate = MathExtensions.convertIndexToXYPosition(index, instance.spanCount.toInt())
                        queue.offer(candidate)
                    }
                }
            }
        }

Now, I want to address two major issues I’m having with the code of mine:

  • Performance

  • Flooding glitch (fixed by suggestion from person in the comments)


Performance

A flood fill needs to be very fast and shouldn’t take less than a second, the problem is, say I have a canvas of size 50 x 50, and I decide to fill in the whole canvas, it can take up to 8 seconds or more.

Here is some data I’ve compiled for the time it’s taken to fill in a whole canvas given the spanCount value:

spanCount approx time taken in seconds to fill whole canvas
10 <1 seconds
20 ~2 seconds
40 ~6 seconds
60 ~15 seconds
100 ~115 seconds

The conclusion from the data is that the flood fill algorithm is unusually slow.

To find out why, I decided to test out which parts of the code are taking the most time to compile. I came to the conclusion that the expandToNeighbors function is taking the most time out of all the other tasks:

enter image description here

Here is an excerpt of the expandToNeighbors function:

fun expandToNeighbors(instance: MyCanvasView, from: XYPosition): List<Int> {
    var asIndex1 = from.x
    var asIndex2 = from.x

    var asIndex3 = from.y
    var asIndex4 = from.y

    if (from.x > 1) {
        asIndex1 = xyPositionData!!.indexOf(XYPosition(from.x - 1, from.y))
    }

    if (from.x < instance.spanCount) {
        asIndex2 = xyPositionData!!.indexOf(XYPosition(from.x + 1, from.y))
    }

    if (from.y > 1) {
        asIndex3 = xyPositionData!!.indexOf(XYPosition(from.x, from.y - 1))
    }

    if (from.y < instance.spanCount) {
        asIndex4 = xyPositionData!!.indexOf(XYPosition(from.x, from.y + 1))
    }

    return listOf(asIndex1, asIndex2, asIndex3, asIndex4)
} 

To understand the use of the expandToNeighbors function, I would recommend watching the video that I linked above.

(The if statements are there to make sure you won’t get an IndexOutOfBoundsException if you try and expand from the edge of the canvas.)

This function will return the index of the north, south, west, and east pixels from the xyPositionData list which contains XYPosition objects.

(The black pixel is the from parameter.)

enter image description here

The xyPositionData list is initialized once in the convertXYDataToIndex function, here:

var xyPositionData: List<XYPosition>? = null
var rectangleData: List<RectF>? = null

fun convertXYDataToIndex(instance: MyCanvasView, from: XYPosition): Int {

    if (rectangleData == null) {
        rectangleData = instance.rectangles.keys.toList()
    }

    if (xyPositionData == null) {
        xyPositionData = MathExtensions.convertListOfSizeNToListOfXYPosition(
            rectangleData!!.size,
            instance.spanCount.toInt()
        )
    }

    return xyPositionData!!.indexOf(from)
}

So, the code works fine (kind of) but the expandToNeighbors function is very slow, and it is the main reason why the flood fill algorithm is taking a long time.

My colleague suggested that indexOf may be slowing everything down, and that I should probably switch to a Map-based implementation with a key being XYPosition and a value being Int representing the index, so I replaced it with the following:

fun expandToNeighborsWithMap(instance: MyCanvasView, from: XYPosition): List<Int> {
    var asIndex1 = from.x
    var asIndex2 = from.x

    var asIndex3 = from.y
    var asIndex4 = from.y

    if (from.x > 1) {
        asIndex1 = rectangleDataMap!![XYPosition(from.x - 1, from.y)]!!
    }

    if (from.x < instance.spanCount) {
        asIndex2 =  rectangleDataMap!![XYPosition(from.x + 1, from.y)]!!
    }

    if (from.y > 1) {
        asIndex3 =  rectangleDataMap!![XYPosition(from.x, from.y - 1)]!!
    }

    if (from.y < instance.spanCount) {
        asIndex4 = rectangleDataMap!![XYPosition(from.x, from.y + 1)]!!
    }

    return listOf(asIndex1, asIndex2, asIndex3, asIndex4)
}

It functions the same way, only this time it uses a Map which is initialized here:

var xyPositionData: List<XYPosition>? = null
var rectangleData: List<RectF>? = null
var rectangleDataMap: Map<XYPosition, Int>? = null

fun convertXYDataToIndex(instance: MyCanvasView, from: XYPosition): Int {

    if (rectangleData == null) {
        rectangleData = instance.rectangles.keys.toList()
    }

    if (xyPositionData == null) {
        xyPositionData = MathExtensions.convertListOfSizeNToListOfXYPosition(
            rectangleData!!.size,
            instance.spanCount.toInt()
        )
    }

    if (rectangleDataMap == null) {
        rectangleDataMap = MathExtensions.convertListToMap(
            rectangleData!!.size,
            instance.spanCount.toInt()
        )
    }

    return xyPositionData!!.indexOf(from)
}

Converting the code to use a map increased the speed by around 20%, although the algorithm is still slow.

After spending a couple of days trying to make the algorithm work faster, I’m out of ideas and I’m unsure why the expandToNeighbors function is taking a long time. Any help would be appreciated to fix this issue.

Apologies if I didn’t do a good enough job of explaining the exact issue, but I have tried my best. Implementation-wise it is quite messy unfortunately because of the whole list index to XYPosition conversions, but at least it works – the only problem is the performance.


So I have two one major problem, if anyone can try and find a solution for it, it would be great because I have tried to myself without much luck.

I’ve actually pushed the fill tool to GitHub as a KIOL (Known Issue or Limitation), so the user can use the fill tool if they want, but they need to be aware of the limitations/issues. This is so anyone who wants to help me fix this can have a look at my code and reproduce the bugs.

Link to repository:

https://github.com/realtomjoney/PyxlMoose


Edit after bounty

I understand that this question is extremely difficult to answer and will require a lot of thinking. I’ve tried myself to fix these issues but haven’t had much success, so I’m offering 50 reputation for anyone who can assist.

I would recommend you clone PyxlMoose and reproduce the errors, then work from there. Relying on the code snippets isn’t enough.


Formula for converting XY position to an index

Somebody in the comments suggested a formula for converting an XYPosition to an index value, I came up with the following method which works:

    fun convertXYPositionToIndex(xyPosition: XYPosition, spanCount: Int): Int {
        val positionX = xyPosition.x
        val positionY = xyPosition.y

        return (spanCount - positionY) + (spanCount * (positionX - 1))
    }

The only problem is – it increases the speed by around 50% but it’s still taking around 10-15 seconds to fill in an area of 80 by 80 pixels, so it has helped to a large degree although it’s still very slow. But thank you very much for the suggestion anyways, it has helped a lot 🙂

Answer

How I fixed it:

  • Getting rid of the toList() calls.
  • Creating an convertXYPositionToIndex() function.

Here is my new code:

   Tools.FILL_TOOL -> {
            val seedColor = instance.rectangles[rectTapped]?.color ?: Color.WHITE

            val queue = LinkedList<XYPosition>()

            val spanCount = instance.spanCount.toInt()

            queue.offer(MathExtensions.convertIndexToXYPosition(rectangleData.indexOf(rectTapped), spanCount))

            val selectedColor = getSelectedColor()

            while (queue.isNotEmpty() && seedColor != selectedColor) {

                val current = queue.poll()

                val color = instance.rectangles[rectangleData[convertXYDataToIndex(spanCount, current)]]?.color ?: Color.WHITE

                if (color != seedColor) {
                    continue
                }

                instance.rectangles[rectangleData[convertXYDataToIndex(spanCount, current)]] = defaultRectPaint // Colors in pixel with defaultRectPaint
                instance.extraCanvas.drawRect(rectangleData[MathExtensions.convertXYPositionToIndex(current, spanCount)], defaultRectPaint)

                for (index in expandToNeighborsWithMap(spanCount, current)) {
                    val candidate = MathExtensions.convertIndexToXYPosition(index, spanCount)
                    queue.offer(candidate)
                }
            }
            val timeTakenForThis = (System.currentTimeMillis()-startTime)
            totalTime += timeTakenForThis
        }

Expand to neighbors func:

fun expandToNeighborsWithMap(spanCount: Int, from: XYPosition): List<Int> {
    val toReturn = mutableListOf<Int>()

    if (from.x > 1) {
        toReturn.add(MathExtensions.convertXYPositionToIndex(XYPosition(from.x - 1, from.y), spanCount))
    }

    if (from.x < spanCount) {
        toReturn.add(MathExtensions.convertXYPositionToIndex(XYPosition(from.x + 1, from.y), spanCount))
    }

    if (from.y > 1) {
        toReturn.add(MathExtensions.convertXYPositionToIndex(XYPosition(from.x, from.y - 1), spanCount))
    }

    if (from.y < spanCount) {
        toReturn.add(MathExtensions.convertXYPositionToIndex(XYPosition(from.x, from.y + 1), spanCount))
    }

    return toReturn
}

It takes less than a second for canvas sizes of 100 by 100 and 200 by 200, so I’d say it’s in the usable stage now.

I would say this is one of the simplest Android flood fill algorithms out there to understand, so if anyone is making an app similar to mine and they want a flood fill tool they can copy my code.

A guy in the comments called EvilTalk helped me with this.

Categories
discuss

How to insert elements into specific index in a 2D array in javascript?

I have an object that looks like below

const tableData = [
    {
        
        "Location": "London",
        "Status": "Unknown"
    },
    {
        
        "Location": "Delhi",
        "Status": "Reachable"
    },
    {
        
        "Location": "Berlin",
        "Status": "Unknown"
    },
    {
        
        "Location": "Tokyo",
        "Status": "Busy"
    },
]

Now I want to create a 2D array which will hold this information in a certain way. Here is my code below

const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
let statusOrderInfo = Array(Object.keys(statusOrder).length).fill([]);
for(let i=0; i< tableData.length; i++) {
    const status = tableData[i]["Status"].trim()
    const statusIndex = statusOrder[status]
    statusOrderInfo[statusIndex].push(tableData[i])
}
console.log(statusOrderInfo)

As you can see I want each item of the tableData object to be in a certain index of the 2D array. So the item that contains Status as Reachable should be at index 0, the item that contains the Status as Busy should be at index 1 and so on.

So the final output should look like

[
   [
      {
         "Location":"Delhi",
         "Status":"Reachable"
      }
   ],
   [
      {
         "Location":"Tokyo",
         "Status":"Busy"
      }
   ],
   [
      {
         "Location":"London",
         "Status":"Unknown"
      },
      {
         "Location":"Berlin",
         "Status":"Unknown"
      }
   ]
]

But I get a wrong output on running the above code even though I am targeting the correct index. What’s wrong in my approach?

Answer

Simple fix on your problem is that just changing your manner to set initial value of statusOrderInfo and use Array.from instead of Array.fill like this:

let statusOrderInfo = Array.from({length: Object.keys(statusOrder).length}, ()=> []);

another solution is set initiali value of statusOrderInfo by empty array, and then in your for loop, after you get the index of current object based on status value, you can check if statusIndex already exist in the statusOrderInfo or not, like this:

const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
let statusOrderInfo = [];
for(let i=0; i< tableData.length; i++) {
    const status = tableData[i]["Status"].trim()
    const statusIndex = statusOrder[status];
    if(statusOrderInfo[statusIndex]) statusOrderInfo[statusIndex].push(tableData[i]);
    else statusOrderInfo[statusIndex] = [ tableData[i] ]
}
console.log(statusOrderInfo);

another solution, is to use reduce method on array, like this:

const tableData = [{

    "Location": "London",
    "Status": "Unknown"
  },
  {

    "Location": "Delhi",
    "Status": "Reachable"
  },
  {

    "Location": "Berlin",
    "Status": "Unknown"
  },
  {

    "Location": "Tokyo",
    "Status": "Busy"
  },
];
const statusOrder = {"Reachable": 0, "Busy": 1, "Unknown": 2}
const result = tableData.reduce((acc, cur) => {
  const index = statusOrder[cur.Status];
  if (acc[index]) acc[index].push(cur);
  else acc[index] = [cur]
  return acc;
}, []);
console.log(result)
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..